Advanced Custom Fields - Version 5.9.9

Version Description

Release Date - 20 July 2021

  • Fix - Fixed warning when deleting fields which don't exist
  • Fix - Fixed issues with older browsers and the blocks JavaScript
  • Fix - Fixed file size & file type validation for front end forms using the basic uploader
Download this release

Release Info

Developer deliciousbrains
Plugin Icon 128x128 Advanced Custom Fields
Version 5.9.9
Comparing to
See all releases

Code changes from version 5.9.8 to 5.9.9

acf.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Advanced Custom Fields
4
  Plugin URI: https://www.advancedcustomfields.com
5
  Description: Customize WordPress with powerful, professional and intuitive fields.
6
- Version: 5.9.8
7
  Author: Delicious Brains
8
  Author URI: https://www.advancedcustomfields.com
9
  Text Domain: acf
@@ -17,7 +17,7 @@ if( ! class_exists('ACF') ) :
17
  class ACF {
18
 
19
  /** @var string The plugin version number. */
20
- var $version = '5.9.8';
21
 
22
  /** @var array The plugin settings array. */
23
  var $settings = array();
@@ -137,6 +137,7 @@ class ACF {
137
  acf_include('includes/loop.php');
138
  acf_include('includes/media.php');
139
  acf_include('includes/revisions.php');
 
140
  acf_include('includes/upgrades.php');
141
  acf_include('includes/validation.php');
142
 
3
  Plugin Name: Advanced Custom Fields
4
  Plugin URI: https://www.advancedcustomfields.com
5
  Description: Customize WordPress with powerful, professional and intuitive fields.
6
+ Version: 5.9.9
7
  Author: Delicious Brains
8
  Author URI: https://www.advancedcustomfields.com
9
  Text Domain: acf
17
  class ACF {
18
 
19
  /** @var string The plugin version number. */
20
+ var $version = '5.9.9';
21
 
22
  /** @var array The plugin settings array. */
23
  var $settings = array();
137
  acf_include('includes/loop.php');
138
  acf_include('includes/media.php');
139
  acf_include('includes/revisions.php');
140
+ acf_include('includes/updates.php');
141
  acf_include('includes/upgrades.php');
142
  acf_include('includes/validation.php');
143
 
assets/build/js/acf-field-group.js CHANGED
@@ -1,2050 +1,2525 @@
1
- (function ($, undefined) {
2
- /**
3
- * fieldGroupManager
4
- *
5
- * Generic field group functionality
6
- *
7
- * @date 15/12/17
8
- * @since 5.7.0
9
- *
10
- * @param void
11
- * @return void
12
- */
13
- var fieldGroupManager = new acf.Model({
14
- id: 'fieldGroupManager',
15
- events: {
16
- 'submit #post': 'onSubmit',
17
- 'click a[href="#"]': 'onClick',
18
- 'click .submitdelete': 'onClickTrash'
19
- },
20
- filters: {
21
- 'find_fields_args': 'filterFindFieldArgs'
22
- },
23
- onSubmit: function (e, $el) {
24
- // vars
25
- var $title = $('#titlewrap #title'); // empty
26
-
27
- if (!$title.val()) {
28
- // prevent default
29
- e.preventDefault(); // unlock form
30
-
31
- acf.unlockForm($el); // alert
32
-
33
- alert(acf.__('Field group title is required')); // focus
34
-
35
- $title.trigger('focus');
36
- }
37
- },
38
- onClick: function (e) {
39
- e.preventDefault();
40
- },
41
- onClickTrash: function (e) {
42
- var result = confirm(acf.__('Move to trash. Are you sure?'));
43
-
44
- if (!result) {
45
- e.preventDefault();
46
- }
47
- },
48
- filterFindFieldArgs: function (args) {
49
- args.visible = true;
50
- return args;
51
- }
52
- });
53
- /**
54
- * screenOptionsManager
55
- *
56
- * Screen options functionality
57
- *
58
- * @date 15/12/17
59
- * @since 5.7.0
60
- *
61
- * @param void
62
- * @return void
63
- */
64
-
65
- var screenOptionsManager = new acf.Model({
66
- id: 'screenOptionsManager',
67
- wait: 'prepare',
68
- events: {
69
- 'change': 'onChange'
70
- },
71
- initialize: function () {
72
- // vars
73
- var $div = $('#adv-settings');
74
- var $append = $('#acf-append-show-on-screen'); // append
75
-
76
- $div.find('.metabox-prefs').append($append.html());
77
- $div.find('.metabox-prefs br').remove(); // clean up
78
-
79
- $append.remove(); // initialize
80
-
81
- this.$el = $('#acf-field-key-hide'); // render
82
-
83
- this.render();
84
- },
85
- isChecked: function () {
86
- return this.$el.prop('checked');
87
- },
88
- onChange: function (e, $el) {
89
- var val = this.isChecked() ? 1 : 0;
90
- acf.updateUserSetting('show_field_keys', val);
91
- this.render();
92
- },
93
- render: function () {
94
- if (this.isChecked()) {
95
- $('#acf-field-group-fields').addClass('show-field-keys');
96
- } else {
97
- $('#acf-field-group-fields').removeClass('show-field-keys');
98
- }
99
- }
100
- });
101
- /**
102
- * appendFieldManager
103
- *
104
- * Appends fields together
105
- *
106
- * @date 15/12/17
107
- * @since 5.7.0
108
- *
109
- * @param void
110
- * @return void
111
- */
112
-
113
- var appendFieldManager = new acf.Model({
114
- actions: {
115
- 'new_field': 'onNewField'
116
- },
117
- onNewField: function (field) {
118
- // bail ealry if not append
119
- if (!field.has('append')) return; // vars
120
-
121
- var append = field.get('append');
122
- var $sibling = field.$el.siblings('[data-name="' + append + '"]').first(); // bail early if no sibling
123
-
124
- if (!$sibling.length) return; // ul
125
-
126
- var $div = $sibling.children('.acf-input');
127
- var $ul = $div.children('ul'); // create ul
128
-
129
- if (!$ul.length) {
130
- $div.wrapInner('<ul class="acf-hl"><li></li></ul>');
131
- $ul = $div.children('ul');
132
- } // li
133
-
134
-
135
- var html = field.$('.acf-input').html();
136
- var $li = $('<li>' + html + '</li>');
137
- $ul.append($li);
138
- $ul.attr('data-cols', $ul.children().length); // clean up
139
-
140
- field.remove();
141
- }
142
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  })(jQuery);
144
-
145
- (function ($, undefined) {
146
- acf.FieldObject = acf.Model.extend({
147
- // class used to avoid nested event triggers
148
- eventScope: '.acf-field-object',
149
- // events
150
- events: {
151
- 'click .edit-field': 'onClickEdit',
152
- 'click .delete-field': 'onClickDelete',
153
- 'click .duplicate-field': 'duplicate',
154
- 'click .move-field': 'move',
155
- 'change .field-type': 'onChangeType',
156
- 'change .field-required': 'onChangeRequired',
157
- 'blur .field-label': 'onChangeLabel',
158
- 'blur .field-name': 'onChangeName',
159
- 'change': 'onChange',
160
- 'changed': 'onChanged'
161
- },
162
- // data
163
- data: {
164
- // Similar to ID, but used for HTML puposes.
165
- // It is possbile for a new field to have an ID of 0, but an id of 'field_123' */
166
- id: 0,
167
- // The field key ('field_123')
168
- key: '',
169
- // The field type (text, image, etc)
170
- type: '' // The $post->ID of this field
171
- //ID: 0,
172
- // The field's parent
173
- //parent: 0,
174
- // The menu order
175
- //menu_order: 0
176
-
177
- },
178
- setup: function ($field) {
179
- // set $el
180
- this.$el = $field; // inherit $field data (id, key, type)
181
-
182
- this.inherit($field); // load additional props
183
- // - this won't trigger 'changed'
184
-
185
- this.prop('ID');
186
- this.prop('parent');
187
- this.prop('menu_order');
188
- },
189
- $input: function (name) {
190
- return $('#' + this.getInputId() + '-' + name);
191
- },
192
- $meta: function () {
193
- return this.$('.meta:first');
194
- },
195
- $handle: function () {
196
- return this.$('.handle:first');
197
- },
198
- $settings: function () {
199
- return this.$('.settings:first');
200
- },
201
- $setting: function (name) {
202
- return this.$('.acf-field-settings:first > .acf-field-setting-' + name);
203
- },
204
- getParent: function () {
205
- return acf.getFieldObjects({
206
- child: this.$el,
207
- limit: 1
208
- }).pop();
209
- },
210
- getParents: function () {
211
- return acf.getFieldObjects({
212
- child: this.$el
213
- });
214
- },
215
- getFields: function () {
216
- return acf.getFieldObjects({
217
- parent: this.$el
218
- });
219
- },
220
- getInputName: function () {
221
- return 'acf_fields[' + this.get('id') + ']';
222
- },
223
- getInputId: function () {
224
- return 'acf_fields-' + this.get('id');
225
- },
226
- newInput: function (name, value) {
227
- // vars
228
- var inputId = this.getInputId();
229
- var inputName = this.getInputName(); // append name
230
-
231
- if (name) {
232
- inputId += '-' + name;
233
- inputName += '[' + name + ']';
234
- } // create input (avoid HTML + JSON value issues)
235
-
236
-
237
- var $input = $('<input />').attr({
238
- id: inputId,
239
- name: inputName,
240
- value: value
241
- });
242
- this.$('> .meta').append($input); // return
243
-
244
- return $input;
245
- },
246
- getProp: function (name) {
247
- // check data
248
- if (this.has(name)) {
249
- return this.get(name);
250
- } // get input value
251
-
252
-
253
- var $input = this.$input(name);
254
- var value = $input.length ? $input.val() : null; // set data silently (cache)
255
-
256
- this.set(name, value, true); // return
257
-
258
- return value;
259
- },
260
- setProp: function (name, value) {
261
- // get input
262
- var $input = this.$input(name);
263
- var prevVal = $input.val(); // create if new
264
-
265
- if (!$input.length) {
266
- $input = this.newInput(name, value);
267
- } // remove
268
-
269
-
270
- if (value === null) {
271
- $input.remove(); // update
272
- } else {
273
- $input.val(value);
274
- } //console.log('setProp', name, value, this);
275
- // set data silently (cache)
276
-
277
-
278
- if (!this.has(name)) {
279
- //console.log('setting silently');
280
- this.set(name, value, true); // set data allowing 'change' event to fire
281
- } else {
282
- //console.log('setting loudly!');
283
- this.set(name, value);
284
- } // return
285
-
286
-
287
- return this;
288
- },
289
- prop: function (name, value) {
290
- if (value !== undefined) {
291
- return this.setProp(name, value);
292
- } else {
293
- return this.getProp(name);
294
- }
295
- },
296
- props: function (props) {
297
- Object.keys(props).map(function (key) {
298
- this.setProp(key, props[key]);
299
- }, this);
300
- },
301
- getLabel: function () {
302
- // get label with empty default
303
- var label = this.prop('label');
304
-
305
- if (label === '') {
306
- label = acf.__('(no label)');
307
- } // return
308
-
309
-
310
- return label;
311
- },
312
- getName: function () {
313
- return this.prop('name');
314
- },
315
- getType: function () {
316
- return this.prop('type');
317
- },
318
- getTypeLabel: function () {
319
- var type = this.prop('type');
320
- var types = acf.get('fieldTypes');
321
- return types[type] ? types[type].label : type;
322
- },
323
- getKey: function () {
324
- return this.prop('key');
325
- },
326
- initialize: function () {
327
- this.addProFields();
328
- },
329
- addProFields: function () {
330
- // Make sure we're only running this on free version.
331
- if (acf.data.fieldTypes.hasOwnProperty('clone')) {
332
- return;
333
- } // Make sure we haven't appended these fields before.
334
-
335
-
336
- var $fieldTypeSelect = $('.field-type').not('.acf-free-field-type'); // Append pro fields to "Layout" group.
337
-
338
- var $layoutGroup = $fieldTypeSelect.find('optgroup option[value="group"]').parent();
339
- $layoutGroup.append('<option value="null" disabled="disabled">' + acf.__('Repeater (Pro only)') + '</option>' + '<option value="null" disabled="disabled">' + acf.__('Flexible Content (Pro only)') + '</option>' + '<option value="null" disabled="disabled">' + acf.__('Clone (Pro only)') + '</option>'); // Add pro fields to "Content" group.
340
-
341
- var $contentGroup = $fieldTypeSelect.find('optgroup option[value="image"]').parent();
342
- $contentGroup.append('<option value="null" disabled="disabled">' + acf.__('Gallery (Pro only)') + '</option>');
343
- $fieldTypeSelect.addClass('acf-free-field-type');
344
- },
345
- render: function () {
346
- // vars
347
- var $handle = this.$('.handle:first');
348
- var menu_order = this.prop('menu_order');
349
- var label = this.getLabel();
350
- var name = this.prop('name');
351
- var type = this.getTypeLabel();
352
- var key = this.prop('key');
353
- var required = this.$input('required').prop('checked'); // update menu order
354
-
355
- $handle.find('.acf-icon').html(parseInt(menu_order) + 1); // update required
356
-
357
- if (required) {
358
- label += ' <span class="acf-required">*</span>';
359
- } // update label
360
-
361
-
362
- $handle.find('.li-field-label strong a').html(label); // update name
363
-
364
- $handle.find('.li-field-name').text(name); // update type
365
-
366
- $handle.find('.li-field-type').text(type); // update key
367
-
368
- $handle.find('.li-field-key').text(key); // action for 3rd party customization
369
-
370
- acf.doAction('render_field_object', this);
371
- },
372
- refresh: function () {
373
- acf.doAction('refresh_field_object', this);
374
- },
375
- isOpen: function () {
376
- return this.$el.hasClass('open');
377
- },
378
- onClickEdit: function (e) {
379
- this.isOpen() ? this.close() : this.open();
380
- },
381
- open: function () {
382
- // vars
383
- var $settings = this.$el.children('.settings'); // open
384
-
385
- $settings.slideDown();
386
- this.$el.addClass('open'); // action (open)
387
-
388
- acf.doAction('open_field_object', this);
389
- this.trigger('openFieldObject'); // action (show)
390
-
391
- acf.doAction('show', $settings);
392
- },
393
- close: function () {
394
- // vars
395
- var $settings = this.$el.children('.settings'); // close
396
-
397
- $settings.slideUp();
398
- this.$el.removeClass('open'); // action (close)
399
-
400
- acf.doAction('close_field_object', this);
401
- this.trigger('closeFieldObject'); // action (hide)
402
-
403
- acf.doAction('hide', $settings);
404
- },
405
- serialize: function () {
406
- return acf.serialize(this.$el, this.getInputName());
407
- },
408
- save: function (type) {
409
- // defaults
410
- type = type || 'settings'; // meta, settings
411
- // vars
412
-
413
- var save = this.getProp('save'); // bail if already saving settings
414
-
415
- if (save === 'settings') {
416
- return;
417
- } // prop
418
-
419
-
420
- this.setProp('save', type); // debug
421
-
422
- this.$el.attr('data-save', type); // action
423
-
424
- acf.doAction('save_field_object', this, type);
425
- },
426
- submit: function () {
427
- // vars
428
- var inputName = this.getInputName();
429
- var save = this.get('save'); // close
430
-
431
- if (this.isOpen()) {
432
- this.close();
433
- } // allow all inputs to save
434
-
435
-
436
- if (save == 'settings') {// do nothing
437
- // allow only meta inputs to save
438
- } else if (save == 'meta') {
439
- this.$('> .settings [name^="' + inputName + '"]').remove(); // prevent all inputs from saving
440
- } else {
441
- this.$('[name^="' + inputName + '"]').remove();
442
- } // action
443
-
444
-
445
- acf.doAction('submit_field_object', this);
446
- },
447
- onChange: function (e, $el) {
448
- // save settings
449
- this.save(); // action for 3rd party customization
450
-
451
- acf.doAction('change_field_object', this);
452
- },
453
- onChanged: function (e, $el, name, value) {
454
- // ignore 'save'
455
- if (name == 'save') {
456
- return;
457
- } // save meta
458
-
459
-
460
- if (['menu_order', 'parent'].indexOf(name) > -1) {
461
- this.save('meta'); // save field
462
- } else {
463
- this.save();
464
- } // render
465
-
466
-
467
- if (['menu_order', 'label', 'required', 'name', 'type', 'key'].indexOf(name) > -1) {
468
- this.render();
469
- } // action for 3rd party customization
470
-
471
-
472
- acf.doAction('change_field_object_' + name, this, value);
473
- },
474
- onChangeLabel: function (e, $el) {
475
- // set
476
- var label = $el.val();
477
- this.set('label', label); // render name
478
-
479
- if (this.prop('name') == '') {
480
- var name = acf.applyFilters('generate_field_object_name', acf.strSanitize(label), this);
481
- this.prop('name', name);
482
- }
483
- },
484
- onChangeName: function (e, $el) {
485
- // set
486
- var name = $el.val();
487
- this.set('name', name); // error
488
-
489
- if (name.substr(0, 6) === 'field_') {
490
- alert(acf.__('The string "field_" may not be used at the start of a field name'));
491
- }
492
- },
493
- onChangeRequired: function (e, $el) {
494
- // set
495
- var required = $el.prop('checked') ? 1 : 0;
496
- this.set('required', required);
497
- },
498
- delete: function (args) {
499
- // defaults
500
- args = acf.parseArgs(args, {
501
- animate: true
502
- }); // add to remove list
503
-
504
- var id = this.prop('ID');
505
-
506
- if (id) {
507
- var $input = $('#_acf_delete_fields');
508
- var newVal = $input.val() + '|' + id;
509
- $input.val(newVal);
510
- } // action
511
-
512
-
513
- acf.doAction('delete_field_object', this); // animate
514
-
515
- if (args.animate) {
516
- this.removeAnimate();
517
- } else {
518
- this.remove();
519
- }
520
- },
521
- onClickDelete: function (e, $el) {
522
- // Bypass confirmation when holding down "shift" key.
523
- if (e.shiftKey) {
524
- return this.delete();
525
- } // add class
526
-
527
-
528
- this.$el.addClass('-hover'); // add tooltip
529
-
530
- var tooltip = acf.newTooltip({
531
- confirmRemove: true,
532
- target: $el,
533
- context: this,
534
- confirm: function () {
535
- this.delete();
536
- },
537
- cancel: function () {
538
- this.$el.removeClass('-hover');
539
- }
540
- });
541
- },
542
- removeAnimate: function () {
543
- // vars
544
- var field = this;
545
- var $list = this.$el.parent();
546
- var $fields = acf.findFieldObjects({
547
- sibling: this.$el
548
- }); // remove
549
-
550
- acf.remove({
551
- target: this.$el,
552
- endHeight: $fields.length ? 0 : 50,
553
- complete: function () {
554
- field.remove();
555
- acf.doAction('removed_field_object', field, $list);
556
- }
557
- }); // action
558
-
559
- acf.doAction('remove_field_object', field, $list);
560
- },
561
- duplicate: function () {
562
- // vars
563
- var newKey = acf.uniqid('field_'); // duplicate
564
-
565
- var $newField = acf.duplicate({
566
- target: this.$el,
567
- search: this.get('id'),
568
- replace: newKey
569
- }); // set new key
570
-
571
- $newField.attr('data-key', newKey); // get instance
572
-
573
- var newField = acf.getFieldObject($newField); // open / close
574
-
575
- if (this.isOpen()) {
576
- this.close();
577
- } else {
578
- newField.open();
579
- } // focus label
580
-
581
-
582
- var $label = newField.$setting('label input');
583
- setTimeout(function () {
584
- $label.trigger('focus');
585
- }, 251); // update newField label / name
586
-
587
- var label = newField.prop('label');
588
- var name = newField.prop('name');
589
- var end = name.split('_').pop();
590
-
591
- var copy = acf.__('copy'); // increase suffix "1"
592
-
593
-
594
- if (acf.isNumeric(end)) {
595
- var i = end * 1 + 1;
596
- label = label.replace(end, i);
597
- name = name.replace(end, i); // increase suffix "(copy1)"
598
- } else if (end.indexOf(copy) === 0) {
599
- var i = end.replace(copy, '') * 1;
600
- i = i ? i + 1 : 2; // replace
601
-
602
- label = label.replace(end, copy + i);
603
- name = name.replace(end, copy + i); // add default "(copy)"
604
- } else {
605
- label += ' (' + copy + ')';
606
- name += '_' + copy;
607
- }
608
-
609
- newField.prop('ID', 0);
610
- newField.prop('label', label);
611
- newField.prop('name', name);
612
- newField.prop('key', newKey); // action
613
-
614
- acf.doAction('duplicate_field_object', this, newField);
615
- acf.doAction('append_field_object', newField);
616
- },
617
- wipe: function () {
618
- // vars
619
- var prevId = this.get('id');
620
- var prevKey = this.get('key');
621
- var newKey = acf.uniqid('field_'); // rename
622
-
623
- acf.rename({
624
- target: this.$el,
625
- search: prevId,
626
- replace: newKey
627
- }); // data
628
-
629
- this.set('id', newKey);
630
- this.set('prevId', prevId);
631
- this.set('prevKey', prevKey); // props
632
-
633
- this.prop('key', newKey);
634
- this.prop('ID', 0); // attr
635
-
636
- this.$el.attr('data-key', newKey);
637
- this.$el.attr('data-id', newKey); // action
638
-
639
- acf.doAction('wipe_field_object', this);
640
- },
641
- move: function () {
642
- // helper
643
- var hasChanged = function (field) {
644
- return field.get('save') == 'settings';
645
- }; // vars
646
-
647
-
648
- var changed = hasChanged(this); // has sub fields changed
649
-
650
- if (!changed) {
651
- acf.getFieldObjects({
652
- parent: this.$el
653
- }).map(function (field) {
654
- changed = hasChanged(field) || field.changed;
655
- });
656
- } // bail early if changed
657
-
658
-
659
- if (changed) {
660
- alert(acf.__('This field cannot be moved until its changes have been saved'));
661
- return;
662
- } // step 1.
663
-
664
-
665
- var id = this.prop('ID');
666
- var field = this;
667
- var popup = false;
668
-
669
- var step1 = function () {
670
- // popup
671
- popup = acf.newPopup({
672
- title: acf.__('Move Custom Field'),
673
- loading: true,
674
- width: '300px'
675
- }); // ajax
676
-
677
- var ajaxData = {
678
- action: 'acf/field_group/move_field',
679
- field_id: id
680
- }; // get HTML
681
-
682
- $.ajax({
683
- url: acf.get('ajaxurl'),
684
- data: acf.prepareForAjax(ajaxData),
685
- type: 'post',
686
- dataType: 'html',
687
- success: step2
688
- });
689
- };
690
-
691
- var step2 = function (html) {
692
- // update popup
693
- popup.loading(false);
694
- popup.content(html); // submit form
695
-
696
- popup.on('submit', 'form', step3);
697
- };
698
-
699
- var step3 = function (e, $el) {
700
- // prevent
701
- e.preventDefault(); // disable
702
-
703
- acf.startButtonLoading(popup.$('.button')); // ajax
704
-
705
- var ajaxData = {
706
- action: 'acf/field_group/move_field',
707
- field_id: id,
708
- field_group_id: popup.$('select').val()
709
- }; // get HTML
710
-
711
- $.ajax({
712
- url: acf.get('ajaxurl'),
713
- data: acf.prepareForAjax(ajaxData),
714
- type: 'post',
715
- dataType: 'html',
716
- success: step4
717
- });
718
- };
719
-
720
- var step4 = function (html) {
721
- // update popup
722
- popup.content(html); // remove element
723
-
724
- field.removeAnimate();
725
- }; // start
726
-
727
-
728
- step1();
729
- },
730
- onChangeType: function (e, $el) {
731
- // clea previous timout
732
- if (this.changeTimeout) {
733
- clearTimeout(this.changeTimeout);
734
- } // set new timeout
735
- // - prevents changing type multiple times whilst user types in newType
736
-
737
-
738
- this.changeTimeout = this.setTimeout(function () {
739
- this.changeType($el.val());
740
- }, 300);
741
- },
742
- changeType: function (newType) {
743
- // vars
744
- var prevType = this.prop('type');
745
- var prevClass = acf.strSlugify('acf-field-object-' + prevType);
746
- var newClass = acf.strSlugify('acf-field-object-' + newType); // update props
747
-
748
- this.$el.removeClass(prevClass).addClass(newClass);
749
- this.$el.attr('data-type', newType);
750
- this.$el.data('type', newType); // abort XHR if this field is already loading AJAX data
751
-
752
- if (this.has('xhr')) {
753
- this.get('xhr').abort();
754
- } // store settings
755
-
756
-
757
- var $tbody = this.$('> .settings > table > tbody');
758
- var $settings = $tbody.children('[data-setting="' + prevType + '"]');
759
- this.set('settings-' + prevType, $settings);
760
- $settings.detach(); // show settings
761
-
762
- if (this.has('settings-' + newType)) {
763
- var $newSettings = this.get('settings-' + newType);
764
- this.$setting('conditional_logic').before($newSettings);
765
- this.set('type', newType); //this.refresh();
766
-
767
- return;
768
- } // load settings
769
-
770
-
771
- var $loading = $('<tr class="acf-field"><td class="acf-label"></td><td class="acf-input"><div class="acf-loading"></div></td></tr>');
772
- this.$setting('conditional_logic').before($loading); // ajax
773
-
774
- var ajaxData = {
775
- action: 'acf/field_group/render_field_settings',
776
- field: this.serialize(),
777
- prefix: this.getInputName()
778
- }; // ajax
779
-
780
- var xhr = $.ajax({
781
- url: acf.get('ajaxurl'),
782
- data: acf.prepareForAjax(ajaxData),
783
- type: 'post',
784
- dataType: 'html',
785
- context: this,
786
- success: function (html) {
787
- // bail early if no settings
788
- if (!html) return; // append settings
789
-
790
- $loading.after(html); // events
791
-
792
- acf.doAction('append', $tbody);
793
- },
794
- complete: function () {
795
- // also triggered by xhr.abort();
796
- $loading.remove();
797
- this.set('type', newType); //this.refresh();
798
- }
799
- }); // set
800
-
801
- this.set('xhr', xhr);
802
- },
803
- updateParent: function () {
804
- // vars
805
- var ID = acf.get('post_id'); // check parent
806
-
807
- var parent = this.getParent();
808
-
809
- if (parent) {
810
- ID = parseInt(parent.prop('ID')) || parent.prop('key');
811
- } // update
812
-
813
-
814
- this.prop('parent', ID);
815
- }
816
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
817
  })(jQuery);
818
-
819
- (function ($, undefined) {
820
- /**
821
- * mid
822
- *
823
- * Calculates the model ID for a field type
824
- *
825
- * @date 15/12/17
826
- * @since 5.6.5
827
- *
828
- * @param string type
829
- * @return string
830
- */
831
- var modelId = function (type) {
832
- return acf.strPascalCase(type || '') + 'FieldSetting';
833
- };
834
- /**
835
- * registerFieldType
836
- *
837
- * description
838
- *
839
- * @date 14/12/17
840
- * @since 5.6.5
841
- *
842
- * @param type $var Description. Default.
843
- * @return type Description.
844
- */
845
-
846
-
847
- acf.registerFieldSetting = function (model) {
848
- var proto = model.prototype;
849
- var mid = modelId(proto.type + ' ' + proto.name);
850
- this.models[mid] = model;
851
- };
852
- /**
853
- * newField
854
- *
855
- * description
856
- *
857
- * @date 14/12/17
858
- * @since 5.6.5
859
- *
860
- * @param type $var Description. Default.
861
- * @return type Description.
862
- */
863
-
864
-
865
- acf.newFieldSetting = function (field) {
866
- // vars
867
- var type = field.get('setting') || '';
868
- var name = field.get('name') || '';
869
- var mid = modelId(type + ' ' + name);
870
- var model = acf.models[mid] || null; // bail ealry if no setting
871
-
872
- if (model === null) return false; // instantiate
873
-
874
- var setting = new model(field); // return
875
-
876
- return setting;
877
- };
878
- /**
879
- * acf.getFieldSetting
880
- *
881
- * description
882
- *
883
- * @date 19/4/18
884
- * @since 5.6.9
885
- *
886
- * @param type $var Description. Default.
887
- * @return type Description.
888
- */
889
-
890
-
891
- acf.getFieldSetting = function (field) {
892
- // allow jQuery
893
- if (field instanceof jQuery) {
894
- field = acf.getField(field);
895
- } // return
896
-
897
-
898
- return field.setting;
899
- };
900
- /**
901
- * settingsManager
902
- *
903
- * description
904
- *
905
- * @date 6/1/18
906
- * @since 5.6.5
907
- *
908
- * @param type $var Description. Default.
909
- * @return type Description.
910
- */
911
-
912
-
913
- var settingsManager = new acf.Model({
914
- actions: {
915
- 'new_field': 'onNewField'
916
- },
917
- onNewField: function (field) {
918
- field.setting = acf.newFieldSetting(field);
919
- }
920
- });
921
- /**
922
- * acf.FieldSetting
923
- *
924
- * description
925
- *
926
- * @date 6/1/18
927
- * @since 5.6.5
928
- *
929
- * @param type $var Description. Default.
930
- * @return type Description.
931
- */
932
-
933
- acf.FieldSetting = acf.Model.extend({
934
- field: false,
935
- type: '',
936
- name: '',
937
- wait: 'ready',
938
- eventScope: '.acf-field',
939
- events: {
940
- 'change': 'render'
941
- },
942
- setup: function (field) {
943
- // vars
944
- var $field = field.$el; // set props
945
-
946
- this.$el = $field;
947
- this.field = field;
948
- this.$fieldObject = $field.closest('.acf-field-object');
949
- this.fieldObject = acf.getFieldObject(this.$fieldObject); // inherit data
950
-
951
- $.extend(this.data, field.data);
952
- },
953
- initialize: function () {
954
- this.render();
955
- },
956
- render: function () {// do nothing
957
- }
958
- });
959
- /*
960
- * Date Picker
961
- *
962
- * This field type requires some extra logic for its settings
963
- *
964
- * @type function
965
- * @date 24/10/13
966
- * @since 5.0.0
967
- *
968
- * @param n/a
969
- * @return n/a
970
- */
971
-
972
- var DisplayFormatFieldSetting = acf.FieldSetting.extend({
973
- type: '',
974
- name: '',
975
- render: function () {
976
- var $input = this.$('input[type="radio"]:checked');
977
-
978
- if ($input.val() != 'other') {
979
- this.$('input[type="text"]').val($input.val());
980
- }
981
- }
982
- });
983
- var DatePickerDisplayFormatFieldSetting = DisplayFormatFieldSetting.extend({
984
- type: 'date_picker',
985
- name: 'display_format'
986
- });
987
- var DatePickerReturnFormatFieldSetting = DisplayFormatFieldSetting.extend({
988
- type: 'date_picker',
989
- name: 'return_format'
990
- });
991
- acf.registerFieldSetting(DatePickerDisplayFormatFieldSetting);
992
- acf.registerFieldSetting(DatePickerReturnFormatFieldSetting);
993
- /*
994
- * Date Time Picker
995
- *
996
- * This field type requires some extra logic for its settings
997
- *
998
- * @type function
999
- * @date 24/10/13
1000
- * @since 5.0.0
1001
- *
1002
- * @param n/a
1003
- * @return n/a
1004
- */
1005
-
1006
- var DateTimePickerDisplayFormatFieldSetting = DisplayFormatFieldSetting.extend({
1007
- type: 'date_time_picker',
1008
- name: 'display_format'
1009
- });
1010
- var DateTimePickerReturnFormatFieldSetting = DisplayFormatFieldSetting.extend({
1011
- type: 'date_time_picker',
1012
- name: 'return_format'
1013
- });
1014
- acf.registerFieldSetting(DateTimePickerDisplayFormatFieldSetting);
1015
- acf.registerFieldSetting(DateTimePickerReturnFormatFieldSetting);
1016
- /*
1017
- * Time Picker
1018
- *
1019
- * This field type requires some extra logic for its settings
1020
- *
1021
- * @type function
1022
- * @date 24/10/13
1023
- * @since 5.0.0
1024
- *
1025
- * @param n/a
1026
- * @return n/a
1027
- */
1028
-
1029
- var TimePickerDisplayFormatFieldSetting = DisplayFormatFieldSetting.extend({
1030
- type: 'time_picker',
1031
- name: 'display_format'
1032
- });
1033
- var TimePickerReturnFormatFieldSetting = DisplayFormatFieldSetting.extend({
1034
- name: 'time_picker',
1035
- name: 'return_format'
1036
- });
1037
- acf.registerFieldSetting(TimePickerDisplayFormatFieldSetting);
1038
- acf.registerFieldSetting(TimePickerReturnFormatFieldSetting);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1039
  })(jQuery);
1040
-
1041
- (function ($, undefined) {
1042
- /**
1043
- * ConditionalLogicFieldSetting
1044
- *
1045
- * description
1046
- *
1047
- * @date 3/2/18
1048
- * @since 5.6.5
1049
- *
1050
- * @param type $var Description. Default.
1051
- * @return type Description.
1052
- */
1053
- var ConditionalLogicFieldSetting = acf.FieldSetting.extend({
1054
- type: '',
1055
- name: 'conditional_logic',
1056
- events: {
1057
- 'change .conditions-toggle': 'onChangeToggle',
1058
- 'click .add-conditional-group': 'onClickAddGroup',
1059
- 'focus .condition-rule-field': 'onFocusField',
1060
- 'change .condition-rule-field': 'onChangeField',
1061
- 'change .condition-rule-operator': 'onChangeOperator',
1062
- 'click .add-conditional-rule': 'onClickAdd',
1063
- 'click .remove-conditional-rule': 'onClickRemove'
1064
- },
1065
- $rule: false,
1066
- scope: function ($rule) {
1067
- this.$rule = $rule;
1068
- return this;
1069
- },
1070
- ruleData: function (name, value) {
1071
- return this.$rule.data.apply(this.$rule, arguments);
1072
- },
1073
- $input: function (name) {
1074
- return this.$rule.find('.condition-rule-' + name);
1075
- },
1076
- $td: function (name) {
1077
- return this.$rule.find('td.' + name);
1078
- },
1079
- $toggle: function () {
1080
- return this.$('.conditions-toggle');
1081
- },
1082
- $control: function () {
1083
- return this.$('.rule-groups');
1084
- },
1085
- $groups: function () {
1086
- return this.$('.rule-group');
1087
- },
1088
- $rules: function () {
1089
- return this.$('.rule');
1090
- },
1091
- open: function () {
1092
- var $div = this.$control();
1093
- $div.show();
1094
- acf.enable($div);
1095
- },
1096
- close: function () {
1097
- var $div = this.$control();
1098
- $div.hide();
1099
- acf.disable($div);
1100
- },
1101
- render: function () {
1102
- // show
1103
- if (this.$toggle().prop('checked')) {
1104
- this.renderRules();
1105
- this.open(); // hide
1106
- } else {
1107
- this.close();
1108
- }
1109
- },
1110
- renderRules: function () {
1111
- // vars
1112
- var self = this; // loop
1113
-
1114
- this.$rules().each(function () {
1115
- self.renderRule($(this));
1116
- });
1117
- },
1118
- renderRule: function ($rule) {
1119
- this.scope($rule);
1120
- this.renderField();
1121
- this.renderOperator();
1122
- this.renderValue();
1123
- },
1124
- renderField: function () {
1125
- // vars
1126
- var choices = [];
1127
- var validFieldTypes = [];
1128
- var cid = this.fieldObject.cid;
1129
- var $select = this.$input('field'); // loop
1130
-
1131
- acf.getFieldObjects().map(function (fieldObject) {
1132
- // vars
1133
- var choice = {
1134
- id: fieldObject.getKey(),
1135
- text: fieldObject.getLabel()
1136
- }; // bail early if is self
1137
-
1138
- if (fieldObject.cid === cid) {
1139
- choice.text += acf.__('(this field)');
1140
- choice.disabled = true;
1141
- } // get selected field conditions
1142
-
1143
-
1144
- var conditionTypes = acf.getConditionTypes({
1145
- fieldType: fieldObject.getType()
1146
- }); // bail early if no types
1147
-
1148
- if (!conditionTypes.length) {
1149
- choice.disabled = true;
1150
- } // calulate indents
1151
-
1152
-
1153
- var indents = fieldObject.getParents().length;
1154
- choice.text = '- '.repeat(indents) + choice.text; // append
1155
-
1156
- choices.push(choice);
1157
- }); // allow for scenario where only one field exists
1158
-
1159
- if (!choices.length) {
1160
- choices.push({
1161
- id: '',
1162
- text: acf.__('No toggle fields available')
1163
- });
1164
- } // render
1165
-
1166
-
1167
- acf.renderSelect($select, choices); // set
1168
-
1169
- this.ruleData('field', $select.val());
1170
- },
1171
- renderOperator: function () {
1172
- // bail early if no field selected
1173
- if (!this.ruleData('field')) {
1174
- return;
1175
- } // vars
1176
-
1177
-
1178
- var $select = this.$input('operator');
1179
- var val = $select.val();
1180
- var choices = []; // set saved value on first render
1181
- // - this allows the 2nd render to correctly select an option
1182
-
1183
- if ($select.val() === null) {
1184
- acf.renderSelect($select, [{
1185
- id: this.ruleData('operator'),
1186
- text: ''
1187
- }]);
1188
- } // get selected field
1189
-
1190
-
1191
- var $field = acf.findFieldObject(this.ruleData('field'));
1192
- var field = acf.getFieldObject($field); // get selected field conditions
1193
-
1194
- var conditionTypes = acf.getConditionTypes({
1195
- fieldType: field.getType()
1196
- }); // html
1197
-
1198
- conditionTypes.map(function (model) {
1199
- choices.push({
1200
- id: model.prototype.operator,
1201
- text: model.prototype.label
1202
- });
1203
- }); // render
1204
-
1205
- acf.renderSelect($select, choices); // set
1206
-
1207
- this.ruleData('operator', $select.val());
1208
- },
1209
- renderValue: function () {
1210
- // bail early if no field selected
1211
- if (!this.ruleData('field') || !this.ruleData('operator')) {
1212
- return;
1213
- } // vars
1214
-
1215
-
1216
- var $select = this.$input('value');
1217
- var $td = this.$td('value');
1218
- var val = $select.val(); // get selected field
1219
-
1220
- var $field = acf.findFieldObject(this.ruleData('field'));
1221
- var field = acf.getFieldObject($field); // get selected field conditions
1222
-
1223
- var conditionTypes = acf.getConditionTypes({
1224
- fieldType: field.getType(),
1225
- operator: this.ruleData('operator')
1226
- }); // html
1227
-
1228
- var conditionType = conditionTypes[0].prototype;
1229
- var choices = conditionType.choices(field); // create html: array
1230
-
1231
- if (choices instanceof Array) {
1232
- var $newSelect = $('<select></select>');
1233
- acf.renderSelect($newSelect, choices); // create html: string (<input />)
1234
- } else {
1235
- var $newSelect = $(choices);
1236
- } // append
1237
-
1238
-
1239
- $select.detach();
1240
- $td.html($newSelect); // copy attrs
1241
- // timeout needed to avoid browser bug where "disabled" attribute is not applied
1242
-
1243
- setTimeout(function () {
1244
- ['class', 'name', 'id'].map(function (attr) {
1245
- $newSelect.attr(attr, $select.attr(attr));
1246
- });
1247
- }, 0); // select existing value (if not a disabled input)
1248
-
1249
- if (!$newSelect.prop('disabled')) {
1250
- acf.val($newSelect, val, true);
1251
- } // set
1252
-
1253
-
1254
- this.ruleData('value', $newSelect.val());
1255
- },
1256
- onChangeToggle: function () {
1257
- this.render();
1258
- },
1259
- onClickAddGroup: function (e, $el) {
1260
- this.addGroup();
1261
- },
1262
- addGroup: function () {
1263
- // vars
1264
- var $group = this.$('.rule-group:last'); // duplicate
1265
-
1266
- var $group2 = acf.duplicate($group); // update h4
1267
-
1268
- $group2.find('h4').text(acf.__('or')); // remove all tr's except the first one
1269
-
1270
- $group2.find('tr').not(':first').remove(); // save field
1271
-
1272
- this.fieldObject.save();
1273
- },
1274
- onFocusField: function (e, $el) {
1275
- this.renderField();
1276
- },
1277
- onChangeField: function (e, $el) {
1278
- // scope
1279
- this.scope($el.closest('.rule')); // set data
1280
-
1281
- this.ruleData('field', $el.val()); // render
1282
-
1283
- this.renderOperator();
1284
- this.renderValue();
1285
- },
1286
- onChangeOperator: function (e, $el) {
1287
- // scope
1288
- this.scope($el.closest('.rule')); // set data
1289
-
1290
- this.ruleData('operator', $el.val()); // render
1291
-
1292
- this.renderValue();
1293
- },
1294
- onClickAdd: function (e, $el) {
1295
- // duplciate
1296
- var $rule = acf.duplicate($el.closest('.rule')); // render
1297
-
1298
- this.renderRule($rule);
1299
- },
1300
- onClickRemove: function (e, $el) {
1301
- // vars
1302
- var $rule = $el.closest('.rule'); // save field
1303
-
1304
- this.fieldObject.save(); // remove group
1305
-
1306
- if ($rule.siblings('.rule').length == 0) {
1307
- $rule.closest('.rule-group').remove();
1308
- } // remove
1309
-
1310
-
1311
- $rule.remove();
1312
- }
1313
- });
1314
- acf.registerFieldSetting(ConditionalLogicFieldSetting);
1315
- /**
1316
- * conditionalLogicHelper
1317
- *
1318
- * description
1319
- *
1320
- * @date 20/4/18
1321
- * @since 5.6.9
1322
- *
1323
- * @param type $var Description. Default.
1324
- * @return type Description.
1325
- */
1326
-
1327
- var conditionalLogicHelper = new acf.Model({
1328
- actions: {
1329
- 'duplicate_field_objects': 'onDuplicateFieldObjects'
1330
- },
1331
- onDuplicateFieldObjects: function (children, newField, prevField) {
1332
- // vars
1333
- var data = {};
1334
- var $selects = $(); // reference change in key
1335
-
1336
- children.map(function (child) {
1337
- // store reference of changed key
1338
- data[child.get('prevKey')] = child.get('key'); // append condition select
1339
-
1340
- $selects = $selects.add(child.$('.condition-rule-field'));
1341
- }); // loop
1342
-
1343
- $selects.each(function () {
1344
- // vars
1345
- var $select = $(this);
1346
- var val = $select.val(); // bail early if val is not a ref key
1347
-
1348
- if (!val || !data[val]) {
1349
- return;
1350
- } // modify selected option
1351
-
1352
-
1353
- $select.find('option:selected').attr('value', data[val]); // set new val
1354
-
1355
- $select.val(data[val]);
1356
- });
1357
- }
1358
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1359
  })(jQuery);
1360
-
1361
- (function ($, undefined) {
1362
- /**
1363
- * acf.findFieldObject
1364
- *
1365
- * Returns a single fieldObject $el for a given field key
1366
- *
1367
- * @date 1/2/18
1368
- * @since 5.7.0
1369
- *
1370
- * @param string key The field key
1371
- * @return jQuery
1372
- */
1373
- acf.findFieldObject = function (key) {
1374
- return acf.findFieldObjects({
1375
- key: key,
1376
- limit: 1
1377
- });
1378
- };
1379
- /**
1380
- * acf.findFieldObjects
1381
- *
1382
- * Returns an array of fieldObject $el for the given args
1383
- *
1384
- * @date 1/2/18
1385
- * @since 5.7.0
1386
- *
1387
- * @param object args
1388
- * @return jQuery
1389
- */
1390
-
1391
-
1392
- acf.findFieldObjects = function (args) {
1393
- // vars
1394
- args = args || {};
1395
- var selector = '.acf-field-object';
1396
- var $fields = false; // args
1397
-
1398
- args = acf.parseArgs(args, {
1399
- id: '',
1400
- key: '',
1401
- type: '',
1402
- limit: false,
1403
- list: null,
1404
- parent: false,
1405
- sibling: false,
1406
- child: false
1407
- }); // id
1408
-
1409
- if (args.id) {
1410
- selector += '[data-id="' + args.id + '"]';
1411
- } // key
1412
-
1413
-
1414
- if (args.key) {
1415
- selector += '[data-key="' + args.key + '"]';
1416
- } // type
1417
-
1418
-
1419
- if (args.type) {
1420
- selector += '[data-type="' + args.type + '"]';
1421
- } // query
1422
-
1423
-
1424
- if (args.list) {
1425
- $fields = args.list.children(selector);
1426
- } else if (args.parent) {
1427
- $fields = args.parent.find(selector);
1428
- } else if (args.sibling) {
1429
- $fields = args.sibling.siblings(selector);
1430
- } else if (args.child) {
1431
- $fields = args.child.parents(selector);
1432
- } else {
1433
- $fields = $(selector);
1434
- } // limit
1435
-
1436
-
1437
- if (args.limit) {
1438
- $fields = $fields.slice(0, args.limit);
1439
- } // return
1440
-
1441
-
1442
- return $fields;
1443
- };
1444
- /**
1445
- * acf.getFieldObject
1446
- *
1447
- * Returns a single fieldObject instance for a given $el|key
1448
- *
1449
- * @date 1/2/18
1450
- * @since 5.7.0
1451
- *
1452
- * @param string|jQuery $field The field $el or key
1453
- * @return jQuery
1454
- */
1455
-
1456
-
1457
- acf.getFieldObject = function ($field) {
1458
- // allow key
1459
- if (typeof $field === 'string') {
1460
- $field = acf.findFieldObject($field);
1461
- } // instantiate
1462
-
1463
-
1464
- var field = $field.data('acf');
1465
-
1466
- if (!field) {
1467
- field = acf.newFieldObject($field);
1468
- } // return
1469
-
1470
-
1471
- return field;
1472
- };
1473
- /**
1474
- * acf.getFieldObjects
1475
- *
1476
- * Returns an array of fieldObject instances for the given args
1477
- *
1478
- * @date 1/2/18
1479
- * @since 5.7.0
1480
- *
1481
- * @param object args
1482
- * @return array
1483
- */
1484
-
1485
-
1486
- acf.getFieldObjects = function (args) {
1487
- // query
1488
- var $fields = acf.findFieldObjects(args); // loop
1489
-
1490
- var fields = [];
1491
- $fields.each(function () {
1492
- var field = acf.getFieldObject($(this));
1493
- fields.push(field);
1494
- }); // return
1495
-
1496
- return fields;
1497
- };
1498
- /**
1499
- * acf.newFieldObject
1500
- *
1501
- * Initializes and returns a new FieldObject instance
1502
- *
1503
- * @date 1/2/18
1504
- * @since 5.7.0
1505
- *
1506
- * @param jQuery $field The field $el
1507
- * @return object
1508
- */
1509
-
1510
-
1511
- acf.newFieldObject = function ($field) {
1512
- // instantiate
1513
- var field = new acf.FieldObject($field); // action
1514
-
1515
- acf.doAction('new_field_object', field); // return
1516
-
1517
- return field;
1518
- };
1519
- /**
1520
- * actionManager
1521
- *
1522
- * description
1523
- *
1524
- * @date 15/12/17
1525
- * @since 5.6.5
1526
- *
1527
- * @param type $var Description. Default.
1528
- * @return type Description.
1529
- */
1530
-
1531
-
1532
- var eventManager = new acf.Model({
1533
- priority: 5,
1534
- initialize: function () {
1535
- // actions
1536
- var actions = ['prepare', 'ready', 'append', 'remove']; // loop
1537
-
1538
- actions.map(function (action) {
1539
- this.addFieldActions(action);
1540
- }, this);
1541
- },
1542
- addFieldActions: function (action) {
1543
- // vars
1544
- var pluralAction = action + '_field_objects'; // ready_field_objects
1545
-
1546
- var singleAction = action + '_field_object'; // ready_field_object
1547
-
1548
- var singleEvent = action + 'FieldObject'; // readyFieldObject
1549
- // global action
1550
-
1551
- var callback = function ($el
1552
- /*, arg1, arg2, etc*/
1553
- ) {
1554
- // vars
1555
- var fieldObjects = acf.getFieldObjects({
1556
- parent: $el
1557
- }); // call plural
1558
-
1559
- if (fieldObjects.length) {
1560
- /// get args [$el, arg1]
1561
- var args = acf.arrayArgs(arguments); // modify args [pluralAction, fields, arg1]
1562
-
1563
- args.splice(0, 1, pluralAction, fieldObjects);
1564
- acf.doAction.apply(null, args);
1565
- }
1566
- }; // plural action
1567
-
1568
-
1569
- var pluralCallback = function (fieldObjects
1570
- /*, arg1, arg2, etc*/
1571
- ) {
1572
- /// get args [fields, arg1]
1573
- var args = acf.arrayArgs(arguments); // modify args [singleAction, fields, arg1]
1574
-
1575
- args.unshift(singleAction); // loop
1576
-
1577
- fieldObjects.map(function (fieldObject) {
1578
- // modify args [singleAction, field, arg1]
1579
- args[1] = fieldObject;
1580
- acf.doAction.apply(null, args);
1581
- });
1582
- }; // single action
1583
-
1584
-
1585
- var singleCallback = function (fieldObject
1586
- /*, arg1, arg2, etc*/
1587
- ) {
1588
- /// get args [$field, arg1]
1589
- var args = acf.arrayArgs(arguments); // modify args [singleAction, $field, arg1]
1590
-
1591
- args.unshift(singleAction); // action variations (ready_field/type=image)
1592
-
1593
- var variations = ['type', 'name', 'key'];
1594
- variations.map(function (variation) {
1595
- args[0] = singleAction + '/' + variation + '=' + fieldObject.get(variation);
1596
- acf.doAction.apply(null, args);
1597
- }); // modify args [arg1]
1598
-
1599
- args.splice(0, 2); // event
1600
-
1601
- fieldObject.trigger(singleEvent, args);
1602
- }; // add actions
1603
-
1604
-
1605
- acf.addAction(action, callback, 5);
1606
- acf.addAction(pluralAction, pluralCallback, 5);
1607
- acf.addAction(singleAction, singleCallback, 5);
1608
- }
1609
- });
1610
- /**
1611
- * fieldManager
1612
- *
1613
- * description
1614
- *
1615
- * @date 4/1/18
1616
- * @since 5.6.5
1617
- *
1618
- * @param type $var Description. Default.
1619
- * @return type Description.
1620
- */
1621
-
1622
- var fieldManager = new acf.Model({
1623
- id: 'fieldManager',
1624
- events: {
1625
- 'submit #post': 'onSubmit',
1626
- 'mouseenter .acf-field-list': 'onHoverSortable',
1627
- 'click .add-field': 'onClickAdd'
1628
- },
1629
- actions: {
1630
- 'removed_field_object': 'onRemovedField',
1631
- 'sortstop_field_object': 'onReorderField',
1632
- 'delete_field_object': 'onDeleteField',
1633
- 'change_field_object_type': 'onChangeFieldType',
1634
- 'duplicate_field_object': 'onDuplicateField'
1635
- },
1636
- onSubmit: function (e, $el) {
1637
- // vars
1638
- var fields = acf.getFieldObjects(); // loop
1639
-
1640
- fields.map(function (field) {
1641
- field.submit();
1642
- });
1643
- },
1644
- setFieldMenuOrder: function (field) {
1645
- this.renderFields(field.$el.parent());
1646
- },
1647
- onHoverSortable: function (e, $el) {
1648
- // bail early if already sortable
1649
- if ($el.hasClass('ui-sortable')) return; // sortable
1650
-
1651
- $el.sortable({
1652
- handle: '.acf-sortable-handle',
1653
- connectWith: '.acf-field-list',
1654
- start: function (e, ui) {
1655
- var field = acf.getFieldObject(ui.item);
1656
- ui.placeholder.height(ui.item.height());
1657
- acf.doAction('sortstart_field_object', field, $el);
1658
- },
1659
- update: function (e, ui) {
1660
- var field = acf.getFieldObject(ui.item);
1661
- acf.doAction('sortstop_field_object', field, $el);
1662
- }
1663
- });
1664
- },
1665
- onRemovedField: function (field, $list) {
1666
- this.renderFields($list);
1667
- },
1668
- onReorderField: function (field, $list) {
1669
- field.updateParent();
1670
- this.renderFields($list);
1671
- },
1672
- onDeleteField: function (field) {
1673
- // delete children
1674
- field.getFields().map(function (child) {
1675
- child.delete({
1676
- animate: false
1677
- });
1678
- });
1679
- },
1680
- onChangeFieldType: function (field) {// this caused sub fields to disapear if changing type back...
1681
- //this.onDeleteField( field );
1682
- },
1683
- onDuplicateField: function (field, newField) {
1684
- // check for children
1685
- var children = newField.getFields();
1686
-
1687
- if (children.length) {
1688
- // loop
1689
- children.map(function (child) {
1690
- // wipe field
1691
- child.wipe(); // update parent
1692
-
1693
- child.updateParent();
1694
- }); // action
1695
-
1696
- acf.doAction('duplicate_field_objects', children, newField, field);
1697
- } // set menu order
1698
-
1699
-
1700
- this.setFieldMenuOrder(newField);
1701
- },
1702
- renderFields: function ($list) {
1703
- // vars
1704
- var fields = acf.getFieldObjects({
1705
- list: $list
1706
- }); // no fields
1707
-
1708
- if (!fields.length) {
1709
- $list.addClass('-empty');
1710
- return;
1711
- } // has fields
1712
-
1713
-
1714
- $list.removeClass('-empty'); // prop
1715
-
1716
- fields.map(function (field, i) {
1717
- field.prop('menu_order', i);
1718
- });
1719
- },
1720
- onClickAdd: function (e, $el) {
1721
- var $list = $el.closest('.acf-tfoot').siblings('.acf-field-list');
1722
- this.addField($list);
1723
- },
1724
- addField: function ($list) {
1725
- // vars
1726
- var html = $('#tmpl-acf-field').html();
1727
- var $el = $(html);
1728
- var prevId = $el.data('id');
1729
- var newKey = acf.uniqid('field_'); // duplicate
1730
-
1731
- var $newField = acf.duplicate({
1732
- target: $el,
1733
- search: prevId,
1734
- replace: newKey,
1735
- append: function ($el, $el2) {
1736
- $list.append($el2);
1737
- }
1738
- }); // get instance
1739
-
1740
- var newField = acf.getFieldObject($newField); // props
1741
-
1742
- newField.prop('key', newKey);
1743
- newField.prop('ID', 0);
1744
- newField.prop('label', '');
1745
- newField.prop('name', ''); // attr
1746
-
1747
- $newField.attr('data-key', newKey);
1748
- $newField.attr('data-id', newKey); // update parent prop
1749
-
1750
- newField.updateParent(); // focus label
1751
-
1752
- var $label = newField.$input('label');
1753
- setTimeout(function () {
1754
- $label.trigger('focus');
1755
- }, 251); // open
1756
-
1757
- newField.open(); // set menu order
1758
-
1759
- this.renderFields($list); // action
1760
-
1761
- acf.doAction('add_field_object', newField);
1762
- acf.doAction('append_field_object', newField);
1763
- }
1764
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1765
  })(jQuery);
1766
-
1767
- (function ($, undefined) {
1768
- /**
1769
- * locationManager
1770
- *
1771
- * Field group location rules functionality
1772
- *
1773
- * @date 15/12/17
1774
- * @since 5.7.0
1775
- *
1776
- * @param void
1777
- * @return void
1778
- */
1779
- var locationManager = new acf.Model({
1780
- id: 'locationManager',
1781
- wait: 'ready',
1782
- events: {
1783
- 'click .add-location-rule': 'onClickAddRule',
1784
- 'click .add-location-group': 'onClickAddGroup',
1785
- 'click .remove-location-rule': 'onClickRemoveRule',
1786
- 'change .refresh-location-rule': 'onChangeRemoveRule'
1787
- },
1788
- initialize: function () {
1789
- this.$el = $('#acf-field-group-locations');
1790
- },
1791
- onClickAddRule: function (e, $el) {
1792
- this.addRule($el.closest('tr'));
1793
- },
1794
- onClickRemoveRule: function (e, $el) {
1795
- this.removeRule($el.closest('tr'));
1796
- },
1797
- onChangeRemoveRule: function (e, $el) {
1798
- this.changeRule($el.closest('tr'));
1799
- },
1800
- onClickAddGroup: function (e, $el) {
1801
- this.addGroup();
1802
- },
1803
- addRule: function ($tr) {
1804
- acf.duplicate($tr);
1805
- },
1806
- removeRule: function ($tr) {
1807
- if ($tr.siblings('tr').length == 0) {
1808
- $tr.closest('.rule-group').remove();
1809
- } else {
1810
- $tr.remove();
1811
- }
1812
- },
1813
- changeRule: function ($rule) {
1814
- // vars
1815
- var $group = $rule.closest('.rule-group');
1816
- var prefix = $rule.find('td.param select').attr('name').replace('[param]', ''); // ajaxdata
1817
-
1818
- var ajaxdata = {};
1819
- ajaxdata.action = 'acf/field_group/render_location_rule';
1820
- ajaxdata.rule = acf.serialize($rule, prefix);
1821
- ajaxdata.rule.id = $rule.data('id');
1822
- ajaxdata.rule.group = $group.data('id'); // temp disable
1823
-
1824
- acf.disable($rule.find('td.value')); // ajax
1825
-
1826
- $.ajax({
1827
- url: acf.get('ajaxurl'),
1828
- data: acf.prepareForAjax(ajaxdata),
1829
- type: 'post',
1830
- dataType: 'html',
1831
- success: function (html) {
1832
- if (!html) return;
1833
- $rule.replaceWith(html);
1834
- }
1835
- });
1836
- },
1837
- addGroup: function () {
1838
- // vars
1839
- var $group = this.$('.rule-group:last'); // duplicate
1840
-
1841
- $group2 = acf.duplicate($group); // update h4
1842
-
1843
- $group2.find('h4').text(acf.__('or')); // remove all tr's except the first one
1844
-
1845
- $group2.find('tr').not(':first').remove();
1846
- }
1847
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1848
  })(jQuery);
1849
-
1850
- (function ($, undefined) {
1851
- var _acf = acf.getCompatibility(acf);
1852
- /**
1853
- * fieldGroupCompatibility
1854
- *
1855
- * Compatibility layer for extinct acf.field_group
1856
- *
1857
- * @date 15/12/17
1858
- * @since 5.7.0
1859
- *
1860
- * @param void
1861
- * @return void
1862
- */
1863
-
1864
-
1865
- _acf.field_group = {
1866
- save_field: function ($field, type) {
1867
- type = type !== undefined ? type : 'settings';
1868
- acf.getFieldObject($field).save(type);
1869
- },
1870
- delete_field: function ($field, animate) {
1871
- animate = animate !== undefined ? animate : true;
1872
- acf.getFieldObject($field).delete({
1873
- animate: animate
1874
- });
1875
- },
1876
- update_field_meta: function ($field, name, value) {
1877
- acf.getFieldObject($field).prop(name, value);
1878
- },
1879
- delete_field_meta: function ($field, name) {
1880
- acf.getFieldObject($field).prop(name, null);
1881
- }
1882
- };
1883
- /**
1884
- * fieldGroupCompatibility.field_object
1885
- *
1886
- * Compatibility layer for extinct acf.field_group.field_object
1887
- *
1888
- * @date 15/12/17
1889
- * @since 5.7.0
1890
- *
1891
- * @param void
1892
- * @return void
1893
- */
1894
-
1895
- _acf.field_group.field_object = acf.model.extend({
1896
- // vars
1897
- type: '',
1898
- o: {},
1899
- $field: null,
1900
- $settings: null,
1901
- tag: function (tag) {
1902
- // vars
1903
- var type = this.type; // explode, add 'field' and implode
1904
- // - open => open_field
1905
- // - change_type => change_field_type
1906
-
1907
- var tags = tag.split('_');
1908
- tags.splice(1, 0, 'field');
1909
- tag = tags.join('_'); // add type
1910
-
1911
- if (type) {
1912
- tag += '/type=' + type;
1913
- } // return
1914
-
1915
-
1916
- return tag;
1917
- },
1918
- selector: function () {
1919
- // vars
1920
- var selector = '.acf-field-object';
1921
- var type = this.type; // add type
1922
-
1923
- if (type) {
1924
- selector += '-' + type;
1925
- selector = acf.str_replace('_', '-', selector);
1926
- } // return
1927
-
1928
-
1929
- return selector;
1930
- },
1931
- _add_action: function (name, callback) {
1932
- // vars
1933
- var model = this; // add action
1934
-
1935
- acf.add_action(this.tag(name), function ($field) {
1936
- // focus
1937
- model.set('$field', $field); // callback
1938
-
1939
- model[callback].apply(model, arguments);
1940
- });
1941
- },
1942
- _add_filter: function (name, callback) {
1943
- // vars
1944
- var model = this; // add action
1945
-
1946
- acf.add_filter(this.tag(name), function ($field) {
1947
- // focus
1948
- model.set('$field', $field); // callback
1949
-
1950
- model[callback].apply(model, arguments);
1951
- });
1952
- },
1953
- _add_event: function (name, callback) {
1954
- // vars
1955
- var model = this;
1956
- var event = name.substr(0, name.indexOf(' '));
1957
- var selector = name.substr(name.indexOf(' ') + 1);
1958
- var context = this.selector(); // add event
1959
-
1960
- $(document).on(event, context + ' ' + selector, function (e) {
1961
- // append $el to event object
1962
- e.$el = $(this);
1963
- e.$field = e.$el.closest('.acf-field-object'); // focus
1964
-
1965
- model.set('$field', e.$field); // callback
1966
-
1967
- model[callback].apply(model, [e]);
1968
- });
1969
- },
1970
- _set_$field: function () {
1971
- // vars
1972
- this.o = this.$field.data(); // els
1973
-
1974
- this.$settings = this.$field.find('> .settings > table > tbody'); // focus
1975
-
1976
- this.focus();
1977
- },
1978
- focus: function () {// do nothing
1979
- },
1980
- setting: function (name) {
1981
- return this.$settings.find('> .acf-field-setting-' + name);
1982
- }
1983
- });
1984
- /*
1985
- * field
1986
- *
1987
- * This model fires actions and filters for registered fields
1988
- *
1989
- * @type function
1990
- * @date 21/02/2014
1991
- * @since 3.5.1
1992
- *
1993
- * @param n/a
1994
- * @return n/a
1995
- */
1996
-
1997
- var actionManager = new acf.Model({
1998
- actions: {
1999
- 'open_field_object': 'onOpenFieldObject',
2000
- 'close_field_object': 'onCloseFieldObject',
2001
- 'add_field_object': 'onAddFieldObject',
2002
- 'duplicate_field_object': 'onDuplicateFieldObject',
2003
- 'delete_field_object': 'onDeleteFieldObject',
2004
- 'change_field_object_type': 'onChangeFieldObjectType',
2005
- 'change_field_object_label': 'onChangeFieldObjectLabel',
2006
- 'change_field_object_name': 'onChangeFieldObjectName',
2007
- 'change_field_object_parent': 'onChangeFieldObjectParent',
2008
- 'sortstop_field_object': 'onChangeFieldObjectParent'
2009
- },
2010
- onOpenFieldObject: function (field) {
2011
- acf.doAction('open_field', field.$el);
2012
- acf.doAction('open_field/type=' + field.get('type'), field.$el);
2013
- acf.doAction('render_field_settings', field.$el);
2014
- acf.doAction('render_field_settings/type=' + field.get('type'), field.$el);
2015
- },
2016
- onCloseFieldObject: function (field) {
2017
- acf.doAction('close_field', field.$el);
2018
- acf.doAction('close_field/type=' + field.get('type'), field.$el);
2019
- },
2020
- onAddFieldObject: function (field) {
2021
- acf.doAction('add_field', field.$el);
2022
- acf.doAction('add_field/type=' + field.get('type'), field.$el);
2023
- },
2024
- onDuplicateFieldObject: function (field) {
2025
- acf.doAction('duplicate_field', field.$el);
2026
- acf.doAction('duplicate_field/type=' + field.get('type'), field.$el);
2027
- },
2028
- onDeleteFieldObject: function (field) {
2029
- acf.doAction('delete_field', field.$el);
2030
- acf.doAction('delete_field/type=' + field.get('type'), field.$el);
2031
- },
2032
- onChangeFieldObjectType: function (field) {
2033
- acf.doAction('change_field_type', field.$el);
2034
- acf.doAction('change_field_type/type=' + field.get('type'), field.$el);
2035
- acf.doAction('render_field_settings', field.$el);
2036
- acf.doAction('render_field_settings/type=' + field.get('type'), field.$el);
2037
- },
2038
- onChangeFieldObjectLabel: function (field) {
2039
- acf.doAction('change_field_label', field.$el);
2040
- acf.doAction('change_field_label/type=' + field.get('type'), field.$el);
2041
- },
2042
- onChangeFieldObjectName: function (field) {
2043
- acf.doAction('change_field_name', field.$el);
2044
- acf.doAction('change_field_name/type=' + field.get('type'), field.$el);
2045
- },
2046
- onChangeFieldObjectParent: function (field) {
2047
- acf.doAction('update_field_parent', field.$el);
2048
- }
2049
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2050
  })(jQuery);
1
+ (function($, undefined){
2
+
3
+ /**
4
+ * fieldGroupManager
5
+ *
6
+ * Generic field group functionality
7
+ *
8
+ * @date 15/12/17
9
+ * @since 5.7.0
10
+ *
11
+ * @param void
12
+ * @return void
13
+ */
14
+
15
+ var fieldGroupManager = new acf.Model({
16
+
17
+ id: 'fieldGroupManager',
18
+
19
+ events: {
20
+ 'submit #post': 'onSubmit',
21
+ 'click a[href="#"]': 'onClick',
22
+ 'click .submitdelete': 'onClickTrash',
23
+ },
24
+
25
+ filters: {
26
+ 'find_fields_args': 'filterFindFieldArgs'
27
+ },
28
+
29
+ onSubmit: function( e, $el ){
30
+
31
+ // vars
32
+ var $title = $('#titlewrap #title');
33
+
34
+ // empty
35
+ if( !$title.val() ) {
36
+
37
+ // prevent default
38
+ e.preventDefault();
39
+
40
+ // unlock form
41
+ acf.unlockForm( $el );
42
+
43
+ // alert
44
+ alert( acf.__('Field group title is required') );
45
+
46
+ // focus
47
+ $title.trigger('focus');
48
+ }
49
+ },
50
+
51
+ onClick: function( e ){
52
+ e.preventDefault();
53
+ },
54
+
55
+ onClickTrash: function( e ){
56
+ var result = confirm( acf.__('Move to trash. Are you sure?') );
57
+ if( !result ) {
58
+ e.preventDefault();
59
+ }
60
+ },
61
+
62
+ filterFindFieldArgs: function( args ){
63
+ args.visible = true;
64
+ return args;
65
+ }
66
+ });
67
+
68
+
69
+ /**
70
+ * screenOptionsManager
71
+ *
72
+ * Screen options functionality
73
+ *
74
+ * @date 15/12/17
75
+ * @since 5.7.0
76
+ *
77
+ * @param void
78
+ * @return void
79
+ */
80
+
81
+ var screenOptionsManager = new acf.Model({
82
+
83
+ id: 'screenOptionsManager',
84
+ wait: 'prepare',
85
+
86
+ events: {
87
+ 'change': 'onChange'
88
+ },
89
+
90
+ initialize: function(){
91
+
92
+ // vars
93
+ var $div = $('#adv-settings');
94
+ var $append = $('#acf-append-show-on-screen');
95
+
96
+ // append
97
+ $div.find('.metabox-prefs').append( $append.html() );
98
+ $div.find('.metabox-prefs br').remove();
99
+
100
+ // clean up
101
+ $append.remove();
102
+
103
+ // initialize
104
+ this.$el = $('#acf-field-key-hide');
105
+
106
+ // render
107
+ this.render();
108
+ },
109
+
110
+ isChecked: function(){
111
+ return this.$el.prop('checked');
112
+ },
113
+
114
+ onChange: function( e, $el ) {
115
+ var val = this.isChecked() ? 1 : 0;
116
+ acf.updateUserSetting('show_field_keys', val);
117
+ this.render();
118
+ },
119
+
120
+ render: function(){
121
+ if( this.isChecked() ) {
122
+ $('#acf-field-group-fields').addClass('show-field-keys');
123
+ } else {
124
+ $('#acf-field-group-fields').removeClass('show-field-keys');
125
+ }
126
+ }
127
+
128
+ });
129
+
130
+
131
+ /**
132
+ * appendFieldManager
133
+ *
134
+ * Appends fields together
135
+ *
136
+ * @date 15/12/17
137
+ * @since 5.7.0
138
+ *
139
+ * @param void
140
+ * @return void
141
+ */
142
+
143
+ var appendFieldManager = new acf.Model({
144
+
145
+ actions: {
146
+ 'new_field' : 'onNewField'
147
+ },
148
+
149
+ onNewField: function( field ){
150
+
151
+ // bail ealry if not append
152
+ if( !field.has('append') ) return;
153
+
154
+ // vars
155
+ var append = field.get('append');
156
+ var $sibling = field.$el.siblings('[data-name="' + append + '"]').first();
157
+
158
+ // bail early if no sibling
159
+ if( !$sibling.length ) return;
160
+
161
+ // ul
162
+ var $div = $sibling.children('.acf-input');
163
+ var $ul = $div.children('ul');
164
+
165
+ // create ul
166
+ if( !$ul.length ) {
167
+ $div.wrapInner('<ul class="acf-hl"><li></li></ul>');
168
+ $ul = $div.children('ul');
169
+ }
170
+
171
+ // li
172
+ var html = field.$('.acf-input').html();
173
+ var $li = $('<li>' + html + '</li>');
174
+ $ul.append( $li );
175
+ $ul.attr('data-cols', $ul.children().length );
176
+
177
+ // clean up
178
+ field.remove();
179
+ }
180
+ });
181
+
182
  })(jQuery);
183
+ (function($, undefined){
184
+
185
+ acf.FieldObject = acf.Model.extend({
186
+
187
+ // class used to avoid nested event triggers
188
+ eventScope: '.acf-field-object',
189
+
190
+ // events
191
+ events: {
192
+ 'click .edit-field': 'onClickEdit',
193
+ 'click .delete-field': 'onClickDelete',
194
+ 'click .duplicate-field': 'duplicate',
195
+ 'click .move-field': 'move',
196
+
197
+ 'change .field-type': 'onChangeType',
198
+ 'change .field-required': 'onChangeRequired',
199
+ 'blur .field-label': 'onChangeLabel',
200
+ 'blur .field-name': 'onChangeName',
201
+
202
+ 'change': 'onChange',
203
+ 'changed': 'onChanged',
204
+ },
205
+
206
+ // data
207
+ data: {
208
+
209
+ // Similar to ID, but used for HTML puposes.
210
+ // It is possbile for a new field to have an ID of 0, but an id of 'field_123' */
211
+ id: 0,
212
+
213
+ // The field key ('field_123')
214
+ key: '',
215
+
216
+ // The field type (text, image, etc)
217
+ type: '',
218
+
219
+ // The $post->ID of this field
220
+ //ID: 0,
221
+
222
+ // The field's parent
223
+ //parent: 0,
224
+
225
+ // The menu order
226
+ //menu_order: 0
227
+ },
228
+
229
+ setup: function( $field ){
230
+
231
+ // set $el
232
+ this.$el = $field;
233
+
234
+ // inherit $field data (id, key, type)
235
+ this.inherit( $field );
236
+
237
+ // load additional props
238
+ // - this won't trigger 'changed'
239
+ this.prop('ID');
240
+ this.prop('parent');
241
+ this.prop('menu_order');
242
+ },
243
+
244
+ $input: function( name ){
245
+ return $('#' + this.getInputId() + '-' + name);
246
+ },
247
+
248
+ $meta: function(){
249
+ return this.$('.meta:first');
250
+ },
251
+
252
+ $handle: function(){
253
+ return this.$('.handle:first');
254
+ },
255
+
256
+ $settings: function(){
257
+ return this.$('.settings:first');
258
+ },
259
+
260
+ $setting: function( name ){
261
+ return this.$('.acf-field-settings:first > .acf-field-setting-' + name);
262
+ },
263
+
264
+ getParent: function(){
265
+ return acf.getFieldObjects({ child: this.$el, limit: 1 }).pop();
266
+ },
267
+
268
+ getParents: function(){
269
+ return acf.getFieldObjects({ child: this.$el });
270
+ },
271
+
272
+ getFields: function(){
273
+ return acf.getFieldObjects({ parent: this.$el });
274
+ },
275
+
276
+ getInputName: function(){
277
+ return 'acf_fields[' + this.get('id') + ']';
278
+ },
279
+
280
+ getInputId: function(){
281
+ return 'acf_fields-' + this.get('id');
282
+ },
283
+
284
+ newInput: function( name, value ){
285
+
286
+ // vars
287
+ var inputId = this.getInputId();
288
+ var inputName = this.getInputName();
289
+
290
+ // append name
291
+ if( name ) {
292
+ inputId += '-'+name;
293
+ inputName += '['+name+']';
294
+ }
295
+
296
+ // create input (avoid HTML + JSON value issues)
297
+ var $input = $('<input />').attr({
298
+ id: inputId,
299
+ name: inputName,
300
+ value: value
301
+ });
302
+ this.$('> .meta').append( $input );
303
+
304
+ // return
305
+ return $input;
306
+ },
307
+
308
+ getProp: function( name ){
309
+
310
+ // check data
311
+ if( this.has(name) ) {
312
+ return this.get(name);
313
+ }
314
+
315
+ // get input value
316
+ var $input = this.$input( name );
317
+ var value = $input.length ? $input.val() : null;
318
+
319
+ // set data silently (cache)
320
+ this.set(name, value, true);
321
+
322
+ // return
323
+ return value;
324
+ },
325
+
326
+ setProp: function( name, value ) {
327
+
328
+ // get input
329
+ var $input = this.$input( name );
330
+ var prevVal = $input.val();
331
+
332
+ // create if new
333
+ if( !$input.length ) {
334
+ $input = this.newInput( name, value );
335
+ }
336
+
337
+ // remove
338
+ if( value === null ) {
339
+ $input.remove();
340
+
341
+ // update
342
+ } else {
343
+ $input.val( value );
344
+ }
345
+
346
+ //console.log('setProp', name, value, this);
347
+
348
+ // set data silently (cache)
349
+ if( !this.has(name) ) {
350
+ //console.log('setting silently');
351
+ this.set(name, value, true);
352
+
353
+ // set data allowing 'change' event to fire
354
+ } else {
355
+ //console.log('setting loudly!');
356
+ this.set(name, value);
357
+ }
358
+
359
+ // return
360
+ return this;
361
+
362
+ },
363
+
364
+ prop: function( name, value ){
365
+ if( value !== undefined ) {
366
+ return this.setProp( name, value );
367
+ } else {
368
+ return this.getProp( name );
369
+ }
370
+ },
371
+
372
+ props: function( props ){
373
+ Object.keys( props ).map(function( key ){
374
+ this.setProp( key, props[key] );
375
+ }, this);
376
+ },
377
+
378
+ getLabel: function(){
379
+
380
+ // get label with empty default
381
+ var label = this.prop('label');
382
+ if( label === '' ) {
383
+ label = acf.__('(no label)')
384
+ }
385
+
386
+ // return
387
+ return label;
388
+ },
389
+
390
+ getName: function(){
391
+ return this.prop('name');
392
+ },
393
+
394
+ getType: function(){
395
+ return this.prop('type');
396
+ },
397
+
398
+ getTypeLabel: function(){
399
+ var type = this.prop('type');
400
+ var types = acf.get('fieldTypes');
401
+ return ( types[type] ) ? types[type].label : type;
402
+ },
403
+
404
+ getKey: function(){
405
+ return this.prop('key');
406
+ },
407
+
408
+ initialize: function(){
409
+ this.addProFields();
410
+ },
411
+
412
+ addProFields: function() {
413
+ // Make sure we're only running this on free version.
414
+ if (acf.data.fieldTypes.hasOwnProperty('clone')) {
415
+ return;
416
+ }
417
+
418
+ // Make sure we haven't appended these fields before.
419
+ var $fieldTypeSelect = $('.field-type').not('.acf-free-field-type');
420
+
421
+ // Append pro fields to "Layout" group.
422
+ var $layoutGroup = $fieldTypeSelect.find('optgroup option[value="group"]').parent();
423
+ $layoutGroup.append(
424
+ '<option value="null" disabled="disabled">' + acf.__('Repeater (Pro only)') + '</option>' +
425
+ '<option value="null" disabled="disabled">' + acf.__('Flexible Content (Pro only)') + '</option>' +
426
+ '<option value="null" disabled="disabled">' + acf.__('Clone (Pro only)') + '</option>'
427
+ );
428
+
429
+ // Add pro fields to "Content" group.
430
+ var $contentGroup = $fieldTypeSelect.find('optgroup option[value="image"]').parent();
431
+ $contentGroup.append(
432
+ '<option value="null" disabled="disabled">' + acf.__('Gallery (Pro only)') + '</option>'
433
+ );
434
+
435
+ $fieldTypeSelect.addClass('acf-free-field-type');
436
+ },
437
+
438
+ render: function(){
439
+
440
+ // vars
441
+ var $handle = this.$('.handle:first');
442
+ var menu_order = this.prop('menu_order');
443
+ var label = this.getLabel();
444
+ var name = this.prop('name');
445
+ var type = this.getTypeLabel();
446
+ var key = this.prop('key');
447
+ var required = this.$input('required').prop('checked');
448
+
449
+ // update menu order
450
+ $handle.find('.acf-icon').html( parseInt(menu_order) + 1 );
451
+
452
+ // update required
453
+ if( required ) {
454
+ label += ' <span class="acf-required">*</span>';
455
+ }
456
+
457
+ // update label
458
+ $handle.find('.li-field-label strong a').html( label );
459
+
460
+ // update name
461
+ $handle.find('.li-field-name').text( name );
462
+
463
+ // update type
464
+ $handle.find('.li-field-type').text( type );
465
+
466
+ // update key
467
+ $handle.find('.li-field-key').text( key );
468
+
469
+ // action for 3rd party customization
470
+ acf.doAction('render_field_object', this);
471
+ },
472
+
473
+ refresh: function(){
474
+ acf.doAction('refresh_field_object', this);
475
+ },
476
+
477
+ isOpen: function() {
478
+ return this.$el.hasClass('open');
479
+ },
480
+
481
+ onClickEdit: function( e ){
482
+ this.isOpen() ? this.close() : this.open();
483
+ },
484
+
485
+ open: function(){
486
+
487
+ // vars
488
+ var $settings = this.$el.children('.settings');
489
+
490
+ // open
491
+ $settings.slideDown();
492
+ this.$el.addClass('open');
493
+
494
+ // action (open)
495
+ acf.doAction('open_field_object', this);
496
+ this.trigger('openFieldObject');
497
+
498
+ // action (show)
499
+ acf.doAction('show', $settings);
500
+ },
501
+
502
+ close: function(){
503
+
504
+ // vars
505
+ var $settings = this.$el.children('.settings');
506
+
507
+ // close
508
+ $settings.slideUp();
509
+ this.$el.removeClass('open');
510
+
511
+ // action (close)
512
+ acf.doAction('close_field_object', this);
513
+ this.trigger('closeFieldObject');
514
+
515
+ // action (hide)
516
+ acf.doAction('hide', $settings);
517
+ },
518
+
519
+ serialize: function(){
520
+ return acf.serialize( this.$el, this.getInputName() );
521
+ },
522
+
523
+ save: function( type ){
524
+
525
+ // defaults
526
+ type = type || 'settings'; // meta, settings
527
+
528
+ // vars
529
+ var save = this.getProp('save');
530
+
531
+ // bail if already saving settings
532
+ if( save === 'settings' ) {
533
+ return;
534
+ }
535
+
536
+ // prop
537
+ this.setProp('save', type);
538
+
539
+ // debug
540
+ this.$el.attr('data-save', type);
541
+
542
+ // action
543
+ acf.doAction('save_field_object', this, type);
544
+ },
545
+
546
+ submit: function(){
547
+
548
+ // vars
549
+ var inputName = this.getInputName();
550
+ var save = this.get('save');
551
+
552
+ // close
553
+ if( this.isOpen() ) {
554
+ this.close();
555
+ }
556
+
557
+ // allow all inputs to save
558
+ if( save == 'settings' ) {
559
+ // do nothing
560
+
561
+ // allow only meta inputs to save
562
+ } else if( save == 'meta' ) {
563
+ this.$('> .settings [name^="' + inputName + '"]').remove();
564
+
565
+ // prevent all inputs from saving
566
+ } else {
567
+ this.$('[name^="' + inputName + '"]').remove();
568
+ }
569
+
570
+ // action
571
+ acf.doAction('submit_field_object', this);
572
+ },
573
+
574
+ onChange: function( e, $el ){
575
+
576
+ // save settings
577
+ this.save();
578
+
579
+ // action for 3rd party customization
580
+ acf.doAction('change_field_object', this);
581
+ },
582
+
583
+ onChanged: function( e, $el, name, value ){
584
+
585
+ // ignore 'save'
586
+ if( name == 'save' ) {
587
+ return;
588
+ }
589
+
590
+ // save meta
591
+ if( ['menu_order', 'parent'].indexOf(name) > -1 ) {
592
+ this.save('meta');
593
+
594
+ // save field
595
+ } else {
596
+ this.save();
597
+ }
598
+
599
+ // render
600
+ if( ['menu_order', 'label', 'required', 'name', 'type', 'key'].indexOf(name) > -1 ) {
601
+ this.render();
602
+ }
603
+
604
+ // action for 3rd party customization
605
+ acf.doAction('change_field_object_' + name, this, value);
606
+ },
607
+
608
+ onChangeLabel: function( e, $el ){
609
+
610
+ // set
611
+ var label = $el.val();
612
+ this.set('label', label);
613
+
614
+ // render name
615
+ if( this.prop('name') == '' ) {
616
+ var name = acf.applyFilters('generate_field_object_name', acf.strSanitize(label), this);
617
+ this.prop('name', name);
618
+ }
619
+ },
620
+
621
+ onChangeName: function( e, $el){
622
+
623
+ // set
624
+ var name = $el.val();
625
+ this.set('name', name);
626
+
627
+ // error
628
+ if( name.substr(0, 6) === 'field_' ) {
629
+ alert( acf.__('The string "field_" may not be used at the start of a field name') );
630
+ }
631
+ },
632
+
633
+ onChangeRequired: function( e, $el ){
634
+
635
+ // set
636
+ var required = $el.prop('checked') ? 1 : 0;
637
+ this.set('required', required);
638
+ },
639
+
640
+ delete: function( args ){
641
+
642
+ // defaults
643
+ args = acf.parseArgs(args, {
644
+ animate: true
645
+ });
646
+
647
+ // add to remove list
648
+ var id = this.prop('ID');
649
+
650
+ if( id ) {
651
+ var $input = $('#_acf_delete_fields');
652
+ var newVal = $input.val() + '|' + id;
653
+ $input.val( newVal );
654
+ }
655
+
656
+ // action
657
+ acf.doAction('delete_field_object', this);
658
+
659
+ // animate
660
+ if( args.animate ) {
661
+ this.removeAnimate();
662
+ } else {
663
+ this.remove();
664
+ }
665
+ },
666
+
667
+ onClickDelete: function( e, $el ){
668
+
669
+ // Bypass confirmation when holding down "shift" key.
670
+ if( e.shiftKey ) {
671
+ return this.delete();
672
+ }
673
+
674
+ // add class
675
+ this.$el.addClass('-hover');
676
+
677
+ // add tooltip
678
+ var tooltip = acf.newTooltip({
679
+ confirmRemove: true,
680
+ target: $el,
681
+ context: this,
682
+ confirm: function(){
683
+ this.delete();
684
+ },
685
+ cancel: function(){
686
+ this.$el.removeClass('-hover');
687
+ }
688
+ });
689
+ },
690
+
691
+ removeAnimate: function(){
692
+
693
+ // vars
694
+ var field = this;
695
+ var $list = this.$el.parent();
696
+ var $fields = acf.findFieldObjects({
697
+ sibling: this.$el
698
+ });
699
+
700
+ // remove
701
+ acf.remove({
702
+ target: this.$el,
703
+ endHeight: $fields.length ? 0 : 50,
704
+ complete: function(){
705
+ field.remove();
706
+ acf.doAction('removed_field_object', field, $list);
707
+ }
708
+ });
709
+
710
+ // action
711
+ acf.doAction('remove_field_object', field, $list);
712
+ },
713
+
714
+ duplicate: function(){
715
+
716
+ // vars
717
+ var newKey = acf.uniqid('field_');
718
+
719
+ // duplicate
720
+ var $newField = acf.duplicate({
721
+ target: this.$el,
722
+ search: this.get('id'),
723
+ replace: newKey,
724
+ });
725
+
726
+ // set new key
727
+ $newField.attr('data-key', newKey);
728
+
729
+ // get instance
730
+ var newField = acf.getFieldObject( $newField );
731
+
732
+ // open / close
733
+ if( this.isOpen() ) {
734
+ this.close();
735
+ } else {
736
+ newField.open();
737
+ }
738
+
739
+ // focus label
740
+ var $label = newField.$setting('label input');
741
+ setTimeout(function(){
742
+ $label.trigger('focus');
743
+ }, 251);
744
+
745
+ // update newField label / name
746
+ var label = newField.prop('label');
747
+ var name = newField.prop('name');
748
+ var end = name.split('_').pop();
749
+ var copy = acf.__('copy');
750
+
751
+ // increase suffix "1"
752
+ if( acf.isNumeric(end) ) {
753
+ var i = (end*1) + 1;
754
+ label = label.replace( end, i );
755
+ name = name.replace( end, i );
756
+
757
+ // increase suffix "(copy1)"
758
+ } else if( end.indexOf(copy) === 0 ) {
759
+ var i = end.replace(copy, '') * 1;
760
+ i = i ? i+1 : 2;
761
+
762
+ // replace
763
+ label = label.replace( end, copy + i );
764
+ name = name.replace( end, copy + i );
765
+
766
+ // add default "(copy)"
767
+ } else {
768
+ label += ' (' + copy + ')';
769
+ name += '_' + copy;
770
+ }
771
+
772
+ newField.prop('ID', 0);
773
+ newField.prop('label', label);
774
+ newField.prop('name', name);
775
+ newField.prop('key', newKey);
776
+
777
+ // action
778
+ acf.doAction('duplicate_field_object', this, newField);
779
+ acf.doAction('append_field_object', newField);
780
+ },
781
+
782
+ wipe: function(){
783
+
784
+ // vars
785
+ var prevId = this.get('id');
786
+ var prevKey = this.get('key');
787
+ var newKey = acf.uniqid('field_');
788
+
789
+ // rename
790
+ acf.rename({
791
+ target: this.$el,
792
+ search: prevId,
793
+ replace: newKey,
794
+ });
795
+
796
+ // data
797
+ this.set('id', newKey);
798
+ this.set('prevId', prevId);
799
+ this.set('prevKey', prevKey);
800
+
801
+ // props
802
+ this.prop('key', newKey);
803
+ this.prop('ID', 0);
804
+
805
+ // attr
806
+ this.$el.attr('data-key', newKey);
807
+ this.$el.attr('data-id', newKey);
808
+
809
+ // action
810
+ acf.doAction('wipe_field_object', this);
811
+ },
812
+
813
+ move: function(){
814
+
815
+ // helper
816
+ var hasChanged = function( field ){
817
+ return (field.get('save') == 'settings');
818
+ };
819
+
820
+ // vars
821
+ var changed = hasChanged(this);
822
+
823
+ // has sub fields changed
824
+ if( !changed ) {
825
+ acf.getFieldObjects({
826
+ parent: this.$el
827
+ }).map(function( field ){
828
+ changed = hasChanged(field) || field.changed;
829
+ });
830
+ }
831
+
832
+ // bail early if changed
833
+ if( changed ) {
834
+ alert( acf.__('This field cannot be moved until its changes have been saved') );
835
+ return;
836
+ }
837
+
838
+ // step 1.
839
+ var id = this.prop('ID');
840
+ var field = this;
841
+ var popup = false;
842
+ var step1 = function(){
843
+
844
+ // popup
845
+ popup = acf.newPopup({
846
+ title: acf.__('Move Custom Field'),
847
+ loading: true,
848
+ width: '300px'
849
+ });
850
+
851
+ // ajax
852
+ var ajaxData = {
853
+ action: 'acf/field_group/move_field',
854
+ field_id: id
855
+ };
856
+
857
+ // get HTML
858
+ $.ajax({
859
+ url: acf.get('ajaxurl'),
860
+ data: acf.prepareForAjax(ajaxData),
861
+ type: 'post',
862
+ dataType: 'html',
863
+ success: step2
864
+ });
865
+ };
866
+
867
+ var step2 = function( html ){
868
+
869
+ // update popup
870
+ popup.loading(false);
871
+ popup.content(html);
872
+
873
+ // submit form
874
+ popup.on('submit', 'form', step3);
875
+ };
876
+
877
+ var step3 = function( e, $el ){
878
+
879
+ // prevent
880
+ e.preventDefault();
881
+
882
+ // disable
883
+ acf.startButtonLoading( popup.$('.button') );
884
+
885
+ // ajax
886
+ var ajaxData = {
887
+ action: 'acf/field_group/move_field',
888
+ field_id: id,
889
+ field_group_id: popup.$('select').val()
890
+ };
891
+
892
+ // get HTML
893
+ $.ajax({
894
+ url: acf.get('ajaxurl'),
895
+ data: acf.prepareForAjax(ajaxData),
896
+ type: 'post',
897
+ dataType: 'html',
898
+ success: step4
899
+ });
900
+ };
901
+
902
+ var step4 = function( html ){
903
+
904
+ // update popup
905
+ popup.content(html);
906
+
907
+ // remove element
908
+ field.removeAnimate();
909
+ };
910
+
911
+ // start
912
+ step1();
913
+
914
+ },
915
+
916
+ onChangeType: function( e, $el ){
917
+
918
+ // clea previous timout
919
+ if( this.changeTimeout ) {
920
+ clearTimeout(this.changeTimeout);
921
+ }
922
+
923
+ // set new timeout
924
+ // - prevents changing type multiple times whilst user types in newType
925
+ this.changeTimeout = this.setTimeout(function(){
926
+ this.changeType( $el.val() );
927
+ }, 300);
928
+ },
929
+
930
+ changeType: function( newType ){
931
+
932
+ // vars
933
+ var prevType = this.prop('type');
934
+ var prevClass = acf.strSlugify( 'acf-field-object-' + prevType );
935
+ var newClass = acf.strSlugify( 'acf-field-object-' + newType );
936
+
937
+ // update props
938
+ this.$el.removeClass(prevClass).addClass(newClass);
939
+ this.$el.attr('data-type', newType);
940
+ this.$el.data('type', newType);
941
+
942
+ // abort XHR if this field is already loading AJAX data
943
+ if( this.has('xhr') ) {
944
+ this.get('xhr').abort();
945
+ }
946
+
947
+ // store settings
948
+ var $tbody = this.$('> .settings > table > tbody');
949
+ var $settings = $tbody.children('[data-setting="' + prevType + '"]');
950
+ this.set( 'settings-' + prevType, $settings );
951
+ $settings.detach();
952
+
953
+ // show settings
954
+ if( this.has('settings-' + newType) ) {
955
+ var $newSettings = this.get('settings-' + newType);
956
+ this.$setting('conditional_logic').before( $newSettings );
957
+ this.set('type', newType);
958
+ //this.refresh();
959
+ return;
960
+ }
961
+
962
+ // load settings
963
+ var $loading = $('<tr class="acf-field"><td class="acf-label"></td><td class="acf-input"><div class="acf-loading"></div></td></tr>');
964
+ this.$setting('conditional_logic').before( $loading );
965
+
966
+ // ajax
967
+ var ajaxData = {
968
+ action: 'acf/field_group/render_field_settings',
969
+ field: this.serialize(),
970
+ prefix: this.getInputName()
971
+ };
972
+
973
+ // ajax
974
+ var xhr = $.ajax({
975
+ url: acf.get('ajaxurl'),
976
+ data: acf.prepareForAjax(ajaxData),
977
+ type: 'post',
978
+ dataType: 'html',
979
+ context: this,
980
+ success: function( html ){
981
+
982
+ // bail early if no settings
983
+ if( !html ) return;
984
+
985
+ // append settings
986
+ $loading.after( html );
987
+
988
+ // events
989
+ acf.doAction('append', $tbody);
990
+ },
991
+ complete: function(){
992
+ // also triggered by xhr.abort();
993
+ $loading.remove();
994
+ this.set('type', newType);
995
+ //this.refresh();
996
+ }
997
+ });
998
+
999
+ // set
1000
+ this.set('xhr', xhr);
1001
+
1002
+ },
1003
+
1004
+ updateParent: function(){
1005
+
1006
+ // vars
1007
+ var ID = acf.get('post_id');
1008
+
1009
+ // check parent
1010
+ var parent = this.getParent();
1011
+ if( parent ) {
1012
+ ID = parseInt(parent.prop('ID')) || parent.prop('key');
1013
+ }
1014
+
1015
+ // update
1016
+ this.prop('parent', ID);
1017
+ }
1018
+
1019
+ });
1020
+
1021
  })(jQuery);
1022
+ (function($, undefined){
1023
+
1024
+ /**
1025
+ * mid
1026
+ *
1027
+ * Calculates the model ID for a field type
1028
+ *
1029
+ * @date 15/12/17
1030
+ * @since 5.6.5
1031
+ *
1032
+ * @param string type
1033
+ * @return string
1034
+ */
1035
+
1036
+ var modelId = function( type ) {
1037
+ return acf.strPascalCase( type || '' ) + 'FieldSetting';
1038
+ };
1039
+
1040
+ /**
1041
+ * registerFieldType
1042
+ *
1043
+ * description
1044
+ *
1045
+ * @date 14/12/17
1046
+ * @since 5.6.5
1047
+ *
1048
+ * @param type $var Description. Default.
1049
+ * @return type Description.
1050
+ */
1051
+
1052
+ acf.registerFieldSetting = function( model ){
1053
+ var proto = model.prototype;
1054
+ var mid = modelId(proto.type + ' ' + proto.name);
1055
+ this.models[ mid ] = model;
1056
+ };
1057
+
1058
+ /**
1059
+ * newField
1060
+ *
1061
+ * description
1062
+ *
1063
+ * @date 14/12/17
1064
+ * @since 5.6.5
1065
+ *
1066
+ * @param type $var Description. Default.
1067
+ * @return type Description.
1068
+ */
1069
+
1070
+ acf.newFieldSetting = function( field ){
1071
+
1072
+ // vars
1073
+ var type = field.get('setting') || '';
1074
+ var name = field.get('name') || '';
1075
+ var mid = modelId( type + ' ' + name );
1076
+ var model = acf.models[ mid ] || null;
1077
+
1078
+ // bail ealry if no setting
1079
+ if( model === null ) return false;
1080
+
1081
+ // instantiate
1082
+ var setting = new model( field );
1083
+
1084
+ // return
1085
+ return setting;
1086
+ };
1087
+
1088
+ /**
1089
+ * acf.getFieldSetting
1090
+ *
1091
+ * description
1092
+ *
1093
+ * @date 19/4/18
1094
+ * @since 5.6.9
1095
+ *
1096
+ * @param type $var Description. Default.
1097
+ * @return type Description.
1098
+ */
1099
+
1100
+ acf.getFieldSetting = function( field ) {
1101
+
1102
+ // allow jQuery
1103
+ if( field instanceof jQuery ) {
1104
+ field = acf.getField(field);
1105
+ }
1106
+
1107
+ // return
1108
+ return field.setting;
1109
+ };
1110
+
1111
+ /**
1112
+ * settingsManager
1113
+ *
1114
+ * description
1115
+ *
1116
+ * @date 6/1/18
1117
+ * @since 5.6.5
1118
+ *
1119
+ * @param type $var Description. Default.
1120
+ * @return type Description.
1121
+ */
1122
+
1123
+ var settingsManager = new acf.Model({
1124
+ actions: {
1125
+ 'new_field': 'onNewField'
1126
+ },
1127
+ onNewField: function( field ){
1128
+ field.setting = acf.newFieldSetting( field );
1129
+ }
1130
+ });
1131
+
1132
+ /**
1133
+ * acf.FieldSetting
1134
+ *
1135
+ * description
1136
+ *
1137
+ * @date 6/1/18
1138
+ * @since 5.6.5
1139
+ *
1140
+ * @param type $var Description. Default.
1141
+ * @return type Description.
1142
+ */
1143
+
1144
+ acf.FieldSetting = acf.Model.extend({
1145
+
1146
+ field: false,
1147
+ type: '',
1148
+ name: '',
1149
+ wait: 'ready',
1150
+ eventScope: '.acf-field',
1151
+
1152
+ events: {
1153
+ 'change': 'render'
1154
+ },
1155
+
1156
+ setup: function( field ){
1157
+
1158
+ // vars
1159
+ var $field = field.$el;
1160
+
1161
+ // set props
1162
+ this.$el = $field;
1163
+ this.field = field;
1164
+ this.$fieldObject = $field.closest('.acf-field-object');
1165
+ this.fieldObject = acf.getFieldObject( this.$fieldObject );
1166
+
1167
+ // inherit data
1168
+ $.extend(this.data, field.data);
1169
+ },
1170
+
1171
+ initialize: function(){
1172
+ this.render();
1173
+ },
1174
+
1175
+ render: function(){
1176
+ // do nothing
1177
+ }
1178
+ });
1179
+
1180
+ /*
1181
+ * Date Picker
1182
+ *
1183
+ * This field type requires some extra logic for its settings
1184
+ *
1185
+ * @type function
1186
+ * @date 24/10/13
1187
+ * @since 5.0.0
1188
+ *
1189
+ * @param n/a
1190
+ * @return n/a
1191
+ */
1192
+
1193
+ var DisplayFormatFieldSetting = acf.FieldSetting.extend({
1194
+ type: '',
1195
+ name: '',
1196
+ render: function(){
1197
+ var $input = this.$('input[type="radio"]:checked');
1198
+ if( $input.val() != 'other' ) {
1199
+ this.$('input[type="text"]').val( $input.val() );
1200
+ }
1201
+ }
1202
+ });
1203
+
1204
+ var DatePickerDisplayFormatFieldSetting = DisplayFormatFieldSetting.extend({
1205
+ type: 'date_picker',
1206
+ name: 'display_format'
1207
+ });
1208
+
1209
+ var DatePickerReturnFormatFieldSetting = DisplayFormatFieldSetting.extend({
1210
+ type: 'date_picker',
1211
+ name: 'return_format'
1212
+ });
1213
+
1214
+ acf.registerFieldSetting( DatePickerDisplayFormatFieldSetting );
1215
+ acf.registerFieldSetting( DatePickerReturnFormatFieldSetting );
1216
+
1217
+ /*
1218
+ * Date Time Picker
1219
+ *
1220
+ * This field type requires some extra logic for its settings
1221
+ *
1222
+ * @type function
1223
+ * @date 24/10/13
1224
+ * @since 5.0.0
1225
+ *
1226
+ * @param n/a
1227
+ * @return n/a
1228
+ */
1229
+
1230
+ var DateTimePickerDisplayFormatFieldSetting = DisplayFormatFieldSetting.extend({
1231
+ type: 'date_time_picker',
1232
+ name: 'display_format'
1233
+ });
1234
+
1235
+ var DateTimePickerReturnFormatFieldSetting = DisplayFormatFieldSetting.extend({
1236
+ type: 'date_time_picker',
1237
+ name: 'return_format'
1238
+ });
1239
+
1240
+ acf.registerFieldSetting( DateTimePickerDisplayFormatFieldSetting );
1241
+ acf.registerFieldSetting( DateTimePickerReturnFormatFieldSetting );
1242
+
1243
+ /*
1244
+ * Time Picker
1245
+ *
1246
+ * This field type requires some extra logic for its settings
1247
+ *
1248
+ * @type function
1249
+ * @date 24/10/13
1250
+ * @since 5.0.0
1251
+ *
1252
+ * @param n/a
1253
+ * @return n/a
1254
+ */
1255
+
1256
+ var TimePickerDisplayFormatFieldSetting = DisplayFormatFieldSetting.extend({
1257
+ type: 'time_picker',
1258
+ name: 'display_format'
1259
+ });
1260
+
1261
+ var TimePickerReturnFormatFieldSetting = DisplayFormatFieldSetting.extend({
1262
+ name: 'time_picker',
1263
+ name: 'return_format'
1264
+ });
1265
+
1266
+ acf.registerFieldSetting( TimePickerDisplayFormatFieldSetting );
1267
+ acf.registerFieldSetting( TimePickerReturnFormatFieldSetting );
1268
+
1269
  })(jQuery);
1270
+ (function($, undefined){
1271
+
1272
+ /**
1273
+ * ConditionalLogicFieldSetting
1274
+ *
1275
+ * description
1276
+ *
1277
+ * @date 3/2/18
1278
+ * @since 5.6.5
1279
+ *
1280
+ * @param type $var Description. Default.
1281
+ * @return type Description.
1282
+ */
1283
+
1284
+ var ConditionalLogicFieldSetting = acf.FieldSetting.extend({
1285
+ type: '',
1286
+ name: 'conditional_logic',
1287
+ events: {
1288
+ 'change .conditions-toggle': 'onChangeToggle',
1289
+ 'click .add-conditional-group': 'onClickAddGroup',
1290
+ 'focus .condition-rule-field': 'onFocusField',
1291
+ 'change .condition-rule-field': 'onChangeField',
1292
+ 'change .condition-rule-operator': 'onChangeOperator',
1293
+ 'click .add-conditional-rule': 'onClickAdd',
1294
+ 'click .remove-conditional-rule': 'onClickRemove'
1295
+ },
1296
+
1297
+ $rule: false,
1298
+
1299
+ scope: function( $rule ){
1300
+ this.$rule = $rule;
1301
+ return this;
1302
+ },
1303
+
1304
+ ruleData: function( name, value ){
1305
+ return this.$rule.data.apply( this.$rule, arguments );
1306
+ },
1307
+
1308
+ $input: function( name ){
1309
+ return this.$rule.find('.condition-rule-' + name);
1310
+ },
1311
+
1312
+ $td: function( name ){
1313
+ return this.$rule.find('td.' + name);
1314
+ },
1315
+
1316
+ $toggle: function(){
1317
+ return this.$('.conditions-toggle');
1318
+ },
1319
+
1320
+ $control: function(){
1321
+ return this.$('.rule-groups');
1322
+ },
1323
+
1324
+ $groups: function(){
1325
+ return this.$('.rule-group');
1326
+ },
1327
+
1328
+ $rules: function(){
1329
+ return this.$('.rule');
1330
+ },
1331
+
1332
+ open: function(){
1333
+ var $div = this.$control();
1334
+ $div.show();
1335
+ acf.enable( $div );
1336
+ },
1337
+
1338
+ close: function(){
1339
+ var $div = this.$control();
1340
+ $div.hide();
1341
+ acf.disable( $div );
1342
+ },
1343
+
1344
+ render: function(){
1345
+
1346
+ // show
1347
+ if( this.$toggle().prop('checked') ) {
1348
+ this.renderRules();
1349
+ this.open();
1350
+
1351
+ // hide
1352
+ } else {
1353
+ this.close();
1354
+ }
1355
+ },
1356
+
1357
+ renderRules: function(){
1358
+
1359
+ // vars
1360
+ var self = this;
1361
+
1362
+ // loop
1363
+ this.$rules().each(function(){
1364
+ self.renderRule( $(this) );
1365
+ });
1366
+ },
1367
+
1368
+ renderRule: function( $rule ){
1369
+ this.scope( $rule );
1370
+ this.renderField();
1371
+ this.renderOperator();
1372
+ this.renderValue();
1373
+ },
1374
+
1375
+ renderField: function(){
1376
+
1377
+ // vars
1378
+ var choices = [];
1379
+ var validFieldTypes = [];
1380
+ var cid = this.fieldObject.cid;
1381
+ var $select = this.$input('field');
1382
+
1383
+ // loop
1384
+ acf.getFieldObjects().map(function( fieldObject ){
1385
+
1386
+ // vars
1387
+ var choice = {
1388
+ id: fieldObject.getKey(),
1389
+ text: fieldObject.getLabel()
1390
+ };
1391
+
1392
+ // bail early if is self
1393
+ if( fieldObject.cid === cid ) {
1394
+ choice.text += acf.__('(this field)');
1395
+ choice.disabled = true;
1396
+ }
1397
+
1398
+ // get selected field conditions
1399
+ var conditionTypes = acf.getConditionTypes({
1400
+ fieldType: fieldObject.getType()
1401
+ });
1402
+
1403
+ // bail early if no types
1404
+ if( !conditionTypes.length ) {
1405
+ choice.disabled = true;
1406
+ }
1407
+
1408
+ // calulate indents
1409
+ var indents = fieldObject.getParents().length;
1410
+ choice.text = '- '.repeat(indents) + choice.text;
1411
+
1412
+ // append
1413
+ choices.push(choice);
1414
+ });
1415
+
1416
+ // allow for scenario where only one field exists
1417
+ if( !choices.length ) {
1418
+ choices.push({
1419
+ id: '',
1420
+ text: acf.__('No toggle fields available'),
1421
+ });
1422
+ }
1423
+
1424
+ // render
1425
+ acf.renderSelect( $select, choices );
1426
+
1427
+ // set
1428
+ this.ruleData('field', $select.val());
1429
+ },
1430
+
1431
+ renderOperator: function(){
1432
+
1433
+ // bail early if no field selected
1434
+ if( !this.ruleData('field') ) {
1435
+ return;
1436
+ }
1437
+
1438
+ // vars
1439
+ var $select = this.$input('operator');
1440
+ var val = $select.val();
1441
+ var choices = [];
1442
+
1443
+ // set saved value on first render
1444
+ // - this allows the 2nd render to correctly select an option
1445
+ if( $select.val() === null ) {
1446
+ acf.renderSelect($select, [{
1447
+ id: this.ruleData('operator'),
1448
+ text: ''
1449
+ }]);
1450
+ }
1451
+
1452
+ // get selected field
1453
+ var $field = acf.findFieldObject( this.ruleData('field') );
1454
+ var field = acf.getFieldObject( $field );
1455
+
1456
+ // get selected field conditions
1457
+ var conditionTypes = acf.getConditionTypes({
1458
+ fieldType: field.getType()
1459
+ });
1460
+
1461
+ // html
1462
+ conditionTypes.map(function( model ){
1463
+ choices.push({
1464
+ id: model.prototype.operator,
1465
+ text: model.prototype.label
1466
+ });
1467
+ });
1468
+
1469
+ // render
1470
+ acf.renderSelect( $select, choices );
1471
+
1472
+ // set
1473
+ this.ruleData('operator', $select.val());
1474
+ },
1475
+
1476
+ renderValue: function(){
1477
+
1478
+ // bail early if no field selected
1479
+ if( !this.ruleData('field') || !this.ruleData('operator') ) {
1480
+ return;
1481
+ }
1482
+
1483
+ // vars
1484
+ var $select = this.$input('value');
1485
+ var $td = this.$td('value');
1486
+ var val = $select.val();
1487
+
1488
+ // get selected field
1489
+ var $field = acf.findFieldObject( this.ruleData('field') );
1490
+ var field = acf.getFieldObject( $field );
1491
+
1492
+ // get selected field conditions
1493
+ var conditionTypes = acf.getConditionTypes({
1494
+ fieldType: field.getType(),
1495
+ operator: this.ruleData('operator')
1496
+ });
1497
+
1498
+ // html
1499
+ var conditionType = conditionTypes[0].prototype;
1500
+ var choices = conditionType.choices( field );
1501
+
1502
+ // create html: array
1503
+ if( choices instanceof Array ) {
1504
+ var $newSelect = $('<select></select>');
1505
+ acf.renderSelect( $newSelect, choices );
1506
+
1507
+ // create html: string (<input />)
1508
+ } else {
1509
+ var $newSelect = $(choices);
1510
+ }
1511
+
1512
+ // append
1513
+ $select.detach();
1514
+ $td.html( $newSelect );
1515
+
1516
+ // copy attrs
1517
+ // timeout needed to avoid browser bug where "disabled" attribute is not applied
1518
+ setTimeout(function(){
1519
+ ['class', 'name', 'id'].map(function( attr ){
1520
+ $newSelect.attr( attr, $select.attr(attr));
1521
+ });
1522
+ }, 0);
1523
+
1524
+ // select existing value (if not a disabled input)
1525
+ if( !$newSelect.prop('disabled') ) {
1526
+ acf.val( $newSelect, val, true );
1527
+ }
1528
+
1529
+ // set
1530
+ this.ruleData('value', $newSelect.val());
1531
+ },
1532
+
1533
+ onChangeToggle: function(){
1534
+ this.render();
1535
+ },
1536
+
1537
+ onClickAddGroup: function( e, $el ){
1538
+ this.addGroup();
1539
+ },
1540
+
1541
+ addGroup: function(){
1542
+
1543
+ // vars
1544
+ var $group = this.$('.rule-group:last');
1545
+
1546
+ // duplicate
1547
+ var $group2 = acf.duplicate( $group );
1548
+
1549
+ // update h4
1550
+ $group2.find('h4').text( acf.__('or') );
1551
+
1552
+ // remove all tr's except the first one
1553
+ $group2.find('tr').not(':first').remove();
1554
+
1555
+ // save field
1556
+ this.fieldObject.save();
1557
+ },
1558
+
1559
+ onFocusField: function( e, $el ){
1560
+ this.renderField();
1561
+ },
1562
+
1563
+ onChangeField: function( e, $el ){
1564
+
1565
+ // scope
1566
+ this.scope( $el.closest('.rule') );
1567
+
1568
+ // set data
1569
+ this.ruleData('field', $el.val());
1570
+
1571
+ // render
1572
+ this.renderOperator();
1573
+ this.renderValue();
1574
+ },
1575
+
1576
+ onChangeOperator: function( e, $el ){
1577
+
1578
+ // scope
1579
+ this.scope( $el.closest('.rule') );
1580
+
1581
+ // set data
1582
+ this.ruleData('operator', $el.val());
1583
+
1584
+ // render
1585
+ this.renderValue();
1586
+ },
1587
+
1588
+ onClickAdd: function( e, $el ){
1589
+
1590
+ // duplciate
1591
+ var $rule = acf.duplicate( $el.closest('.rule') );
1592
+
1593
+ // render
1594
+ this.renderRule( $rule );
1595
+ },
1596
+
1597
+ onClickRemove: function( e, $el ){
1598
+
1599
+ // vars
1600
+ var $rule = $el.closest('.rule');
1601
+
1602
+ // save field
1603
+ this.fieldObject.save();
1604
+
1605
+ // remove group
1606
+ if( $rule.siblings('.rule').length == 0 ) {
1607
+ $rule.closest('.rule-group').remove();
1608
+ }
1609
+
1610
+ // remove
1611
+ $rule.remove();
1612
+ }
1613
+ });
1614
+
1615
+ acf.registerFieldSetting( ConditionalLogicFieldSetting );
1616
+
1617
+
1618
+ /**
1619
+ * conditionalLogicHelper
1620
+ *
1621
+ * description
1622
+ *
1623
+ * @date 20/4/18
1624
+ * @since 5.6.9
1625
+ *
1626
+ * @param type $var Description. Default.
1627
+ * @return type Description.
1628
+ */
1629
+
1630
+ var conditionalLogicHelper = new acf.Model({
1631
+ actions: {
1632
+ 'duplicate_field_objects': 'onDuplicateFieldObjects',
1633
+ },
1634
+
1635
+ onDuplicateFieldObjects: function( children, newField, prevField ){
1636
+
1637
+ // vars
1638
+ var data = {};
1639
+ var $selects = $();
1640
+
1641
+ // reference change in key
1642
+ children.map(function( child ){
1643
+
1644
+ // store reference of changed key
1645
+ data[ child.get('prevKey') ] = child.get('key');
1646
+
1647
+ // append condition select
1648
+ $selects = $selects.add( child.$('.condition-rule-field') );
1649
+ });
1650
+
1651
+ // loop
1652
+ $selects.each(function(){
1653
+
1654
+ // vars
1655
+ var $select = $(this);
1656
+ var val = $select.val();
1657
+
1658
+ // bail early if val is not a ref key
1659
+ if( !val || !data[val] ) {
1660
+ return;
1661
+ }
1662
+
1663
+ // modify selected option
1664
+ $select.find('option:selected').attr('value', data[val]);
1665
+
1666
+ // set new val
1667
+ $select.val( data[val] );
1668
+
1669
+ });
1670
+ },
1671
+ });
1672
  })(jQuery);
1673
+ (function($, undefined){
1674
+
1675
+ /**
1676
+ * acf.findFieldObject
1677
+ *
1678
+ * Returns a single fieldObject $el for a given field key
1679
+ *
1680
+ * @date 1/2/18
1681
+ * @since 5.7.0
1682
+ *
1683
+ * @param string key The field key
1684
+ * @return jQuery
1685
+ */
1686
+
1687
+ acf.findFieldObject = function( key ){
1688
+ return acf.findFieldObjects({
1689
+ key: key,
1690
+ limit: 1
1691
+ });
1692
+ };
1693
+
1694
+ /**
1695
+ * acf.findFieldObjects
1696
+ *
1697
+ * Returns an array of fieldObject $el for the given args
1698
+ *
1699
+ * @date 1/2/18
1700
+ * @since 5.7.0
1701
+ *
1702
+ * @param object args
1703
+ * @return jQuery
1704
+ */
1705
+
1706
+ acf.findFieldObjects = function( args ){
1707
+
1708
+ // vars
1709
+ args = args || {};
1710
+ var selector = '.acf-field-object';
1711
+ var $fields = false;
1712
+
1713
+ // args
1714
+ args = acf.parseArgs(args, {
1715
+ id: '',
1716
+ key: '',
1717
+ type: '',
1718
+ limit: false,
1719
+ list: null,
1720
+ parent: false,
1721
+ sibling: false,
1722
+ child: false,
1723
+ });
1724
+
1725
+ // id
1726
+ if( args.id ) {
1727
+ selector += '[data-id="' + args.id + '"]';
1728
+ }
1729
+
1730
+ // key
1731
+ if( args.key ) {
1732
+ selector += '[data-key="' + args.key + '"]';
1733
+ }
1734
+
1735
+ // type
1736
+ if( args.type ) {
1737
+ selector += '[data-type="' + args.type + '"]';
1738
+ }
1739
+
1740
+ // query
1741
+ if( args.list ) {
1742
+ $fields = args.list.children( selector );
1743
+ } else if( args.parent ) {
1744
+ $fields = args.parent.find( selector );
1745
+ } else if( args.sibling ) {
1746
+ $fields = args.sibling.siblings( selector );
1747
+ } else if( args.child ) {
1748
+ $fields = args.child.parents( selector );
1749
+ } else {
1750
+ $fields = $( selector );
1751
+ }
1752
+
1753
+ // limit
1754
+ if( args.limit ) {
1755
+ $fields = $fields.slice( 0, args.limit );
1756
+ }
1757
+
1758
+ // return
1759
+ return $fields;
1760
+ };
1761
+
1762
+ /**
1763
+ * acf.getFieldObject
1764
+ *
1765
+ * Returns a single fieldObject instance for a given $el|key
1766
+ *
1767
+ * @date 1/2/18
1768
+ * @since 5.7.0
1769
+ *
1770
+ * @param string|jQuery $field The field $el or key
1771
+ * @return jQuery
1772
+ */
1773
+
1774
+ acf.getFieldObject = function( $field ){
1775
+
1776
+ // allow key
1777
+ if( typeof $field === 'string' ) {
1778
+ $field = acf.findFieldObject( $field );
1779
+ }
1780
+
1781
+ // instantiate
1782
+ var field = $field.data('acf');
1783
+ if( !field ) {
1784
+ field = acf.newFieldObject( $field );
1785
+ }
1786
+
1787
+ // return
1788
+ return field;
1789
+ };
1790
+
1791
+ /**
1792
+ * acf.getFieldObjects
1793
+ *
1794
+ * Returns an array of fieldObject instances for the given args
1795
+ *
1796
+ * @date 1/2/18
1797
+ * @since 5.7.0
1798
+ *
1799
+ * @param object args
1800
+ * @return array
1801
+ */
1802
+
1803
+ acf.getFieldObjects = function( args ){
1804
+
1805
+ // query
1806
+ var $fields = acf.findFieldObjects( args );
1807
+
1808
+ // loop
1809
+ var fields = [];
1810
+ $fields.each(function(){
1811
+ var field = acf.getFieldObject( $(this) );
1812
+ fields.push( field );
1813
+ });
1814
+
1815
+ // return
1816
+ return fields;
1817
+ };
1818
+
1819
+ /**
1820
+ * acf.newFieldObject
1821
+ *
1822
+ * Initializes and returns a new FieldObject instance
1823
+ *
1824
+ * @date 1/2/18
1825
+ * @since 5.7.0
1826
+ *
1827
+ * @param jQuery $field The field $el
1828
+ * @return object
1829
+ */
1830
+
1831
+ acf.newFieldObject = function( $field ){
1832
+
1833
+ // instantiate
1834
+ var field = new acf.FieldObject( $field );
1835
+
1836
+ // action
1837
+ acf.doAction('new_field_object', field);
1838
+
1839
+ // return
1840
+ return field;
1841
+ };
1842
+
1843
+ /**
1844
+ * actionManager
1845
+ *
1846
+ * description
1847
+ *
1848
+ * @date 15/12/17
1849
+ * @since 5.6.5
1850
+ *
1851
+ * @param type $var Description. Default.
1852
+ * @return type Description.
1853
+ */
1854
+
1855
+ var eventManager = new acf.Model({
1856
+
1857
+ priority: 5,
1858
+
1859
+ initialize: function(){
1860
+
1861
+ // actions
1862
+ var actions = [
1863
+ 'prepare',
1864
+ 'ready',
1865
+ 'append',
1866
+ 'remove'
1867
+ ];
1868
+
1869
+ // loop
1870
+ actions.map(function( action ){
1871
+ this.addFieldActions( action );
1872
+ }, this);
1873
+ },
1874
+
1875
+ addFieldActions: function( action ){
1876
+
1877
+ // vars
1878
+ var pluralAction = action + '_field_objects'; // ready_field_objects
1879
+ var singleAction = action + '_field_object'; // ready_field_object
1880
+ var singleEvent = action + 'FieldObject'; // readyFieldObject
1881
+
1882
+ // global action
1883
+ var callback = function( $el /*, arg1, arg2, etc*/ ){
1884
+
1885
+ // vars
1886
+ var fieldObjects = acf.getFieldObjects({ parent: $el });
1887
+
1888
+ // call plural
1889
+ if( fieldObjects.length ) {
1890
+
1891
+ /// get args [$el, arg1]
1892
+ var args = acf.arrayArgs( arguments );
1893
+
1894
+ // modify args [pluralAction, fields, arg1]
1895
+ args.splice(0, 1, pluralAction, fieldObjects);
1896
+ acf.doAction.apply(null, args);
1897
+ }
1898
+ };
1899
+
1900
+ // plural action
1901
+ var pluralCallback = function( fieldObjects /*, arg1, arg2, etc*/ ){
1902
+
1903
+ /// get args [fields, arg1]
1904
+ var args = acf.arrayArgs( arguments );
1905
+
1906
+ // modify args [singleAction, fields, arg1]
1907
+ args.unshift(singleAction);
1908
+
1909
+ // loop
1910
+ fieldObjects.map(function( fieldObject ){
1911
+
1912
+ // modify args [singleAction, field, arg1]
1913
+ args[1] = fieldObject;
1914
+ acf.doAction.apply(null, args);
1915
+ });
1916
+ };
1917
+
1918
+ // single action
1919
+ var singleCallback = function( fieldObject /*, arg1, arg2, etc*/ ){
1920
+
1921
+ /// get args [$field, arg1]
1922
+ var args = acf.arrayArgs( arguments );
1923
+
1924
+ // modify args [singleAction, $field, arg1]
1925
+ args.unshift(singleAction);
1926
+
1927
+ // action variations (ready_field/type=image)
1928
+ var variations = ['type', 'name', 'key'];
1929
+ variations.map(function( variation ){
1930
+ args[0] = singleAction + '/' + variation + '=' + fieldObject.get(variation);
1931
+ acf.doAction.apply(null, args);
1932
+ });
1933
+
1934
+ // modify args [arg1]
1935
+ args.splice(0, 2);
1936
+
1937
+ // event
1938
+ fieldObject.trigger(singleEvent, args);
1939
+ };
1940
+
1941
+ // add actions
1942
+ acf.addAction(action, callback, 5);
1943
+ acf.addAction(pluralAction, pluralCallback, 5);
1944
+ acf.addAction(singleAction, singleCallback, 5);
1945
+
1946
+ }
1947
+ });
1948
+
1949
+ /**
1950
+ * fieldManager
1951
+ *
1952
+ * description
1953
+ *
1954
+ * @date 4/1/18
1955
+ * @since 5.6.5
1956
+ *
1957
+ * @param type $var Description. Default.
1958
+ * @return type Description.
1959
+ */
1960
+
1961
+ var fieldManager = new acf.Model({
1962
+
1963
+ id: 'fieldManager',
1964
+
1965
+ events: {
1966
+ 'submit #post': 'onSubmit',
1967
+ 'mouseenter .acf-field-list': 'onHoverSortable',
1968
+ 'click .add-field': 'onClickAdd',
1969
+ },
1970
+
1971
+ actions: {
1972
+ 'removed_field_object': 'onRemovedField',
1973
+ 'sortstop_field_object': 'onReorderField',
1974
+ 'delete_field_object': 'onDeleteField',
1975
+ 'change_field_object_type': 'onChangeFieldType',
1976
+ 'duplicate_field_object': 'onDuplicateField'
1977
+ },
1978
+
1979
+ onSubmit: function( e, $el ){
1980
+
1981
+ // vars
1982
+ var fields = acf.getFieldObjects();
1983
+
1984
+ // loop
1985
+ fields.map(function( field ){
1986
+ field.submit();
1987
+ });
1988
+ },
1989
+
1990
+ setFieldMenuOrder: function( field ){
1991
+ this.renderFields( field.$el.parent() );
1992
+ },
1993
+
1994
+ onHoverSortable: function( e, $el ){
1995
+
1996
+ // bail early if already sortable
1997
+ if( $el.hasClass('ui-sortable') ) return;
1998
+
1999
+ // sortable
2000
+ $el.sortable({
2001
+ handle: '.acf-sortable-handle',
2002
+ connectWith: '.acf-field-list',
2003
+ start: function( e, ui ){
2004
+ var field = acf.getFieldObject( ui.item );
2005
+ ui.placeholder.height( ui.item.height() );
2006
+ acf.doAction('sortstart_field_object', field, $el);
2007
+ },
2008
+ update: function( e, ui ){
2009
+ var field = acf.getFieldObject( ui.item );
2010
+ acf.doAction('sortstop_field_object', field, $el);
2011
+ }
2012
+ });
2013
+ },
2014
+
2015
+ onRemovedField: function( field, $list ){
2016
+ this.renderFields( $list );
2017
+ },
2018
+
2019
+ onReorderField: function( field, $list ){
2020
+ field.updateParent();
2021
+ this.renderFields( $list );
2022
+ },
2023
+
2024
+ onDeleteField: function( field ){
2025
+
2026
+ // delete children
2027
+ field.getFields().map(function( child ){
2028
+ child.delete({ animate: false });
2029
+ });
2030
+ },
2031
+
2032
+ onChangeFieldType: function( field ){
2033
+ // this caused sub fields to disapear if changing type back...
2034
+ //this.onDeleteField( field );
2035
+ },
2036
+
2037
+ onDuplicateField: function( field, newField ){
2038
+
2039
+ // check for children
2040
+ var children = newField.getFields();
2041
+ if( children.length ) {
2042
+
2043
+ // loop
2044
+ children.map(function( child ){
2045
+
2046
+ // wipe field
2047
+ child.wipe();
2048
+
2049
+ // update parent
2050
+ child.updateParent();
2051
+ });
2052
+
2053
+ // action
2054
+ acf.doAction('duplicate_field_objects', children, newField, field);
2055
+ }
2056
+
2057
+ // set menu order
2058
+ this.setFieldMenuOrder( newField );
2059
+ },
2060
+
2061
+ renderFields: function( $list ){
2062
+
2063
+ // vars
2064
+ var fields = acf.getFieldObjects({
2065
+ list: $list
2066
+ });
2067
+
2068
+ // no fields
2069
+ if( !fields.length ) {
2070
+ $list.addClass('-empty');
2071
+ return;
2072
+ }
2073
+
2074
+ // has fields
2075
+ $list.removeClass('-empty');
2076
+
2077
+ // prop
2078
+ fields.map(function( field, i ){
2079
+ field.prop('menu_order', i);
2080
+ });
2081
+ },
2082
+
2083
+ onClickAdd: function( e, $el ){
2084
+ var $list = $el.closest('.acf-tfoot').siblings('.acf-field-list');
2085
+ this.addField( $list );
2086
+ },
2087
+
2088
+ addField: function( $list ){
2089
+
2090
+ // vars
2091
+ var html = $('#tmpl-acf-field').html();
2092
+ var $el = $(html);
2093
+ var prevId = $el.data('id');
2094
+ var newKey = acf.uniqid('field_');
2095
+
2096
+ // duplicate
2097
+ var $newField = acf.duplicate({
2098
+ target: $el,
2099
+ search: prevId,
2100
+ replace: newKey,
2101
+ append: function( $el, $el2 ){
2102
+ $list.append( $el2 );
2103
+ }
2104
+ });
2105
+
2106
+ // get instance
2107
+ var newField = acf.getFieldObject( $newField );
2108
+
2109
+ // props
2110
+ newField.prop('key', newKey);
2111
+ newField.prop('ID', 0);
2112
+ newField.prop('label', '');
2113
+ newField.prop('name', '');
2114
+
2115
+ // attr
2116
+ $newField.attr('data-key', newKey);
2117
+ $newField.attr('data-id', newKey);
2118
+
2119
+ // update parent prop
2120
+ newField.updateParent();
2121
+
2122
+ // focus label
2123
+ var $label = newField.$input('label');
2124
+ setTimeout(function(){
2125
+ $label.trigger('focus');
2126
+ }, 251);
2127
+
2128
+ // open
2129
+ newField.open();
2130
+
2131
+ // set menu order
2132
+ this.renderFields( $list );
2133
+
2134
+ // action
2135
+ acf.doAction('add_field_object', newField);
2136
+ acf.doAction('append_field_object', newField);
2137
+ }
2138
+ });
2139
+
2140
  })(jQuery);
2141
+ (function($, undefined){
2142
+
2143
+ /**
2144
+ * locationManager
2145
+ *
2146
+ * Field group location rules functionality
2147
+ *
2148
+ * @date 15/12/17
2149
+ * @since 5.7.0
2150
+ *
2151
+ * @param void
2152
+ * @return void
2153
+ */
2154
+
2155
+ var locationManager = new acf.Model({
2156
+
2157
+ id: 'locationManager',
2158
+ wait: 'ready',
2159
+
2160
+ events: {
2161
+ 'click .add-location-rule': 'onClickAddRule',
2162
+ 'click .add-location-group': 'onClickAddGroup',
2163
+ 'click .remove-location-rule': 'onClickRemoveRule',
2164
+ 'change .refresh-location-rule': 'onChangeRemoveRule'
2165
+ },
2166
+
2167
+ initialize: function(){
2168
+ this.$el = $('#acf-field-group-locations');
2169
+ },
2170
+
2171
+ onClickAddRule: function( e, $el ){
2172
+ this.addRule( $el.closest('tr') );
2173
+ },
2174
+
2175
+ onClickRemoveRule: function( e, $el ){
2176
+ this.removeRule( $el.closest('tr') );
2177
+ },
2178
+
2179
+ onChangeRemoveRule: function( e, $el ){
2180
+ this.changeRule( $el.closest('tr') );
2181
+ },
2182
+
2183
+ onClickAddGroup: function( e, $el ){
2184
+ this.addGroup();
2185
+ },
2186
+
2187
+ addRule: function( $tr ){
2188
+ acf.duplicate( $tr );
2189
+ },
2190
+
2191
+ removeRule: function( $tr ){
2192
+ if( $tr.siblings('tr').length == 0 ) {
2193
+ $tr.closest('.rule-group').remove();
2194
+ } else {
2195
+ $tr.remove();
2196
+ }
2197
+ },
2198
+
2199
+ changeRule: function( $rule ){
2200
+
2201
+ // vars
2202
+ var $group = $rule.closest('.rule-group');
2203
+ var prefix = $rule.find('td.param select').attr('name').replace('[param]', '');
2204
+
2205
+ // ajaxdata
2206
+ var ajaxdata = {};
2207
+ ajaxdata.action = 'acf/field_group/render_location_rule';
2208
+ ajaxdata.rule = acf.serialize( $rule, prefix );
2209
+ ajaxdata.rule.id = $rule.data('id');
2210
+ ajaxdata.rule.group = $group.data('id');
2211
+
2212
+ // temp disable
2213
+ acf.disable( $rule.find('td.value') );
2214
+
2215
+ // ajax
2216
+ $.ajax({
2217
+ url: acf.get('ajaxurl'),
2218
+ data: acf.prepareForAjax(ajaxdata),
2219
+ type: 'post',
2220
+ dataType: 'html',
2221
+ success: function( html ){
2222
+ if( !html ) return;
2223
+ $rule.replaceWith( html );
2224
+ }
2225
+ });
2226
+ },
2227
+
2228
+ addGroup: function(){
2229
+
2230
+ // vars
2231
+ var $group = this.$('.rule-group:last');
2232
+
2233
+ // duplicate
2234
+ $group2 = acf.duplicate( $group );
2235
+
2236
+ // update h4
2237
+ $group2.find('h4').text( acf.__('or') );
2238
+
2239
+ // remove all tr's except the first one
2240
+ $group2.find('tr').not(':first').remove();
2241
+ }
2242
+ });
2243
+
2244
  })(jQuery);
2245
+ (function($, undefined){
2246
+
2247
+ var _acf = acf.getCompatibility( acf );
2248
+
2249
+ /**
2250
+ * fieldGroupCompatibility
2251
+ *
2252
+ * Compatibility layer for extinct acf.field_group
2253
+ *
2254
+ * @date 15/12/17
2255
+ * @since 5.7.0
2256
+ *
2257
+ * @param void
2258
+ * @return void
2259
+ */
2260
+
2261
+ _acf.field_group = {
2262
+
2263
+ save_field: function( $field, type ){
2264
+ type = (type !== undefined) ? type : 'settings';
2265
+ acf.getFieldObject( $field ).save( type );
2266
+ },
2267
+
2268
+ delete_field: function( $field, animate ){
2269
+ animate = (animate !== undefined) ? animate : true;
2270
+ acf.getFieldObject( $field ).delete({
2271
+ animate: animate
2272
+ });
2273
+ },
2274
+
2275
+ update_field_meta: function( $field, name, value ){
2276
+ acf.getFieldObject( $field ).prop( name, value );
2277
+ },
2278
+
2279
+ delete_field_meta: function( $field, name ){
2280
+ acf.getFieldObject( $field ).prop( name, null );
2281
+ }
2282
+ };
2283
+
2284
+ /**
2285
+ * fieldGroupCompatibility.field_object
2286
+ *
2287
+ * Compatibility layer for extinct acf.field_group.field_object
2288
+ *
2289
+ * @date 15/12/17
2290
+ * @since 5.7.0
2291
+ *
2292
+ * @param void
2293
+ * @return void
2294
+ */
2295
+
2296
+ _acf.field_group.field_object = acf.model.extend({
2297
+
2298
+ // vars
2299
+ type: '',
2300
+ o: {},
2301
+ $field: null,
2302
+ $settings: null,
2303
+
2304
+ tag: function( tag ) {
2305
+
2306
+ // vars
2307
+ var type = this.type;
2308
+
2309
+
2310
+ // explode, add 'field' and implode
2311
+ // - open => open_field
2312
+ // - change_type => change_field_type
2313
+ var tags = tag.split('_');
2314
+ tags.splice(1, 0, 'field');
2315
+ tag = tags.join('_');
2316
+
2317
+
2318
+ // add type
2319
+ if( type ) {
2320
+ tag += '/type=' + type;
2321
+ }
2322
+
2323
+
2324
+ // return
2325
+ return tag;
2326
+
2327
+ },
2328
+
2329
+ selector: function(){
2330
+
2331
+ // vars
2332
+ var selector = '.acf-field-object';
2333
+ var type = this.type;
2334
+
2335
+
2336
+ // add type
2337
+ if( type ) {
2338
+ selector += '-' + type;
2339
+ selector = acf.str_replace('_', '-', selector);
2340
+ }
2341
+
2342
+
2343
+ // return
2344
+ return selector;
2345
+
2346
+ },
2347
+
2348
+ _add_action: function( name, callback ) {
2349
+
2350
+ // vars
2351
+ var model = this;
2352
+
2353
+
2354
+ // add action
2355
+ acf.add_action( this.tag(name), function( $field ){
2356
+
2357
+ // focus
2358
+ model.set('$field', $field);
2359
+
2360
+
2361
+ // callback
2362
+ model[ callback ].apply(model, arguments);
2363
+
2364
+ });
2365
+
2366
+ },
2367
+
2368
+ _add_filter: function( name, callback ) {
2369
+
2370
+ // vars
2371
+ var model = this;
2372
+
2373
+
2374
+ // add action
2375
+ acf.add_filter( this.tag(name), function( $field ){
2376
+
2377
+ // focus
2378
+ model.set('$field', $field);
2379
+
2380
+
2381
+ // callback
2382
+ model[ callback ].apply(model, arguments);
2383
+
2384
+ });
2385
+
2386
+ },
2387
+
2388
+ _add_event: function( name, callback ) {
2389
+
2390
+ // vars
2391
+ var model = this;
2392
+ var event = name.substr(0,name.indexOf(' '));
2393
+ var selector = name.substr(name.indexOf(' ')+1);
2394
+ var context = this.selector();
2395
+
2396
+
2397
+ // add event
2398
+ $(document).on(event, context + ' ' + selector, function( e ){
2399
+
2400
+ // append $el to event object
2401
+ e.$el = $(this);
2402
+ e.$field = e.$el.closest('.acf-field-object');
2403
+
2404
+
2405
+ // focus
2406
+ model.set('$field', e.$field);
2407
+
2408
+
2409
+ // callback
2410
+ model[ callback ].apply(model, [e]);
2411
+
2412
+ });
2413
+
2414
+ },
2415
+
2416
+ _set_$field: function(){
2417
+
2418
+ // vars
2419
+ this.o = this.$field.data();
2420
+
2421
+
2422
+ // els
2423
+ this.$settings = this.$field.find('> .settings > table > tbody');
2424
+
2425
+
2426
+ // focus
2427
+ this.focus();
2428
+
2429
+ },
2430
+
2431
+ focus: function(){
2432
+
2433
+ // do nothing
2434
+
2435
+ },
2436
+
2437
+ setting: function( name ) {
2438
+
2439
+ return this.$settings.find('> .acf-field-setting-' + name);
2440
+
2441
+ }
2442
+
2443
+ });
2444
+
2445
+
2446
+ /*
2447
+ * field
2448
+ *
2449
+ * This model fires actions and filters for registered fields
2450
+ *
2451
+ * @type function
2452
+ * @date 21/02/2014
2453
+ * @since 3.5.1
2454
+ *
2455
+ * @param n/a
2456
+ * @return n/a
2457
+ */
2458
+
2459
+ var actionManager = new acf.Model({
2460
+
2461
+ actions: {
2462
+ 'open_field_object': 'onOpenFieldObject',
2463
+ 'close_field_object': 'onCloseFieldObject',
2464
+ 'add_field_object': 'onAddFieldObject',
2465
+ 'duplicate_field_object': 'onDuplicateFieldObject',
2466
+ 'delete_field_object': 'onDeleteFieldObject',
2467
+ 'change_field_object_type': 'onChangeFieldObjectType',
2468
+ 'change_field_object_label': 'onChangeFieldObjectLabel',
2469
+ 'change_field_object_name': 'onChangeFieldObjectName',
2470
+ 'change_field_object_parent': 'onChangeFieldObjectParent',
2471
+ 'sortstop_field_object': 'onChangeFieldObjectParent'
2472
+ },
2473
+
2474
+ onOpenFieldObject: function( field ){
2475
+ acf.doAction('open_field', field.$el);
2476
+ acf.doAction('open_field/type=' + field.get('type'), field.$el);
2477
+
2478
+ acf.doAction('render_field_settings', field.$el);
2479
+ acf.doAction('render_field_settings/type=' + field.get('type'), field.$el);
2480
+ },
2481
+
2482
+ onCloseFieldObject: function( field ){
2483
+ acf.doAction('close_field', field.$el);
2484
+ acf.doAction('close_field/type=' + field.get('type'), field.$el);
2485
+ },
2486
+
2487
+ onAddFieldObject: function( field ){
2488
+ acf.doAction('add_field', field.$el);
2489
+ acf.doAction('add_field/type=' + field.get('type'), field.$el);
2490
+ },
2491
+
2492
+ onDuplicateFieldObject: function( field ){
2493
+ acf.doAction('duplicate_field', field.$el);
2494
+ acf.doAction('duplicate_field/type=' + field.get('type'), field.$el);
2495
+ },
2496
+
2497
+ onDeleteFieldObject: function( field ){
2498
+ acf.doAction('delete_field', field.$el);
2499
+ acf.doAction('delete_field/type=' + field.get('type'), field.$el);
2500
+ },
2501
+
2502
+ onChangeFieldObjectType: function( field ){
2503
+ acf.doAction('change_field_type', field.$el);
2504
+ acf.doAction('change_field_type/type=' + field.get('type'), field.$el);
2505
+
2506
+ acf.doAction('render_field_settings', field.$el);
2507
+ acf.doAction('render_field_settings/type=' + field.get('type'), field.$el);
2508
+ },
2509
+
2510
+ onChangeFieldObjectLabel: function( field ){
2511
+ acf.doAction('change_field_label', field.$el);
2512
+ acf.doAction('change_field_label/type=' + field.get('type'), field.$el);
2513
+ },
2514
+
2515
+ onChangeFieldObjectName: function( field ){
2516
+ acf.doAction('change_field_name', field.$el);
2517
+ acf.doAction('change_field_name/type=' + field.get('type'), field.$el);
2518
+ },
2519
+
2520
+ onChangeFieldObjectParent: function( field ){
2521
+ acf.doAction('update_field_parent', field.$el);
2522
+ }
2523
+ });
2524
+
2525
  })(jQuery);
assets/build/js/acf-input.js CHANGED
@@ -1,9253 +1,10883 @@
1
- (function ($, undefined) {
2
- // vars
3
- var storage = [];
4
- /**
5
- * acf.Field
6
- *
7
- * description
8
- *
9
- * @date 23/3/18
10
- * @since 5.6.9
11
- *
12
- * @param type $var Description. Default.
13
- * @return type Description.
14
- */
15
-
16
- acf.Field = acf.Model.extend({
17
- // field type
18
- type: '',
19
- // class used to avoid nested event triggers
20
- eventScope: '.acf-field',
21
- // initialize events on 'ready'
22
- wait: 'ready',
23
-
24
- /**
25
- * setup
26
- *
27
- * Called during the constructor function to setup this field ready for initialization
28
- *
29
- * @date 8/5/18
30
- * @since 5.6.9
31
- *
32
- * @param jQuery $field The field element.
33
- * @return void
34
- */
35
- setup: function ($field) {
36
- // set $el
37
- this.$el = $field; // inherit $field data
38
-
39
- this.inherit($field); // inherit controll data
40
-
41
- this.inherit(this.$control());
42
- },
43
-
44
- /**
45
- * val
46
- *
47
- * Sets or returns the field's value
48
- *
49
- * @date 8/5/18
50
- * @since 5.6.9
51
- *
52
- * @param mixed val Optional. The value to set
53
- * @return mixed
54
- */
55
- val: function (val) {
56
- // Set.
57
- if (val !== undefined) {
58
- return this.setValue(val); // Get.
59
- } else {
60
- return this.prop('disabled') ? null : this.getValue();
61
- }
62
- },
63
-
64
- /**
65
- * getValue
66
- *
67
- * returns the field's value
68
- *
69
- * @date 8/5/18
70
- * @since 5.6.9
71
- *
72
- * @param void
73
- * @return mixed
74
- */
75
- getValue: function () {
76
- return this.$input().val();
77
- },
78
-
79
- /**
80
- * setValue
81
- *
82
- * sets the field's value and returns true if changed
83
- *
84
- * @date 8/5/18
85
- * @since 5.6.9
86
- *
87
- * @param mixed val
88
- * @return boolean. True if changed.
89
- */
90
- setValue: function (val) {
91
- return acf.val(this.$input(), val);
92
- },
93
-
94
- /**
95
- * __
96
- *
97
- * i18n helper to be removed
98
- *
99
- * @date 8/5/18
100
- * @since 5.6.9
101
- *
102
- * @param type $var Description. Default.
103
- * @return type Description.
104
- */
105
- __: function (string) {
106
- return acf._e(this.type, string);
107
- },
108
-
109
- /**
110
- * $control
111
- *
112
- * returns the control jQuery element used for inheriting data. Uses this.control setting.
113
- *
114
- * @date 8/5/18
115
- * @since 5.6.9
116
- *
117
- * @param void
118
- * @return jQuery
119
- */
120
- $control: function () {
121
- return false;
122
- },
123
-
124
- /**
125
- * $input
126
- *
127
- * returns the input jQuery element used for saving values. Uses this.input setting.
128
- *
129
- * @date 8/5/18
130
- * @since 5.6.9
131
- *
132
- * @param void
133
- * @return jQuery
134
- */
135
- $input: function () {
136
- return this.$('[name]:first');
137
- },
138
-
139
- /**
140
- * $inputWrap
141
- *
142
- * description
143
- *
144
- * @date 12/5/18
145
- * @since 5.6.9
146
- *
147
- * @param type $var Description. Default.
148
- * @return type Description.
149
- */
150
- $inputWrap: function () {
151
- return this.$('.acf-input:first');
152
- },
153
-
154
- /**
155
- * $inputWrap
156
- *
157
- * description
158
- *
159
- * @date 12/5/18
160
- * @since 5.6.9
161
- *
162
- * @param type $var Description. Default.
163
- * @return type Description.
164
- */
165
- $labelWrap: function () {
166
- return this.$('.acf-label:first');
167
- },
168
-
169
- /**
170
- * getInputName
171
- *
172
- * Returns the field's input name
173
- *
174
- * @date 8/5/18
175
- * @since 5.6.9
176
- *
177
- * @param void
178
- * @return string
179
- */
180
- getInputName: function () {
181
- return this.$input().attr('name') || '';
182
- },
183
-
184
- /**
185
- * parent
186
- *
187
- * returns the field's parent field or false on failure.
188
- *
189
- * @date 8/5/18
190
- * @since 5.6.9
191
- *
192
- * @param void
193
- * @return object|false
194
- */
195
- parent: function () {
196
- // vars
197
- var parents = this.parents(); // return
198
-
199
- return parents.length ? parents[0] : false;
200
- },
201
-
202
- /**
203
- * parents
204
- *
205
- * description
206
- *
207
- * @date 9/7/18
208
- * @since 5.6.9
209
- *
210
- * @param type $var Description. Default.
211
- * @return type Description.
212
- */
213
- parents: function () {
214
- // vars
215
- var $parents = this.$el.parents('.acf-field'); // convert
216
-
217
- var parents = acf.getFields($parents); // return
218
-
219
- return parents;
220
- },
221
- show: function (lockKey, context) {
222
- // show field and store result
223
- var changed = acf.show(this.$el, lockKey); // do action if visibility has changed
224
-
225
- if (changed) {
226
- this.prop('hidden', false);
227
- acf.doAction('show_field', this, context);
228
- } // return
229
-
230
-
231
- return changed;
232
- },
233
- hide: function (lockKey, context) {
234
- // hide field and store result
235
- var changed = acf.hide(this.$el, lockKey); // do action if visibility has changed
236
-
237
- if (changed) {
238
- this.prop('hidden', true);
239
- acf.doAction('hide_field', this, context);
240
- } // return
241
-
242
-
243
- return changed;
244
- },
245
- enable: function (lockKey, context) {
246
- // enable field and store result
247
- var changed = acf.enable(this.$el, lockKey); // do action if disabled has changed
248
-
249
- if (changed) {
250
- this.prop('disabled', false);
251
- acf.doAction('enable_field', this, context);
252
- } // return
253
-
254
-
255
- return changed;
256
- },
257
- disable: function (lockKey, context) {
258
- // disabled field and store result
259
- var changed = acf.disable(this.$el, lockKey); // do action if disabled has changed
260
-
261
- if (changed) {
262
- this.prop('disabled', true);
263
- acf.doAction('disable_field', this, context);
264
- } // return
265
-
266
-
267
- return changed;
268
- },
269
- showEnable: function (lockKey, context) {
270
- // enable
271
- this.enable.apply(this, arguments); // show and return true if changed
272
-
273
- return this.show.apply(this, arguments);
274
- },
275
- hideDisable: function (lockKey, context) {
276
- // disable
277
- this.disable.apply(this, arguments); // hide and return true if changed
278
-
279
- return this.hide.apply(this, arguments);
280
- },
281
- showNotice: function (props) {
282
- // ensure object
283
- if (typeof props !== 'object') {
284
- props = {
285
- text: props
286
- };
287
- } // remove old notice
288
-
289
-
290
- if (this.notice) {
291
- this.notice.remove();
292
- } // create new notice
293
-
294
-
295
- props.target = this.$inputWrap();
296
- this.notice = acf.newNotice(props);
297
- },
298
- removeNotice: function (timeout) {
299
- if (this.notice) {
300
- this.notice.away(timeout || 0);
301
- this.notice = false;
302
- }
303
- },
304
- showError: function (message) {
305
- // add class
306
- this.$el.addClass('acf-error'); // add message
307
-
308
- if (message !== undefined) {
309
- this.showNotice({
310
- text: message,
311
- type: 'error',
312
- dismiss: false
313
- });
314
- } // action
315
-
316
-
317
- acf.doAction('invalid_field', this); // add event
318
-
319
- this.$el.one('focus change', 'input, select, textarea', $.proxy(this.removeError, this));
320
- },
321
- removeError: function () {
322
- // remove class
323
- this.$el.removeClass('acf-error'); // remove notice
324
-
325
- this.removeNotice(250); // action
326
-
327
- acf.doAction('valid_field', this);
328
- },
329
- trigger: function (name, args, bubbles) {
330
- // allow some events to bubble
331
- if (name == 'invalidField') {
332
- bubbles = true;
333
- } // return
334
-
335
-
336
- return acf.Model.prototype.trigger.apply(this, [name, args, bubbles]);
337
- }
338
- });
339
- /**
340
- * newField
341
- *
342
- * description
343
- *
344
- * @date 14/12/17
345
- * @since 5.6.5
346
- *
347
- * @param type $var Description. Default.
348
- * @return type Description.
349
- */
350
-
351
- acf.newField = function ($field) {
352
- // vars
353
- var type = $field.data('type');
354
- var mid = modelId(type);
355
- var model = acf.models[mid] || acf.Field; // instantiate
356
-
357
- var field = new model($field); // actions
358
-
359
- acf.doAction('new_field', field); // return
360
-
361
- return field;
362
- };
363
- /**
364
- * mid
365
- *
366
- * Calculates the model ID for a field type
367
- *
368
- * @date 15/12/17
369
- * @since 5.6.5
370
- *
371
- * @param string type
372
- * @return string
373
- */
374
-
375
-
376
- var modelId = function (type) {
377
- return acf.strPascalCase(type || '') + 'Field';
378
- };
379
- /**
380
- * registerFieldType
381
- *
382
- * description
383
- *
384
- * @date 14/12/17
385
- * @since 5.6.5
386
- *
387
- * @param type $var Description. Default.
388
- * @return type Description.
389
- */
390
-
391
-
392
- acf.registerFieldType = function (model) {
393
- // vars
394
- var proto = model.prototype;
395
- var type = proto.type;
396
- var mid = modelId(type); // store model
397
-
398
- acf.models[mid] = model; // store reference
399
-
400
- storage.push(type);
401
- };
402
- /**
403
- * acf.getFieldType
404
- *
405
- * description
406
- *
407
- * @date 1/2/18
408
- * @since 5.6.5
409
- *
410
- * @param type $var Description. Default.
411
- * @return type Description.
412
- */
413
-
414
-
415
- acf.getFieldType = function (type) {
416
- var mid = modelId(type);
417
- return acf.models[mid] || false;
418
- };
419
- /**
420
- * acf.getFieldTypes
421
- *
422
- * description
423
- *
424
- * @date 1/2/18
425
- * @since 5.6.5
426
- *
427
- * @param type $var Description. Default.
428
- * @return type Description.
429
- */
430
-
431
-
432
- acf.getFieldTypes = function (args) {
433
- // defaults
434
- args = acf.parseArgs(args, {
435
- category: '' // hasValue: true
436
-
437
- }); // clonse available types
438
-
439
- var types = []; // loop
440
-
441
- storage.map(function (type) {
442
- // vars
443
- var model = acf.getFieldType(type);
444
- var proto = model.prototype; // check operator
445
-
446
- if (args.category && proto.category !== args.category) {
447
- return;
448
- } // append
449
-
450
-
451
- types.push(model);
452
- }); // return
453
-
454
- return types;
455
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  })(jQuery);
457
-
458
- (function ($, undefined) {
459
- /**
460
- * findFields
461
- *
462
- * Returns a jQuery selection object of acf fields.
463
- *
464
- * @date 14/12/17
465
- * @since 5.6.5
466
- *
467
- * @param object $args {
468
- * Optional. Arguments to find fields.
469
- *
470
- * @type string key The field's key (data-attribute).
471
- * @type string name The field's name (data-attribute).
472
- * @type string type The field's type (data-attribute).
473
- * @type string is jQuery selector to compare against.
474
- * @type jQuery parent jQuery element to search within.
475
- * @type jQuery sibling jQuery element to search alongside.
476
- * @type limit int The number of fields to find.
477
- * @type suppressFilters bool Whether to allow filters to add/remove results. Default behaviour will ignore clone fields.
478
- * }
479
- * @return jQuery
480
- */
481
- acf.findFields = function (args) {
482
- // vars
483
- var selector = '.acf-field';
484
- var $fields = false; // args
485
-
486
- args = acf.parseArgs(args, {
487
- key: '',
488
- name: '',
489
- type: '',
490
- is: '',
491
- parent: false,
492
- sibling: false,
493
- limit: false,
494
- visible: false,
495
- suppressFilters: false
496
- }); // filter args
497
-
498
- if (!args.suppressFilters) {
499
- args = acf.applyFilters('find_fields_args', args);
500
- } // key
501
-
502
-
503
- if (args.key) {
504
- selector += '[data-key="' + args.key + '"]';
505
- } // type
506
-
507
-
508
- if (args.type) {
509
- selector += '[data-type="' + args.type + '"]';
510
- } // name
511
-
512
-
513
- if (args.name) {
514
- selector += '[data-name="' + args.name + '"]';
515
- } // is
516
-
517
-
518
- if (args.is) {
519
- selector += args.is;
520
- } // visibility
521
-
522
-
523
- if (args.visible) {
524
- selector += ':visible';
525
- } // query
526
-
527
-
528
- if (args.parent) {
529
- $fields = args.parent.find(selector);
530
- } else if (args.sibling) {
531
- $fields = args.sibling.siblings(selector);
532
- } else {
533
- $fields = $(selector);
534
- } // filter
535
-
536
-
537
- if (!args.suppressFilters) {
538
- $fields = $fields.not('.acf-clone .acf-field');
539
- $fields = acf.applyFilters('find_fields', $fields);
540
- } // limit
541
-
542
-
543
- if (args.limit) {
544
- $fields = $fields.slice(0, args.limit);
545
- } // return
546
-
547
-
548
- return $fields;
549
- };
550
- /**
551
- * findField
552
- *
553
- * Finds a specific field with jQuery
554
- *
555
- * @date 14/12/17
556
- * @since 5.6.5
557
- *
558
- * @param string key The field's key.
559
- * @param jQuery $parent jQuery element to search within.
560
- * @return jQuery
561
- */
562
-
563
-
564
- acf.findField = function (key, $parent) {
565
- return acf.findFields({
566
- key: key,
567
- limit: 1,
568
- parent: $parent,
569
- suppressFilters: true
570
- });
571
- };
572
- /**
573
- * getField
574
- *
575
- * Returns a field instance
576
- *
577
- * @date 14/12/17
578
- * @since 5.6.5
579
- *
580
- * @param jQuery|string $field jQuery element or field key.
581
- * @return object
582
- */
583
-
584
-
585
- acf.getField = function ($field) {
586
- // allow jQuery
587
- if ($field instanceof jQuery) {// find fields
588
- } else {
589
- $field = acf.findField($field);
590
- } // instantiate
591
-
592
-
593
- var field = $field.data('acf');
594
-
595
- if (!field) {
596
- field = acf.newField($field);
597
- } // return
598
-
599
-
600
- return field;
601
- };
602
- /**
603
- * getFields
604
- *
605
- * Returns multiple field instances
606
- *
607
- * @date 14/12/17
608
- * @since 5.6.5
609
- *
610
- * @param jQuery|object $fields jQuery elements or query args.
611
- * @return array
612
- */
613
-
614
-
615
- acf.getFields = function ($fields) {
616
- // allow jQuery
617
- if ($fields instanceof jQuery) {// find fields
618
- } else {
619
- $fields = acf.findFields($fields);
620
- } // loop
621
-
622
-
623
- var fields = [];
624
- $fields.each(function () {
625
- var field = acf.getField($(this));
626
- fields.push(field);
627
- }); // return
628
-
629
- return fields;
630
- };
631
- /**
632
- * findClosestField
633
- *
634
- * Returns the closest jQuery field element
635
- *
636
- * @date 9/4/18
637
- * @since 5.6.9
638
- *
639
- * @param jQuery $el
640
- * @return jQuery
641
- */
642
-
643
-
644
- acf.findClosestField = function ($el) {
645
- return $el.closest('.acf-field');
646
- };
647
- /**
648
- * getClosestField
649
- *
650
- * Returns the closest field instance
651
- *
652
- * @date 22/1/18
653
- * @since 5.6.5
654
- *
655
- * @param jQuery $el
656
- * @return object
657
- */
658
-
659
-
660
- acf.getClosestField = function ($el) {
661
- var $field = acf.findClosestField($el);
662
- return this.getField($field);
663
- };
664
- /**
665
- * addGlobalFieldAction
666
- *
667
- * Sets up callback logic for global field actions
668
- *
669
- * @date 15/6/18
670
- * @since 5.6.9
671
- *
672
- * @param string action
673
- * @return void
674
- */
675
-
676
-
677
- var addGlobalFieldAction = function (action) {
678
- // vars
679
- var globalAction = action;
680
- var pluralAction = action + '_fields'; // ready_fields
681
-
682
- var singleAction = action + '_field'; // ready_field
683
- // global action
684
-
685
- var globalCallback = function ($el
686
- /*, arg1, arg2, etc*/
687
- ) {
688
- //console.log( action, arguments );
689
- // get args [$el, ...]
690
- var args = acf.arrayArgs(arguments);
691
- var extraArgs = args.slice(1); // find fields
692
-
693
- var fields = acf.getFields({
694
- parent: $el
695
- }); // check
696
-
697
- if (fields.length) {
698
- // pluralAction
699
- var pluralArgs = [pluralAction, fields].concat(extraArgs);
700
- acf.doAction.apply(null, pluralArgs);
701
- }
702
- }; // plural action
703
-
704
-
705
- var pluralCallback = function (fields
706
- /*, arg1, arg2, etc*/
707
- ) {
708
- //console.log( pluralAction, arguments );
709
- // get args [fields, ...]
710
- var args = acf.arrayArgs(arguments);
711
- var extraArgs = args.slice(1); // loop
712
-
713
- fields.map(function (field, i) {
714
- //setTimeout(function(){
715
- // singleAction
716
- var singleArgs = [singleAction, field].concat(extraArgs);
717
- acf.doAction.apply(null, singleArgs); //}, i * 100);
718
- });
719
- }; // add actions
720
-
721
-
722
- acf.addAction(globalAction, globalCallback);
723
- acf.addAction(pluralAction, pluralCallback); // also add single action
724
-
725
- addSingleFieldAction(action);
726
- };
727
- /**
728
- * addSingleFieldAction
729
- *
730
- * Sets up callback logic for single field actions
731
- *
732
- * @date 15/6/18
733
- * @since 5.6.9
734
- *
735
- * @param string action
736
- * @return void
737
- */
738
-
739
-
740
- var addSingleFieldAction = function (action) {
741
- // vars
742
- var singleAction = action + '_field'; // ready_field
743
-
744
- var singleEvent = action + 'Field'; // readyField
745
- // single action
746
-
747
- var singleCallback = function (field
748
- /*, arg1, arg2, etc*/
749
- ) {
750
- //console.log( singleAction, arguments );
751
- // get args [field, ...]
752
- var args = acf.arrayArgs(arguments);
753
- var extraArgs = args.slice(1); // action variations (ready_field/type=image)
754
-
755
- var variations = ['type', 'name', 'key'];
756
- variations.map(function (variation) {
757
- // vars
758
- var prefix = '/' + variation + '=' + field.get(variation); // singleAction
759
-
760
- args = [singleAction + prefix, field].concat(extraArgs);
761
- acf.doAction.apply(null, args);
762
- }); // event
763
-
764
- if (singleFieldEvents.indexOf(action) > -1) {
765
- field.trigger(singleEvent, extraArgs);
766
- }
767
- }; // add actions
768
-
769
-
770
- acf.addAction(singleAction, singleCallback);
771
- }; // vars
772
-
773
-
774
- var globalFieldActions = ['prepare', 'ready', 'load', 'append', 'remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload'];
775
- var singleFieldActions = ['valid', 'invalid', 'enable', 'disable', 'new', 'duplicate'];
776
- var singleFieldEvents = ['remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload', 'valid', 'invalid', 'enable', 'disable', 'duplicate']; // add
777
-
778
- globalFieldActions.map(addGlobalFieldAction);
779
- singleFieldActions.map(addSingleFieldAction);
780
- /**
781
- * fieldsEventManager
782
- *
783
- * Manages field actions and events
784
- *
785
- * @date 15/12/17
786
- * @since 5.6.5
787
- *
788
- * @param void
789
- * @param void
790
- */
791
-
792
- var fieldsEventManager = new acf.Model({
793
- id: 'fieldsEventManager',
794
- events: {
795
- 'click .acf-field a[href="#"]': 'onClick',
796
- 'change .acf-field': 'onChange'
797
- },
798
- onClick: function (e) {
799
- // prevent default of any link with an href of #
800
- e.preventDefault();
801
- },
802
- onChange: function () {
803
- // preview hack allows post to save with no title or content
804
- $('#_acf_changed').val(1);
805
- }
806
- });
807
- var duplicateFieldsManager = new acf.Model({
808
- id: 'duplicateFieldsManager',
809
- actions: {
810
- 'duplicate': 'onDuplicate',
811
- 'duplicate_fields': 'onDuplicateFields'
812
- },
813
- onDuplicate: function ($el, $el2) {
814
- var fields = acf.getFields({
815
- parent: $el
816
- });
817
-
818
- if (fields.length) {
819
- var $fields = acf.findFields({
820
- parent: $el2
821
- });
822
- acf.doAction('duplicate_fields', fields, $fields);
823
- }
824
- },
825
- onDuplicateFields: function (fields, duplicates) {
826
- fields.map(function (field, i) {
827
- acf.doAction('duplicate_field', field, $(duplicates[i]));
828
- });
829
- }
830
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
831
  })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832
 
833
- (function ($, undefined) {
834
- var i = 0;
835
- var Field = acf.Field.extend({
836
- type: 'accordion',
837
- wait: '',
838
- $control: function () {
839
- return this.$('.acf-fields:first');
840
- },
841
- initialize: function () {
842
- // Bail early if this is a duplicate of an existing initialized accordion.
843
- if (this.$el.hasClass('acf-accordion')) {
844
- return;
845
- } // bail early if is cell
846
-
847
-
848
- if (this.$el.is('td')) return; // enpoint
849
-
850
- if (this.get('endpoint')) {
851
- return this.remove();
852
- } // vars
853
-
854
-
855
- var $field = this.$el;
856
- var $label = this.$labelWrap();
857
- var $input = this.$inputWrap();
858
- var $wrap = this.$control();
859
- var $instructions = $input.children('.description'); // force description into label
860
-
861
- if ($instructions.length) {
862
- $label.append($instructions);
863
- } // table
864
-
865
-
866
- if (this.$el.is('tr')) {
867
- // vars
868
- var $table = this.$el.closest('table');
869
- var $newLabel = $('<div class="acf-accordion-title"/>');
870
- var $newInput = $('<div class="acf-accordion-content"/>');
871
- var $newTable = $('<table class="' + $table.attr('class') + '"/>');
872
- var $newWrap = $('<tbody/>'); // dom
873
-
874
- $newLabel.append($label.html());
875
- $newTable.append($newWrap);
876
- $newInput.append($newTable);
877
- $input.append($newLabel);
878
- $input.append($newInput); // modify
879
-
880
- $label.remove();
881
- $wrap.remove();
882
- $input.attr('colspan', 2); // update vars
883
-
884
- $label = $newLabel;
885
- $input = $newInput;
886
- $wrap = $newWrap;
887
- } // add classes
888
-
889
-
890
- $field.addClass('acf-accordion');
891
- $label.addClass('acf-accordion-title');
892
- $input.addClass('acf-accordion-content'); // index
893
-
894
- i++; // multi-expand
895
-
896
- if (this.get('multi_expand')) {
897
- $field.attr('multi-expand', 1);
898
- } // open
899
-
900
-
901
- var order = acf.getPreference('this.accordions') || [];
902
-
903
- if (order[i - 1] !== undefined) {
904
- this.set('open', order[i - 1]);
905
- }
906
-
907
- if (this.get('open')) {
908
- $field.addClass('-open');
909
- $input.css('display', 'block'); // needed for accordion to close smoothly
910
- } // add icon
911
-
912
-
913
- $label.prepend(accordionManager.iconHtml({
914
- open: this.get('open')
915
- })); // classes
916
- // - remove 'inside' which is a #poststuff WP class
917
-
918
- var $parent = $field.parent();
919
- $wrap.addClass($parent.hasClass('-left') ? '-left' : '');
920
- $wrap.addClass($parent.hasClass('-clear') ? '-clear' : ''); // append
921
-
922
- $wrap.append($field.nextUntil('.acf-field-accordion', '.acf-field')); // clean up
923
-
924
- $wrap.removeAttr('data-open data-multi_expand data-endpoint');
925
- }
926
- });
927
- acf.registerFieldType(Field);
928
- /**
929
- * accordionManager
930
- *
931
- * Events manager for the acf accordion
932
- *
933
- * @date 14/2/18
934
- * @since 5.6.9
935
- *
936
- * @param void
937
- * @return void
938
- */
939
-
940
- var accordionManager = new acf.Model({
941
- actions: {
942
- 'unload': 'onUnload'
943
- },
944
- events: {
945
- 'click .acf-accordion-title': 'onClick',
946
- 'invalidField .acf-accordion': 'onInvalidField'
947
- },
948
- isOpen: function ($el) {
949
- return $el.hasClass('-open');
950
- },
951
- toggle: function ($el) {
952
- if (this.isOpen($el)) {
953
- this.close($el);
954
- } else {
955
- this.open($el);
956
- }
957
- },
958
- iconHtml: function (props) {
959
- // Use SVG inside Gutenberg editor.
960
- if (acf.isGutenberg()) {
961
- if (props.open) {
962
- return '<svg class="acf-accordion-icon" width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img" aria-hidden="true" focusable="false"><g><path fill="none" d="M0,0h24v24H0V0z"></path></g><g><path d="M12,8l-6,6l1.41,1.41L12,10.83l4.59,4.58L18,14L12,8z"></path></g></svg>';
963
- } else {
964
- return '<svg class="acf-accordion-icon" width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img" aria-hidden="true" focusable="false"><g><path fill="none" d="M0,0h24v24H0V0z"></path></g><g><path d="M7.41,8.59L12,13.17l4.59-4.58L18,10l-6,6l-6-6L7.41,8.59z"></path></g></svg>';
965
- }
966
- } else {
967
- if (props.open) {
968
- return '<i class="acf-accordion-icon dashicons dashicons-arrow-down"></i>';
969
- } else {
970
- return '<i class="acf-accordion-icon dashicons dashicons-arrow-right"></i>';
971
- }
972
- }
973
- },
974
- open: function ($el) {
975
- var duration = acf.isGutenberg() ? 0 : 300; // open
976
-
977
- $el.find('.acf-accordion-content:first').slideDown(duration).css('display', 'block');
978
- $el.find('.acf-accordion-icon:first').replaceWith(this.iconHtml({
979
- open: true
980
- }));
981
- $el.addClass('-open'); // action
982
-
983
- acf.doAction('show', $el); // close siblings
984
-
985
- if (!$el.attr('multi-expand')) {
986
- $el.siblings('.acf-accordion.-open').each(function () {
987
- accordionManager.close($(this));
988
- });
989
- }
990
- },
991
- close: function ($el) {
992
- var duration = acf.isGutenberg() ? 0 : 300; // close
993
-
994
- $el.find('.acf-accordion-content:first').slideUp(duration);
995
- $el.find('.acf-accordion-icon:first').replaceWith(this.iconHtml({
996
- open: false
997
- }));
998
- $el.removeClass('-open'); // action
999
-
1000
- acf.doAction('hide', $el);
1001
- },
1002
- onClick: function (e, $el) {
1003
- // prevent Defailt
1004
- e.preventDefault(); // open close
1005
-
1006
- this.toggle($el.parent());
1007
- },
1008
- onInvalidField: function (e, $el) {
1009
- // bail early if already focused
1010
- if (this.busy) {
1011
- return;
1012
- } // disable functionality for 1sec (allow next validation to work)
1013
-
1014
-
1015
- this.busy = true;
1016
- this.setTimeout(function () {
1017
- this.busy = false;
1018
- }, 1000); // open accordion
1019
-
1020
- this.open($el);
1021
- },
1022
- onUnload: function (e) {
1023
- // vars
1024
- var order = []; // loop
1025
-
1026
- $('.acf-accordion').each(function () {
1027
- var open = $(this).hasClass('-open') ? 1 : 0;
1028
- order.push(open);
1029
- }); // set
1030
-
1031
- if (order.length) {
1032
- acf.setPreference('this.accordions', order);
1033
- }
1034
- }
1035
- });
1036
  })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
 
1038
- (function ($, undefined) {
1039
- var Field = acf.Field.extend({
1040
- type: 'button_group',
1041
- events: {
1042
- 'click input[type="radio"]': 'onClick'
1043
- },
1044
- $control: function () {
1045
- return this.$('.acf-button-group');
1046
- },
1047
- $input: function () {
1048
- return this.$('input:checked');
1049
- },
1050
- setValue: function (val) {
1051
- this.$('input[value="' + val + '"]').prop('checked', true).trigger('change');
1052
- },
1053
- onClick: function (e, $el) {
1054
- // vars
1055
- var $label = $el.parent('label');
1056
- var selected = $label.hasClass('selected'); // remove previous selected
1057
-
1058
- this.$('.selected').removeClass('selected'); // add active class
1059
-
1060
- $label.addClass('selected'); // allow null
1061
-
1062
- if (this.get('allow_null') && selected) {
1063
- $label.removeClass('selected');
1064
- $el.prop('checked', false).trigger('change');
1065
- }
1066
- }
1067
- });
1068
- acf.registerFieldType(Field);
1069
  })(jQuery);
1070
-
1071
- (function ($, undefined) {
1072
- var Field = acf.Field.extend({
1073
- type: 'checkbox',
1074
- events: {
1075
- 'change input': 'onChange',
1076
- 'click .acf-add-checkbox': 'onClickAdd',
1077
- 'click .acf-checkbox-toggle': 'onClickToggle',
1078
- 'click .acf-checkbox-custom': 'onClickCustom'
1079
- },
1080
- $control: function () {
1081
- return this.$('.acf-checkbox-list');
1082
- },
1083
- $toggle: function () {
1084
- return this.$('.acf-checkbox-toggle');
1085
- },
1086
- $input: function () {
1087
- return this.$('input[type="hidden"]');
1088
- },
1089
- $inputs: function () {
1090
- return this.$('input[type="checkbox"]').not('.acf-checkbox-toggle');
1091
- },
1092
- getValue: function () {
1093
- var val = [];
1094
- this.$(':checked').each(function () {
1095
- val.push($(this).val());
1096
- });
1097
- return val.length ? val : false;
1098
- },
1099
- onChange: function (e, $el) {
1100
- // Vars.
1101
- var checked = $el.prop('checked');
1102
- var $label = $el.parent('label');
1103
- var $toggle = this.$toggle(); // Add or remove "selected" class.
1104
-
1105
- if (checked) {
1106
- $label.addClass('selected');
1107
- } else {
1108
- $label.removeClass('selected');
1109
- } // Update toggle state if all inputs are checked.
1110
-
1111
-
1112
- if ($toggle.length) {
1113
- var $inputs = this.$inputs(); // all checked
1114
-
1115
- if ($inputs.not(':checked').length == 0) {
1116
- $toggle.prop('checked', true);
1117
- } else {
1118
- $toggle.prop('checked', false);
1119
- }
1120
- }
1121
- },
1122
- onClickAdd: function (e, $el) {
1123
- var html = '<li><input class="acf-checkbox-custom" type="checkbox" checked="checked" /><input type="text" name="' + this.getInputName() + '[]" /></li>';
1124
- $el.parent('li').before(html);
1125
- },
1126
- onClickToggle: function (e, $el) {
1127
- // Vars.
1128
- var checked = $el.prop('checked');
1129
- var $inputs = this.$('input[type="checkbox"]');
1130
- var $labels = this.$('label'); // Update "checked" state.
1131
-
1132
- $inputs.prop('checked', checked); // Add or remove "selected" class.
1133
-
1134
- if (checked) {
1135
- $labels.addClass('selected');
1136
- } else {
1137
- $labels.removeClass('selected');
1138
- }
1139
- },
1140
- onClickCustom: function (e, $el) {
1141
- var checked = $el.prop('checked');
1142
- var $text = $el.next('input[type="text"]'); // checked
1143
-
1144
- if (checked) {
1145
- $text.prop('disabled', false); // not checked
1146
- } else {
1147
- $text.prop('disabled', true); // remove
1148
-
1149
- if ($text.val() == '') {
1150
- $el.parent('li').remove();
1151
- }
1152
- }
1153
- }
1154
- });
1155
- acf.registerFieldType(Field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1156
  })(jQuery);
1157
-
1158
- (function ($, undefined) {
1159
- var Field = acf.Field.extend({
1160
- type: 'color_picker',
1161
- wait: 'load',
1162
- events: {
1163
- 'duplicateField': 'onDuplicate'
1164
- },
1165
- $control: function () {
1166
- return this.$('.acf-color-picker');
1167
- },
1168
- $input: function () {
1169
- return this.$('input[type="hidden"]');
1170
- },
1171
- $inputText: function () {
1172
- return this.$('input[type="text"]');
1173
- },
1174
- setValue: function (val) {
1175
- // update input (with change)
1176
- acf.val(this.$input(), val); // update iris
1177
-
1178
- this.$inputText().iris('color', val);
1179
- },
1180
- initialize: function () {
1181
- // vars
1182
- var $input = this.$input();
1183
- var $inputText = this.$inputText(); // event
1184
-
1185
- var onChange = function (e) {
1186
- // timeout is required to ensure the $input val is correct
1187
- setTimeout(function () {
1188
- acf.val($input, $inputText.val());
1189
- }, 1);
1190
- }; // args
1191
-
1192
-
1193
- var args = {
1194
- defaultColor: false,
1195
- palettes: true,
1196
- hide: true,
1197
- change: onChange,
1198
- clear: onChange
1199
- }; // filter
1200
-
1201
- var args = acf.applyFilters('color_picker_args', args, this); // initialize
1202
-
1203
- $inputText.wpColorPicker(args);
1204
- },
1205
- onDuplicate: function (e, $el, $duplicate) {
1206
- // The wpColorPicker library does not provide a destroy method.
1207
- // Manually reset DOM by replacing elements back to their original state.
1208
- $colorPicker = $duplicate.find('.wp-picker-container');
1209
- $inputText = $duplicate.find('input[type="text"]');
1210
- $colorPicker.replaceWith($inputText);
1211
- }
1212
- });
1213
- acf.registerFieldType(Field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1214
  })(jQuery);
1215
-
1216
- (function ($, undefined) {
1217
- var Field = acf.Field.extend({
1218
- type: 'date_picker',
1219
- events: {
1220
- 'blur input[type="text"]': 'onBlur',
1221
- 'duplicateField': 'onDuplicate'
1222
- },
1223
- $control: function () {
1224
- return this.$('.acf-date-picker');
1225
- },
1226
- $input: function () {
1227
- return this.$('input[type="hidden"]');
1228
- },
1229
- $inputText: function () {
1230
- return this.$('input[type="text"]');
1231
- },
1232
- initialize: function () {
1233
- // save_format: compatibility with ACF < 5.0.0
1234
- if (this.has('save_format')) {
1235
- return this.initializeCompatibility();
1236
- } // vars
1237
-
1238
-
1239
- var $input = this.$input();
1240
- var $inputText = this.$inputText(); // args
1241
-
1242
- var args = {
1243
- dateFormat: this.get('date_format'),
1244
- altField: $input,
1245
- altFormat: 'yymmdd',
1246
- changeYear: true,
1247
- yearRange: "-100:+100",
1248
- changeMonth: true,
1249
- showButtonPanel: true,
1250
- firstDay: this.get('first_day')
1251
- }; // filter
1252
-
1253
- args = acf.applyFilters('date_picker_args', args, this); // add date picker
1254
-
1255
- acf.newDatePicker($inputText, args); // action
1256
-
1257
- acf.doAction('date_picker_init', $inputText, args, this);
1258
- },
1259
- initializeCompatibility: function () {
1260
- // vars
1261
- var $input = this.$input();
1262
- var $inputText = this.$inputText(); // get and set value from alt field
1263
-
1264
- $inputText.val($input.val()); // args
1265
-
1266
- var args = {
1267
- dateFormat: this.get('date_format'),
1268
- altField: $input,
1269
- altFormat: this.get('save_format'),
1270
- changeYear: true,
1271
- yearRange: "-100:+100",
1272
- changeMonth: true,
1273
- showButtonPanel: true,
1274
- firstDay: this.get('first_day')
1275
- }; // filter for 3rd party customization
1276
-
1277
- args = acf.applyFilters('date_picker_args', args, this); // backup
1278
-
1279
- var dateFormat = args.dateFormat; // change args.dateFormat
1280
-
1281
- args.dateFormat = this.get('save_format'); // add date picker
1282
-
1283
- acf.newDatePicker($inputText, args); // now change the format back to how it should be.
1284
-
1285
- $inputText.datepicker('option', 'dateFormat', dateFormat); // action for 3rd party customization
1286
-
1287
- acf.doAction('date_picker_init', $inputText, args, this);
1288
- },
1289
- onBlur: function () {
1290
- if (!this.$inputText().val()) {
1291
- acf.val(this.$input(), '');
1292
- }
1293
- },
1294
- onDuplicate: function (e, $el, $duplicate) {
1295
- $duplicate.find('input[type="text"]').removeClass('hasDatepicker').removeAttr('id');
1296
- }
1297
- });
1298
- acf.registerFieldType(Field); // manager
1299
-
1300
- var datePickerManager = new acf.Model({
1301
- priority: 5,
1302
- wait: 'ready',
1303
- initialize: function () {
1304
- // vars
1305
- var locale = acf.get('locale');
1306
- var rtl = acf.get('rtl');
1307
- var l10n = acf.get('datePickerL10n'); // bail ealry if no l10n
1308
-
1309
- if (!l10n) {
1310
- return false;
1311
- } // bail ealry if no datepicker library
1312
-
1313
-
1314
- if (typeof $.datepicker === 'undefined') {
1315
- return false;
1316
- } // rtl
1317
-
1318
-
1319
- l10n.isRTL = rtl; // append
1320
-
1321
- $.datepicker.regional[locale] = l10n;
1322
- $.datepicker.setDefaults(l10n);
1323
- }
1324
- }); // add
1325
-
1326
- acf.newDatePicker = function ($input, args) {
1327
- // bail ealry if no datepicker library
1328
- if (typeof $.datepicker === 'undefined') {
1329
- return false;
1330
- } // defaults
1331
-
1332
-
1333
- args = args || {}; // initialize
1334
-
1335
- $input.datepicker(args); // wrap the datepicker (only if it hasn't already been wrapped)
1336
-
1337
- if ($('body > #ui-datepicker-div').exists()) {
1338
- $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
1339
- }
1340
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1341
  })(jQuery);
1342
-
1343
- (function ($, undefined) {
1344
- var Field = acf.models.DatePickerField.extend({
1345
- type: 'date_time_picker',
1346
- $control: function () {
1347
- return this.$('.acf-date-time-picker');
1348
- },
1349
- initialize: function () {
1350
- // vars
1351
- var $input = this.$input();
1352
- var $inputText = this.$inputText(); // args
1353
-
1354
- var args = {
1355
- dateFormat: this.get('date_format'),
1356
- timeFormat: this.get('time_format'),
1357
- altField: $input,
1358
- altFieldTimeOnly: false,
1359
- altFormat: 'yy-mm-dd',
1360
- altTimeFormat: 'HH:mm:ss',
1361
- changeYear: true,
1362
- yearRange: "-100:+100",
1363
- changeMonth: true,
1364
- showButtonPanel: true,
1365
- firstDay: this.get('first_day'),
1366
- controlType: 'select',
1367
- oneLine: true
1368
- }; // filter
1369
-
1370
- args = acf.applyFilters('date_time_picker_args', args, this); // add date time picker
1371
-
1372
- acf.newDateTimePicker($inputText, args); // action
1373
-
1374
- acf.doAction('date_time_picker_init', $inputText, args, this);
1375
- }
1376
- });
1377
- acf.registerFieldType(Field); // manager
1378
-
1379
- var dateTimePickerManager = new acf.Model({
1380
- priority: 5,
1381
- wait: 'ready',
1382
- initialize: function () {
1383
- // vars
1384
- var locale = acf.get('locale');
1385
- var rtl = acf.get('rtl');
1386
- var l10n = acf.get('dateTimePickerL10n'); // bail ealry if no l10n
1387
-
1388
- if (!l10n) {
1389
- return false;
1390
- } // bail ealry if no datepicker library
1391
-
1392
-
1393
- if (typeof $.timepicker === 'undefined') {
1394
- return false;
1395
- } // rtl
1396
-
1397
-
1398
- l10n.isRTL = rtl; // append
1399
-
1400
- $.timepicker.regional[locale] = l10n;
1401
- $.timepicker.setDefaults(l10n);
1402
- }
1403
- }); // add
1404
-
1405
- acf.newDateTimePicker = function ($input, args) {
1406
- // bail ealry if no datepicker library
1407
- if (typeof $.timepicker === 'undefined') {
1408
- return false;
1409
- } // defaults
1410
-
1411
-
1412
- args = args || {}; // initialize
1413
-
1414
- $input.datetimepicker(args); // wrap the datepicker (only if it hasn't already been wrapped)
1415
-
1416
- if ($('body > #ui-datepicker-div').exists()) {
1417
- $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
1418
- }
1419
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1420
  })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1421
 
1422
- (function ($, undefined) {
1423
- var Field = acf.Field.extend({
1424
- type: 'google_map',
1425
- map: false,
1426
- wait: 'load',
1427
- events: {
1428
- 'click a[data-name="clear"]': 'onClickClear',
1429
- 'click a[data-name="locate"]': 'onClickLocate',
1430
- 'click a[data-name="search"]': 'onClickSearch',
1431
- 'keydown .search': 'onKeydownSearch',
1432
- 'keyup .search': 'onKeyupSearch',
1433
- 'focus .search': 'onFocusSearch',
1434
- 'blur .search': 'onBlurSearch',
1435
- 'showField': 'onShow'
1436
- },
1437
- $control: function () {
1438
- return this.$('.acf-google-map');
1439
- },
1440
- $search: function () {
1441
- return this.$('.search');
1442
- },
1443
- $canvas: function () {
1444
- return this.$('.canvas');
1445
- },
1446
- setState: function (state) {
1447
- // Remove previous state classes.
1448
- this.$control().removeClass('-value -loading -searching'); // Determine auto state based of current value.
1449
-
1450
- if (state === 'default') {
1451
- state = this.val() ? 'value' : '';
1452
- } // Update state class.
1453
-
1454
-
1455
- if (state) {
1456
- this.$control().addClass('-' + state);
1457
- }
1458
- },
1459
- getValue: function () {
1460
- var val = this.$input().val();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1461
 
1462
- if (val) {
1463
- return JSON.parse(val);
1464
- } else {
1465
- return false;
1466
- }
1467
- },
1468
- setValue: function (val, silent) {
1469
- // Convert input value.
1470
- var valAttr = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1471
 
1472
- if (val) {
1473
- valAttr = JSON.stringify(val);
1474
- } // Update input (with change).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1476
 
1477
- acf.val(this.$input(), valAttr); // Bail early if silent update.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1478
 
1479
- if (silent) {
1480
- return;
1481
- } // Render.
1482
-
1483
-
1484
- this.renderVal(val);
1485
- /**
1486
- * Fires immediately after the value has changed.
1487
- *
1488
- * @date 12/02/2014
1489
- * @since 5.0.0
1490
- *
1491
- * @param object|string val The new value.
1492
- * @param object map The Google Map isntance.
1493
- * @param object field The field instance.
1494
- */
1495
-
1496
- acf.doAction('google_map_change', val, this.map, this);
1497
- },
1498
- renderVal: function (val) {
1499
- // Value.
1500
- if (val) {
1501
- this.setState('value');
1502
- this.$search().val(val.address);
1503
- this.setPosition(val.lat, val.lng); // No value.
1504
- } else {
1505
- this.setState('');
1506
- this.$search().val('');
1507
- this.map.marker.setVisible(false);
1508
- }
1509
- },
1510
- newLatLng: function (lat, lng) {
1511
- return new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
1512
- },
1513
- setPosition: function (lat, lng) {
1514
- // Update marker position.
1515
- this.map.marker.setPosition({
1516
- lat: parseFloat(lat),
1517
- lng: parseFloat(lng)
1518
- }); // Show marker.
1519
-
1520
- this.map.marker.setVisible(true); // Center map.
1521
-
1522
- this.center();
1523
- },
1524
- center: function () {
1525
- // Find marker position.
1526
- var position = this.map.marker.getPosition();
1527
-
1528
- if (position) {
1529
- var lat = position.lat();
1530
- var lng = position.lng(); // Or find default settings.
1531
- } else {
1532
- var lat = this.get('lat');
1533
- var lng = this.get('lng');
1534
- } // Center map.
1535
-
1536
-
1537
- this.map.setCenter({
1538
- lat: parseFloat(lat),
1539
- lng: parseFloat(lng)
1540
- });
1541
- },
1542
- initialize: function () {
1543
- // Ensure Google API is loaded and then initialize map.
1544
- withAPI(this.initializeMap.bind(this));
1545
- },
1546
- initializeMap: function () {
1547
- // Get value ignoring conditional logic status.
1548
- var val = this.getValue(); // Construct default args.
1549
-
1550
- var args = acf.parseArgs(val, {
1551
- zoom: this.get('zoom'),
1552
- lat: this.get('lat'),
1553
- lng: this.get('lng')
1554
- }); // Create Map.
1555
-
1556
- var mapArgs = {
1557
- scrollwheel: false,
1558
- zoom: parseInt(args.zoom),
1559
- center: {
1560
- lat: parseFloat(args.lat),
1561
- lng: parseFloat(args.lng)
1562
- },
1563
- mapTypeId: google.maps.MapTypeId.ROADMAP,
1564
- marker: {
1565
- draggable: true,
1566
- raiseOnDrag: true
1567
- },
1568
- autocomplete: {}
1569
- };
1570
- mapArgs = acf.applyFilters('google_map_args', mapArgs, this);
1571
- var map = new google.maps.Map(this.$canvas()[0], mapArgs); // Create Marker.
1572
-
1573
- var markerArgs = acf.parseArgs(mapArgs.marker, {
1574
- draggable: true,
1575
- raiseOnDrag: true,
1576
- map: map
1577
- });
1578
- markerArgs = acf.applyFilters('google_map_marker_args', markerArgs, this);
1579
- var marker = new google.maps.Marker(markerArgs); // Maybe Create Autocomplete.
1580
-
1581
- var autocomplete = false;
1582
-
1583
- if (acf.isset(google, 'maps', 'places', 'Autocomplete')) {
1584
- var autocompleteArgs = mapArgs.autocomplete || {};
1585
- autocompleteArgs = acf.applyFilters('google_map_autocomplete_args', autocompleteArgs, this);
1586
- autocomplete = new google.maps.places.Autocomplete(this.$search()[0], autocompleteArgs);
1587
- autocomplete.bindTo('bounds', map);
1588
- } // Add map events.
1589
-
1590
-
1591
- this.addMapEvents(this, map, marker, autocomplete); // Append references.
1592
-
1593
- map.acf = this;
1594
- map.marker = marker;
1595
- map.autocomplete = autocomplete;
1596
- this.map = map; // Set position.
1597
-
1598
- if (val) {
1599
- this.setPosition(val.lat, val.lng);
1600
- }
1601
- /**
1602
- * Fires immediately after the Google Map has been initialized.
1603
- *
1604
- * @date 12/02/2014
1605
- * @since 5.0.0
1606
- *
1607
- * @param object map The Google Map isntance.
1608
- * @param object marker The Google Map marker isntance.
1609
- * @param object field The field instance.
1610
- */
1611
-
1612
-
1613
- acf.doAction('google_map_init', map, marker, this);
1614
- },
1615
- addMapEvents: function (field, map, marker, autocomplete) {
1616
- // Click map.
1617
- google.maps.event.addListener(map, 'click', function (e) {
1618
- var lat = e.latLng.lat();
1619
- var lng = e.latLng.lng();
1620
- field.searchPosition(lat, lng);
1621
- }); // Drag marker.
1622
-
1623
- google.maps.event.addListener(marker, 'dragend', function () {
1624
- var lat = this.getPosition().lat();
1625
- var lng = this.getPosition().lng();
1626
- field.searchPosition(lat, lng);
1627
- }); // Autocomplete search.
1628
-
1629
- if (autocomplete) {
1630
- google.maps.event.addListener(autocomplete, 'place_changed', function () {
1631
- var place = this.getPlace();
1632
- field.searchPlace(place);
1633
- });
1634
- } // Detect zoom change.
1635
-
1636
-
1637
- google.maps.event.addListener(map, 'zoom_changed', function () {
1638
- var val = field.val();
1639
-
1640
- if (val) {
1641
- val.zoom = map.getZoom();
1642
- field.setValue(val, true);
1643
- }
1644
- });
1645
- },
1646
- searchPosition: function (lat, lng) {
1647
- //console.log('searchPosition', lat, lng );
1648
- // Start Loading.
1649
- this.setState('loading'); // Query Geocoder.
1650
-
1651
- var latLng = {
1652
- lat: lat,
1653
- lng: lng
1654
- };
1655
- geocoder.geocode({
1656
- location: latLng
1657
- }, function (results, status) {
1658
- //console.log('searchPosition', arguments );
1659
- // End Loading.
1660
- this.setState(''); // Status failure.
1661
-
1662
- if (status !== 'OK') {
1663
- this.showNotice({
1664
- text: acf.__('Location not found: %s').replace('%s', status),
1665
- type: 'warning'
1666
- }); // Success.
1667
- } else {
1668
- var val = this.parseResult(results[0]); // Override lat/lng to match user defined marker location.
1669
- // Avoids issue where marker "snaps" to nearest result.
1670
-
1671
- val.lat = lat;
1672
- val.lng = lng;
1673
- this.val(val);
1674
- }
1675
- }.bind(this));
1676
- },
1677
- searchPlace: function (place) {
1678
- //console.log('searchPlace', place );
1679
- // Bail early if no place.
1680
- if (!place) {
1681
- return;
1682
- } // Selecting from the autocomplete dropdown will return a rich PlaceResult object.
1683
- // Be sure to over-write the "formatted_address" value with the one displayed to the user for best UX.
1684
-
1685
-
1686
- if (place.geometry) {
1687
- place.formatted_address = this.$search().val();
1688
- var val = this.parseResult(place);
1689
- this.val(val); // Searching a custom address will return an empty PlaceResult object.
1690
- } else if (place.name) {
1691
- this.searchAddress(place.name);
1692
- }
1693
- },
1694
- searchAddress: function (address) {
1695
- //console.log('searchAddress', address );
1696
- // Bail early if no address.
1697
- if (!address) {
1698
- return;
1699
- } // Allow "lat,lng" search.
1700
-
1701
-
1702
- var latLng = address.split(',');
1703
-
1704
- if (latLng.length == 2) {
1705
- var lat = parseFloat(latLng[0]);
1706
- var lng = parseFloat(latLng[1]);
1707
-
1708
- if (lat && lng) {
1709
- return this.searchPosition(lat, lng);
1710
- }
1711
- } // Start Loading.
1712
-
1713
-
1714
- this.setState('loading'); // Query Geocoder.
1715
-
1716
- geocoder.geocode({
1717
- address: address
1718
- }, function (results, status) {
1719
- //console.log('searchPosition', arguments );
1720
- // End Loading.
1721
- this.setState(''); // Status failure.
1722
-
1723
- if (status !== 'OK') {
1724
- this.showNotice({
1725
- text: acf.__('Location not found: %s').replace('%s', status),
1726
- type: 'warning'
1727
- }); // Success.
1728
- } else {
1729
- var val = this.parseResult(results[0]); // Override address data with parameter allowing custom address to be defined in search.
1730
-
1731
- val.address = address; // Update value.
1732
-
1733
- this.val(val);
1734
- }
1735
- }.bind(this));
1736
- },
1737
- searchLocation: function () {
1738
- //console.log('searchLocation' );
1739
- // Check HTML5 geolocation.
1740
- if (!navigator.geolocation) {
1741
- return alert(acf.__('Sorry, this browser does not support geolocation'));
1742
- } // Start Loading.
1743
-
1744
-
1745
- this.setState('loading'); // Query Geolocation.
1746
-
1747
- navigator.geolocation.getCurrentPosition( // Success.
1748
- function (results) {
1749
- // End Loading.
1750
- this.setState(''); // Search position.
1751
-
1752
- var lat = results.coords.latitude;
1753
- var lng = results.coords.longitude;
1754
- this.searchPosition(lat, lng);
1755
- }.bind(this), // Failure.
1756
- function (error) {
1757
- this.setState('');
1758
- }.bind(this));
1759
- },
1760
-
1761
- /**
1762
- * parseResult
1763
- *
1764
- * Returns location data for the given GeocoderResult object.
1765
- *
1766
- * @date 15/10/19
1767
- * @since 5.8.6
1768
- *
1769
- * @param object obj A GeocoderResult object.
1770
- * @return object
1771
- */
1772
- parseResult: function (obj) {
1773
- // Construct basic data.
1774
- var result = {
1775
- address: obj.formatted_address,
1776
- lat: obj.geometry.location.lat(),
1777
- lng: obj.geometry.location.lng()
1778
- }; // Add zoom level.
1779
-
1780
- result.zoom = this.map.getZoom(); // Add place ID.
1781
-
1782
- if (obj.place_id) {
1783
- result.place_id = obj.place_id;
1784
- } // Add place name.
1785
-
1786
-
1787
- if (obj.name) {
1788
- result.name = obj.name;
1789
- } // Create search map for address component data.
1790
-
1791
-
1792
- var map = {
1793
- street_number: ['street_number'],
1794
- street_name: ['street_address', 'route'],
1795
- city: ['locality'],
1796
- state: ['administrative_area_level_1', 'administrative_area_level_2', 'administrative_area_level_3', 'administrative_area_level_4', 'administrative_area_level_5'],
1797
- post_code: ['postal_code'],
1798
- country: ['country']
1799
- }; // Loop over map.
1800
-
1801
- for (var k in map) {
1802
- var keywords = map[k]; // Loop over address components.
1803
-
1804
- for (var i = 0; i < obj.address_components.length; i++) {
1805
- var component = obj.address_components[i];
1806
- var component_type = component.types[0]; // Look for matching component type.
1807
-
1808
- if (keywords.indexOf(component_type) !== -1) {
1809
- // Append to result.
1810
- result[k] = component.long_name; // Append short version.
1811
-
1812
- if (component.long_name !== component.short_name) {
1813
- result[k + '_short'] = component.short_name;
1814
- }
1815
- }
1816
- }
1817
- }
1818
- /**
1819
- * Filters the parsed result.
1820
- *
1821
- * @date 18/10/19
1822
- * @since 5.8.6
1823
- *
1824
- * @param object result The parsed result value.
1825
- * @param object obj The GeocoderResult object.
1826
- */
1827
-
1828
-
1829
- return acf.applyFilters('google_map_result', result, obj, this.map, this);
1830
- },
1831
- onClickClear: function () {
1832
- this.val(false);
1833
- },
1834
- onClickLocate: function () {
1835
- this.searchLocation();
1836
- },
1837
- onClickSearch: function () {
1838
- this.searchAddress(this.$search().val());
1839
- },
1840
- onFocusSearch: function (e, $el) {
1841
- this.setState('searching');
1842
- },
1843
- onBlurSearch: function (e, $el) {
1844
- // Get saved address value.
1845
- var val = this.val();
1846
- var address = val ? val.address : ''; // Remove 'is-searching' if value has not changed.
1847
-
1848
- if ($el.val() === address) {
1849
- this.setState('default');
1850
- }
1851
- },
1852
- onKeyupSearch: function (e, $el) {
1853
- // Clear empty value.
1854
- if (!$el.val()) {
1855
- this.val(false);
1856
- }
1857
- },
1858
- // Prevent form from submitting.
1859
- onKeydownSearch: function (e, $el) {
1860
- if (e.which == 13) {
1861
- e.preventDefault();
1862
- $el.blur();
1863
- }
1864
- },
1865
- // Center map once made visible.
1866
- onShow: function () {
1867
- if (this.map) {
1868
- this.setTimeout(this.center);
1869
- }
1870
- }
1871
- });
1872
- acf.registerFieldType(Field); // Vars.
1873
-
1874
- var loading = false;
1875
- var geocoder = false;
1876
- /**
1877
- * withAPI
1878
- *
1879
- * Loads the Google Maps API library and troggers callback.
1880
- *
1881
- * @date 28/3/19
1882
- * @since 5.7.14
1883
- *
1884
- * @param function callback The callback to excecute.
1885
- * @return void
1886
- */
1887
-
1888
- function withAPI(callback) {
1889
- // Check if geocoder exists.
1890
- if (geocoder) {
1891
- return callback();
1892
- } // Check if geocoder API exists.
1893
-
1894
-
1895
- if (acf.isset(window, 'google', 'maps', 'Geocoder')) {
1896
- geocoder = new google.maps.Geocoder();
1897
- return callback();
1898
- } // Geocoder will need to be loaded. Hook callback to action.
1899
-
1900
-
1901
- acf.addAction('google_map_api_loaded', callback); // Bail early if already loading API.
1902
-
1903
- if (loading) {
1904
- return;
1905
- } // load api
1906
-
1907
-
1908
- var url = acf.get('google_map_api');
1909
-
1910
- if (url) {
1911
- // Set loading status.
1912
- loading = true; // Load API
1913
-
1914
- $.ajax({
1915
- url: url,
1916
- dataType: 'script',
1917
- cache: true,
1918
- success: function () {
1919
- geocoder = new google.maps.Geocoder();
1920
- acf.doAction('google_map_api_loaded');
1921
- }
1922
- });
1923
- }
1924
- }
1925
- })(jQuery);
1926
-
1927
- (function ($, undefined) {
1928
- var Field = acf.Field.extend({
1929
- type: 'image',
1930
- $control: function () {
1931
- return this.$('.acf-image-uploader');
1932
- },
1933
- $input: function () {
1934
- return this.$('input[type="hidden"]');
1935
- },
1936
- events: {
1937
- 'click a[data-name="add"]': 'onClickAdd',
1938
- 'click a[data-name="edit"]': 'onClickEdit',
1939
- 'click a[data-name="remove"]': 'onClickRemove',
1940
- 'change input[type="file"]': 'onChange'
1941
- },
1942
- initialize: function () {
1943
- // add attribute to form
1944
- if (this.get('uploader') === 'basic') {
1945
- this.$el.closest('form').attr('enctype', 'multipart/form-data');
1946
- }
1947
- },
1948
- validateAttachment: function (attachment) {
1949
- // Use WP attachment attributes when available.
1950
- if (attachment && attachment.attributes) {
1951
- attachment = attachment.attributes;
1952
- } // Apply defaults.
1953
-
1954
-
1955
- attachment = acf.parseArgs(attachment, {
1956
- id: 0,
1957
- url: '',
1958
- alt: '',
1959
- title: '',
1960
- caption: '',
1961
- description: '',
1962
- width: 0,
1963
- height: 0
1964
- }); // Override with "preview size".
1965
-
1966
- var size = acf.isget(attachment, 'sizes', this.get('preview_size'));
1967
-
1968
- if (size) {
1969
- attachment.url = size.url;
1970
- attachment.width = size.width;
1971
- attachment.height = size.height;
1972
- } // Return.
1973
-
1974
-
1975
- return attachment;
1976
- },
1977
- render: function (attachment) {
1978
- attachment = this.validateAttachment(attachment); // Update DOM.
1979
-
1980
- this.$('img').attr({
1981
- src: attachment.url,
1982
- alt: attachment.alt
1983
- });
1984
-
1985
- if (attachment.id) {
1986
- this.val(attachment.id);
1987
- this.$control().addClass('has-value');
1988
- } else {
1989
- this.val('');
1990
- this.$control().removeClass('has-value');
1991
- }
1992
- },
1993
- // create a new repeater row and render value
1994
- append: function (attachment, parent) {
1995
- // create function to find next available field within parent
1996
- var getNext = function (field, parent) {
1997
- // find existing file fields within parent
1998
- var fields = acf.getFields({
1999
- key: field.get('key'),
2000
- parent: parent.$el
2001
- }); // find the first field with no value
2002
-
2003
- for (var i = 0; i < fields.length; i++) {
2004
- if (!fields[i].val()) {
2005
- return fields[i];
2006
- }
2007
- } // return
2008
-
2009
-
2010
- return false;
2011
- }; // find existing file fields within parent
2012
-
2013
-
2014
- var field = getNext(this, parent); // add new row if no available field
2015
-
2016
- if (!field) {
2017
- parent.$('.acf-button:last').trigger('click');
2018
- field = getNext(this, parent);
2019
- } // render
2020
-
2021
-
2022
- if (field) {
2023
- field.render(attachment);
2024
- }
2025
- },
2026
- selectAttachment: function () {
2027
- // vars
2028
- var parent = this.parent();
2029
- var multiple = parent && parent.get('type') === 'repeater'; // new frame
2030
-
2031
- var frame = acf.newMediaPopup({
2032
- mode: 'select',
2033
- type: 'image',
2034
- title: acf.__('Select Image'),
2035
- field: this.get('key'),
2036
- multiple: multiple,
2037
- library: this.get('library'),
2038
- allowedTypes: this.get('mime_types'),
2039
- select: $.proxy(function (attachment, i) {
2040
- if (i > 0) {
2041
- this.append(attachment, parent);
2042
- } else {
2043
- this.render(attachment);
2044
- }
2045
- }, this)
2046
- });
2047
- },
2048
- editAttachment: function () {
2049
- // vars
2050
- var val = this.val(); // bail early if no val
2051
-
2052
- if (!val) return; // popup
2053
-
2054
- var frame = acf.newMediaPopup({
2055
- mode: 'edit',
2056
- title: acf.__('Edit Image'),
2057
- button: acf.__('Update Image'),
2058
- attachment: val,
2059
- field: this.get('key'),
2060
- select: $.proxy(function (attachment, i) {
2061
- this.render(attachment);
2062
- }, this)
2063
- });
2064
- },
2065
- removeAttachment: function () {
2066
- this.render(false);
2067
- },
2068
- onClickAdd: function (e, $el) {
2069
- this.selectAttachment();
2070
- },
2071
- onClickEdit: function (e, $el) {
2072
- this.editAttachment();
2073
- },
2074
- onClickRemove: function (e, $el) {
2075
- this.removeAttachment();
2076
- },
2077
- onChange: function (e, $el) {
2078
- var $hiddenInput = this.$input();
2079
- acf.getFileInputData($el, function (data) {
2080
- $hiddenInput.val($.param(data));
2081
- });
2082
- }
2083
- });
2084
- acf.registerFieldType(Field);
2085
- })(jQuery);
2086
-
2087
- (function ($, undefined) {
2088
- var Field = acf.models.ImageField.extend({
2089
- type: 'file',
2090
- $control: function () {
2091
- return this.$('.acf-file-uploader');
2092
- },
2093
- $input: function () {
2094
- return this.$('input[type="hidden"]');
2095
- },
2096
- validateAttachment: function (attachment) {
2097
- // defaults
2098
- attachment = attachment || {}; // WP attachment
2099
-
2100
- if (attachment.id !== undefined) {
2101
- attachment = attachment.attributes;
2102
- } // args
2103
-
2104
-
2105
- attachment = acf.parseArgs(attachment, {
2106
- url: '',
2107
- alt: '',
2108
- title: '',
2109
- filename: '',
2110
- filesizeHumanReadable: '',
2111
- icon: '/wp-includes/images/media/default.png'
2112
- }); // return
2113
-
2114
- return attachment;
2115
- },
2116
- render: function (attachment) {
2117
- // vars
2118
- attachment = this.validateAttachment(attachment); // update image
2119
-
2120
- this.$('img').attr({
2121
- src: attachment.icon,
2122
- alt: attachment.alt,
2123
- title: attachment.title
2124
- }); // update elements
2125
-
2126
- this.$('[data-name="title"]').text(attachment.title);
2127
- this.$('[data-name="filename"]').text(attachment.filename).attr('href', attachment.url);
2128
- this.$('[data-name="filesize"]').text(attachment.filesizeHumanReadable); // vars
2129
-
2130
- var val = attachment.id || ''; // update val
2131
-
2132
- acf.val(this.$input(), val); // update class
2133
-
2134
- if (val) {
2135
- this.$control().addClass('has-value');
2136
- } else {
2137
- this.$control().removeClass('has-value');
2138
- }
2139
- },
2140
- selectAttachment: function () {
2141
- // vars
2142
- var parent = this.parent();
2143
- var multiple = parent && parent.get('type') === 'repeater'; // new frame
2144
-
2145
- var frame = acf.newMediaPopup({
2146
- mode: 'select',
2147
- title: acf.__('Select File'),
2148
- field: this.get('key'),
2149
- multiple: multiple,
2150
- library: this.get('library'),
2151
- allowedTypes: this.get('mime_types'),
2152
- select: $.proxy(function (attachment, i) {
2153
- if (i > 0) {
2154
- this.append(attachment, parent);
2155
- } else {
2156
- this.render(attachment);
2157
- }
2158
- }, this)
2159
- });
2160
- },
2161
- editAttachment: function () {
2162
- // vars
2163
- var val = this.val(); // bail early if no val
2164
-
2165
- if (!val) {
2166
- return false;
2167
- } // popup
2168
-
2169
-
2170
- var frame = acf.newMediaPopup({
2171
- mode: 'edit',
2172
- title: acf.__('Edit File'),
2173
- button: acf.__('Update File'),
2174
- attachment: val,
2175
- field: this.get('key'),
2176
- select: $.proxy(function (attachment, i) {
2177
- this.render(attachment);
2178
- }, this)
2179
- });
2180
- }
2181
- });
2182
- acf.registerFieldType(Field);
2183
- })(jQuery);
2184
-
2185
- (function ($, undefined) {
2186
- var Field = acf.Field.extend({
2187
- type: 'link',
2188
- events: {
2189
- 'click a[data-name="add"]': 'onClickEdit',
2190
- 'click a[data-name="edit"]': 'onClickEdit',
2191
- 'click a[data-name="remove"]': 'onClickRemove',
2192
- 'change .link-node': 'onChange'
2193
- },
2194
- $control: function () {
2195
- return this.$('.acf-link');
2196
- },
2197
- $node: function () {
2198
- return this.$('.link-node');
2199
- },
2200
- getValue: function () {
2201
- // vars
2202
- var $node = this.$node(); // return false if empty
2203
-
2204
- if (!$node.attr('href')) {
2205
- return false;
2206
- } // return
2207
-
2208
-
2209
- return {
2210
- title: $node.html(),
2211
- url: $node.attr('href'),
2212
- target: $node.attr('target')
2213
- };
2214
- },
2215
- setValue: function (val) {
2216
- // default
2217
- val = acf.parseArgs(val, {
2218
- title: '',
2219
- url: '',
2220
- target: ''
2221
- }); // vars
2222
-
2223
- var $div = this.$control();
2224
- var $node = this.$node(); // remove class
2225
-
2226
- $div.removeClass('-value -external'); // add class
2227
-
2228
- if (val.url) $div.addClass('-value');
2229
- if (val.target === '_blank') $div.addClass('-external'); // update text
2230
-
2231
- this.$('.link-title').html(val.title);
2232
- this.$('.link-url').attr('href', val.url).html(val.url); // update node
2233
-
2234
- $node.html(val.title);
2235
- $node.attr('href', val.url);
2236
- $node.attr('target', val.target); // update inputs
2237
-
2238
- this.$('.input-title').val(val.title);
2239
- this.$('.input-target').val(val.target);
2240
- this.$('.input-url').val(val.url).trigger('change');
2241
- },
2242
- onClickEdit: function (e, $el) {
2243
- acf.wpLink.open(this.$node());
2244
- },
2245
- onClickRemove: function (e, $el) {
2246
- this.setValue(false);
2247
- },
2248
- onChange: function (e, $el) {
2249
- // get the changed value
2250
- var val = this.getValue(); // update inputs
2251
-
2252
- this.setValue(val);
2253
- }
2254
- });
2255
- acf.registerFieldType(Field); // manager
2256
-
2257
- acf.wpLink = new acf.Model({
2258
- getNodeValue: function () {
2259
- var $node = this.get('node');
2260
- return {
2261
- title: acf.decode($node.html()),
2262
- url: $node.attr('href'),
2263
- target: $node.attr('target')
2264
- };
2265
- },
2266
- setNodeValue: function (val) {
2267
- var $node = this.get('node');
2268
- $node.text(val.title);
2269
- $node.attr('href', val.url);
2270
- $node.attr('target', val.target);
2271
- $node.trigger('change');
2272
- },
2273
- getInputValue: function () {
2274
- return {
2275
- title: $('#wp-link-text').val(),
2276
- url: $('#wp-link-url').val(),
2277
- target: $('#wp-link-target').prop('checked') ? '_blank' : ''
2278
- };
2279
- },
2280
- setInputValue: function (val) {
2281
- $('#wp-link-text').val(val.title);
2282
- $('#wp-link-url').val(val.url);
2283
- $('#wp-link-target').prop('checked', val.target === '_blank');
2284
- },
2285
- open: function ($node) {
2286
- // add events
2287
- this.on('wplink-open', 'onOpen');
2288
- this.on('wplink-close', 'onClose'); // set node
2289
-
2290
- this.set('node', $node); // create textarea
2291
-
2292
- var $textarea = $('<textarea id="acf-link-textarea" style="display:none;"></textarea>');
2293
- $('body').append($textarea); // vars
2294
-
2295
- var val = this.getNodeValue(); // open popup
2296
-
2297
- wpLink.open('acf-link-textarea', val.url, val.title, null);
2298
- },
2299
- onOpen: function () {
2300
- // always show title (WP will hide title if empty)
2301
- $('#wp-link-wrap').addClass('has-text-field'); // set inputs
2302
-
2303
- var val = this.getNodeValue();
2304
- this.setInputValue(val); // Update button text.
2305
-
2306
- if (val.url && wpLinkL10n) {
2307
- $('#wp-link-submit').val(wpLinkL10n.update);
2308
- }
2309
- },
2310
- close: function () {
2311
- wpLink.close();
2312
- },
2313
- onClose: function () {
2314
- // Bail early if no node.
2315
- // Needed due to WP triggering this event twice.
2316
- if (!this.has('node')) {
2317
- return false;
2318
- } // Determine context.
2319
-
2320
-
2321
- var $submit = $('#wp-link-submit');
2322
- var isSubmit = $submit.is(':hover') || $submit.is(':focus'); // Set value
2323
-
2324
- if (isSubmit) {
2325
- var val = this.getInputValue();
2326
- this.setNodeValue(val);
2327
- } // Cleanup.
2328
-
2329
-
2330
- this.off('wplink-open');
2331
- this.off('wplink-close');
2332
- $('#acf-link-textarea').remove();
2333
- this.set('node', null);
2334
- }
2335
- });
2336
  })(jQuery);
2337
-
2338
- (function ($, undefined) {
2339
- var Field = acf.Field.extend({
2340
- type: 'oembed',
2341
- events: {
2342
- 'click [data-name="clear-button"]': 'onClickClear',
2343
- 'keypress .input-search': 'onKeypressSearch',
2344
- 'keyup .input-search': 'onKeyupSearch',
2345
- 'change .input-search': 'onChangeSearch'
2346
- },
2347
- $control: function () {
2348
- return this.$('.acf-oembed');
2349
- },
2350
- $input: function () {
2351
- return this.$('.input-value');
2352
- },
2353
- $search: function () {
2354
- return this.$('.input-search');
2355
- },
2356
- getValue: function () {
2357
- return this.$input().val();
2358
- },
2359
- getSearchVal: function () {
2360
- return this.$search().val();
2361
- },
2362
- setValue: function (val) {
2363
- // class
2364
- if (val) {
2365
- this.$control().addClass('has-value');
2366
- } else {
2367
- this.$control().removeClass('has-value');
2368
- }
2369
-
2370
- acf.val(this.$input(), val);
2371
- },
2372
- showLoading: function (show) {
2373
- acf.showLoading(this.$('.canvas'));
2374
- },
2375
- hideLoading: function () {
2376
- acf.hideLoading(this.$('.canvas'));
2377
- },
2378
- maybeSearch: function () {
2379
- // vars
2380
- var prevUrl = this.val();
2381
- var url = this.getSearchVal(); // no value
2382
-
2383
- if (!url) {
2384
- return this.clear();
2385
- } // fix missing 'http://' - causes the oembed code to error and fail
2386
-
2387
-
2388
- if (url.substr(0, 4) != 'http') {
2389
- url = 'http://' + url;
2390
- } // bail early if no change
2391
-
2392
-
2393
- if (url === prevUrl) return; // clear existing timeout
2394
-
2395
- var timeout = this.get('timeout');
2396
-
2397
- if (timeout) {
2398
- clearTimeout(timeout);
2399
- } // set new timeout
2400
-
2401
-
2402
- var callback = $.proxy(this.search, this, url);
2403
- this.set('timeout', setTimeout(callback, 300));
2404
- },
2405
- search: function (url) {
2406
- // ajax
2407
- var ajaxData = {
2408
- action: 'acf/fields/oembed/search',
2409
- s: url,
2410
- field_key: this.get('key')
2411
- }; // clear existing timeout
2412
-
2413
- var xhr = this.get('xhr');
2414
-
2415
- if (xhr) {
2416
- xhr.abort();
2417
- } // loading
2418
-
2419
-
2420
- this.showLoading(); // query
2421
-
2422
- var xhr = $.ajax({
2423
- url: acf.get('ajaxurl'),
2424
- data: acf.prepareForAjax(ajaxData),
2425
- type: 'post',
2426
- dataType: 'json',
2427
- context: this,
2428
- success: function (json) {
2429
- // error
2430
- if (!json || !json.html) {
2431
- json = {
2432
- url: false,
2433
- html: ''
2434
- };
2435
- } // update vars
2436
-
2437
-
2438
- this.val(json.url);
2439
- this.$('.canvas-media').html(json.html);
2440
- },
2441
- complete: function () {
2442
- this.hideLoading();
2443
- }
2444
- });
2445
- this.set('xhr', xhr);
2446
- },
2447
- clear: function () {
2448
- this.val('');
2449
- this.$search().val('');
2450
- this.$('.canvas-media').html('');
2451
- },
2452
- onClickClear: function (e, $el) {
2453
- this.clear();
2454
- },
2455
- onKeypressSearch: function (e, $el) {
2456
- if (e.which == 13) {
2457
- e.preventDefault();
2458
- this.maybeSearch();
2459
- }
2460
- },
2461
- onKeyupSearch: function (e, $el) {
2462
- if ($el.val()) {
2463
- this.maybeSearch();
2464
- }
2465
- },
2466
- onChangeSearch: function (e, $el) {
2467
- this.maybeSearch();
2468
- }
2469
- });
2470
- acf.registerFieldType(Field);
2471
- })(jQuery);
2472
-
2473
- (function ($, undefined) {
2474
- var Field = acf.Field.extend({
2475
- type: 'radio',
2476
- events: {
2477
- 'click input[type="radio"]': 'onClick'
2478
- },
2479
- $control: function () {
2480
- return this.$('.acf-radio-list');
2481
- },
2482
- $input: function () {
2483
- return this.$('input:checked');
2484
- },
2485
- $inputText: function () {
2486
- return this.$('input[type="text"]');
2487
- },
2488
- getValue: function () {
2489
- var val = this.$input().val();
2490
-
2491
- if (val === 'other' && this.get('other_choice')) {
2492
- val = this.$inputText().val();
2493
- }
2494
-
2495
- return val;
2496
- },
2497
- onClick: function (e, $el) {
2498
- // vars
2499
- var $label = $el.parent('label');
2500
- var selected = $label.hasClass('selected');
2501
- var val = $el.val(); // remove previous selected
2502
-
2503
- this.$('.selected').removeClass('selected'); // add active class
2504
-
2505
- $label.addClass('selected'); // allow null
2506
-
2507
- if (this.get('allow_null') && selected) {
2508
- $label.removeClass('selected');
2509
- $el.prop('checked', false).trigger('change');
2510
- val = false;
2511
- } // other
2512
-
2513
-
2514
- if (this.get('other_choice')) {
2515
- // enable
2516
- if (val === 'other') {
2517
- this.$inputText().prop('disabled', false); // disable
2518
- } else {
2519
- this.$inputText().prop('disabled', true);
2520
- }
2521
- }
2522
- }
2523
- });
2524
- acf.registerFieldType(Field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2525
  })(jQuery);
2526
-
2527
- (function ($, undefined) {
2528
- var Field = acf.Field.extend({
2529
- type: 'range',
2530
- events: {
2531
- 'input input[type="range"]': 'onChange',
2532
- 'change input': 'onChange'
2533
- },
2534
- $input: function () {
2535
- return this.$('input[type="range"]');
2536
- },
2537
- $inputAlt: function () {
2538
- return this.$('input[type="number"]');
2539
- },
2540
- setValue: function (val) {
2541
- this.busy = true; // Update range input (with change).
2542
-
2543
- acf.val(this.$input(), val); // Update alt input (without change).
2544
- // Read in input value to inherit min/max validation.
2545
-
2546
- acf.val(this.$inputAlt(), this.$input().val(), true);
2547
- this.busy = false;
2548
- },
2549
- onChange: function (e, $el) {
2550
- if (!this.busy) {
2551
- this.setValue($el.val());
2552
- }
2553
- }
2554
- });
2555
- acf.registerFieldType(Field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2556
  })(jQuery);
2557
-
2558
- (function ($, undefined) {
2559
- var Field = acf.Field.extend({
2560
- type: 'relationship',
2561
- events: {
2562
- 'keypress [data-filter]': 'onKeypressFilter',
2563
- 'change [data-filter]': 'onChangeFilter',
2564
- 'keyup [data-filter]': 'onChangeFilter',
2565
- 'click .choices-list .acf-rel-item': 'onClickAdd',
2566
- 'click [data-name="remove_item"]': 'onClickRemove'
2567
- },
2568
- $control: function () {
2569
- return this.$('.acf-relationship');
2570
- },
2571
- $list: function (list) {
2572
- return this.$('.' + list + '-list');
2573
- },
2574
- $listItems: function (list) {
2575
- return this.$list(list).find('.acf-rel-item');
2576
- },
2577
- $listItem: function (list, id) {
2578
- return this.$list(list).find('.acf-rel-item[data-id="' + id + '"]');
2579
- },
2580
- getValue: function () {
2581
- var val = [];
2582
- this.$listItems('values').each(function () {
2583
- val.push($(this).data('id'));
2584
- });
2585
- return val.length ? val : false;
2586
- },
2587
- newChoice: function (props) {
2588
- return ['<li>', '<span data-id="' + props.id + '" class="acf-rel-item">' + props.text + '</span>', '</li>'].join('');
2589
- },
2590
- newValue: function (props) {
2591
- return ['<li>', '<input type="hidden" name="' + this.getInputName() + '[]" value="' + props.id + '" />', '<span data-id="' + props.id + '" class="acf-rel-item">' + props.text, '<a href="#" class="acf-icon -minus small dark" data-name="remove_item"></a>', '</span>', '</li>'].join('');
2592
- },
2593
- initialize: function () {
2594
- // Delay initialization until "interacted with" or "in view".
2595
- var delayed = this.proxy(acf.once(function () {
2596
- // Add sortable.
2597
- this.$list('values').sortable({
2598
- items: 'li',
2599
- forceHelperSize: true,
2600
- forcePlaceholderSize: true,
2601
- scroll: true,
2602
- update: this.proxy(function () {
2603
- this.$input().trigger('change');
2604
- })
2605
- }); // Avoid browser remembering old scroll position and add event.
2606
-
2607
- this.$list('choices').scrollTop(0).on('scroll', this.proxy(this.onScrollChoices)); // Fetch choices.
2608
-
2609
- this.fetch();
2610
- })); // Bind "interacted with".
2611
-
2612
- this.$el.one('mouseover', delayed);
2613
- this.$el.one('focus', 'input', delayed); // Bind "in view".
2614
-
2615
- acf.onceInView(this.$el, delayed);
2616
- },
2617
- onScrollChoices: function (e) {
2618
- // bail early if no more results
2619
- if (this.get('loading') || !this.get('more')) {
2620
- return;
2621
- } // Scrolled to bottom
2622
-
2623
-
2624
- var $list = this.$list('choices');
2625
- var scrollTop = Math.ceil($list.scrollTop());
2626
- var scrollHeight = Math.ceil($list[0].scrollHeight);
2627
- var innerHeight = Math.ceil($list.innerHeight());
2628
- var paged = this.get('paged') || 1;
2629
-
2630
- if (scrollTop + innerHeight >= scrollHeight) {
2631
- // update paged
2632
- this.set('paged', paged + 1); // fetch
2633
-
2634
- this.fetch();
2635
- }
2636
- },
2637
- onKeypressFilter: function (e, $el) {
2638
- // don't submit form
2639
- if (e.which == 13) {
2640
- e.preventDefault();
2641
- }
2642
- },
2643
- onChangeFilter: function (e, $el) {
2644
- // vars
2645
- var val = $el.val();
2646
- var filter = $el.data('filter'); // Bail early if filter has not changed
2647
-
2648
- if (this.get(filter) === val) {
2649
- return;
2650
- } // update attr
2651
-
2652
-
2653
- this.set(filter, val); // reset paged
2654
-
2655
- this.set('paged', 1); // fetch
2656
-
2657
- if ($el.is('select')) {
2658
- this.fetch(); // search must go through timeout
2659
- } else {
2660
- this.maybeFetch();
2661
- }
2662
- },
2663
- onClickAdd: function (e, $el) {
2664
- // vars
2665
- var val = this.val();
2666
- var max = parseInt(this.get('max')); // can be added?
2667
-
2668
- if ($el.hasClass('disabled')) {
2669
- return false;
2670
- } // validate
2671
-
2672
-
2673
- if (max > 0 && val && val.length >= max) {
2674
- // add notice
2675
- this.showNotice({
2676
- text: acf.__('Maximum values reached ( {max} values )').replace('{max}', max),
2677
- type: 'warning'
2678
- });
2679
- return false;
2680
- } // disable
2681
-
2682
-
2683
- $el.addClass('disabled'); // add
2684
-
2685
- var html = this.newValue({
2686
- id: $el.data('id'),
2687
- text: $el.html()
2688
- });
2689
- this.$list('values').append(html); // trigger change
2690
-
2691
- this.$input().trigger('change');
2692
- },
2693
- onClickRemove: function (e, $el) {
2694
- // Prevent default here because generic handler wont be triggered.
2695
- e.preventDefault(); // vars
2696
-
2697
- var $span = $el.parent();
2698
- var $li = $span.parent();
2699
- var id = $span.data('id'); // remove value
2700
-
2701
- $li.remove(); // show choice
2702
-
2703
- this.$listItem('choices', id).removeClass('disabled'); // trigger change
2704
-
2705
- this.$input().trigger('change');
2706
- },
2707
- maybeFetch: function () {
2708
- // vars
2709
- var timeout = this.get('timeout'); // abort timeout
2710
-
2711
- if (timeout) {
2712
- clearTimeout(timeout);
2713
- } // fetch
2714
-
2715
-
2716
- timeout = this.setTimeout(this.fetch, 300);
2717
- this.set('timeout', timeout);
2718
- },
2719
- getAjaxData: function () {
2720
- // load data based on element attributes
2721
- var ajaxData = this.$control().data();
2722
-
2723
- for (var name in ajaxData) {
2724
- ajaxData[name] = this.get(name);
2725
- } // extra
2726
-
2727
-
2728
- ajaxData.action = 'acf/fields/relationship/query';
2729
- ajaxData.field_key = this.get('key'); // Filter.
2730
-
2731
- ajaxData = acf.applyFilters('relationship_ajax_data', ajaxData, this); // return
2732
-
2733
- return ajaxData;
2734
- },
2735
- fetch: function () {
2736
- // abort XHR if this field is already loading AJAX data
2737
- var xhr = this.get('xhr');
2738
-
2739
- if (xhr) {
2740
- xhr.abort();
2741
- } // add to this.o
2742
-
2743
-
2744
- var ajaxData = this.getAjaxData(); // clear html if is new query
2745
-
2746
- var $choiceslist = this.$list('choices');
2747
-
2748
- if (ajaxData.paged == 1) {
2749
- $choiceslist.html('');
2750
- } // loading
2751
-
2752
-
2753
- var $loading = $('<li><i class="acf-loading"></i> ' + acf.__('Loading') + '</li>');
2754
- $choiceslist.append($loading);
2755
- this.set('loading', true); // callback
2756
-
2757
- var onComplete = function () {
2758
- this.set('loading', false);
2759
- $loading.remove();
2760
- };
2761
-
2762
- var onSuccess = function (json) {
2763
- // no results
2764
- if (!json || !json.results || !json.results.length) {
2765
- // prevent pagination
2766
- this.set('more', false); // add message
2767
-
2768
- if (this.get('paged') == 1) {
2769
- this.$list('choices').append('<li>' + acf.__('No matches found') + '</li>');
2770
- } // return
2771
-
2772
-
2773
- return;
2774
- } // set more (allows pagination scroll)
2775
-
2776
-
2777
- this.set('more', json.more); // get new results
2778
-
2779
- var html = this.walkChoices(json.results);
2780
- var $html = $(html); // apply .disabled to left li's
2781
-
2782
- var val = this.val();
2783
-
2784
- if (val && val.length) {
2785
- val.map(function (id) {
2786
- $html.find('.acf-rel-item[data-id="' + id + '"]').addClass('disabled');
2787
- });
2788
- } // append
2789
-
2790
-
2791
- $choiceslist.append($html); // merge together groups
2792
-
2793
- var $prevLabel = false;
2794
- var $prevList = false;
2795
- $choiceslist.find('.acf-rel-label').each(function () {
2796
- var $label = $(this);
2797
- var $list = $label.siblings('ul');
2798
-
2799
- if ($prevLabel && $prevLabel.text() == $label.text()) {
2800
- $prevList.append($list.children());
2801
- $(this).parent().remove();
2802
- return;
2803
- } // update vars
2804
-
2805
-
2806
- $prevLabel = $label;
2807
- $prevList = $list;
2808
- });
2809
- }; // get results
2810
-
2811
-
2812
- var xhr = $.ajax({
2813
- url: acf.get('ajaxurl'),
2814
- dataType: 'json',
2815
- type: 'post',
2816
- data: acf.prepareForAjax(ajaxData),
2817
- context: this,
2818
- success: onSuccess,
2819
- complete: onComplete
2820
- }); // set
2821
-
2822
- this.set('xhr', xhr);
2823
- },
2824
- walkChoices: function (data) {
2825
- // walker
2826
- var walk = function (data) {
2827
- // vars
2828
- var html = ''; // is array
2829
-
2830
- if ($.isArray(data)) {
2831
- data.map(function (item) {
2832
- html += walk(item);
2833
- }); // is item
2834
- } else if ($.isPlainObject(data)) {
2835
- // group
2836
- if (data.children !== undefined) {
2837
- html += '<li><span class="acf-rel-label">' + acf.escHtml(data.text) + '</span><ul class="acf-bl">';
2838
- html += walk(data.children);
2839
- html += '</ul></li>'; // single
2840
- } else {
2841
- html += '<li><span class="acf-rel-item" data-id="' + acf.escAttr(data.id) + '">' + acf.escHtml(data.text) + '</span></li>';
2842
- }
2843
- } // return
2844
-
2845
-
2846
- return html;
2847
- };
2848
-
2849
- return walk(data);
2850
- }
2851
- });
2852
- acf.registerFieldType(Field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2853
  })(jQuery);
2854
-
2855
- (function ($, undefined) {
2856
- var Field = acf.Field.extend({
2857
- type: 'select',
2858
- select2: false,
2859
- wait: 'load',
2860
- events: {
2861
- 'removeField': 'onRemove',
2862
- 'duplicateField': 'onDuplicate'
2863
- },
2864
- $input: function () {
2865
- return this.$('select');
2866
- },
2867
- initialize: function () {
2868
- // vars
2869
- var $select = this.$input(); // inherit data
2870
-
2871
- this.inherit($select); // select2
2872
-
2873
- if (this.get('ui')) {
2874
- // populate ajax_data (allowing custom attribute to already exist)
2875
- var ajaxAction = this.get('ajax_action');
2876
-
2877
- if (!ajaxAction) {
2878
- ajaxAction = 'acf/fields/' + this.get('type') + '/query';
2879
- } // select2
2880
-
2881
-
2882
- this.select2 = acf.newSelect2($select, {
2883
- field: this,
2884
- ajax: this.get('ajax'),
2885
- multiple: this.get('multiple'),
2886
- placeholder: this.get('placeholder'),
2887
- allowNull: this.get('allow_null'),
2888
- ajaxAction: ajaxAction
2889
- });
2890
- }
2891
- },
2892
- onRemove: function () {
2893
- if (this.select2) {
2894
- this.select2.destroy();
2895
- }
2896
- },
2897
- onDuplicate: function (e, $el, $duplicate) {
2898
- if (this.select2) {
2899
- $duplicate.find('.select2-container').remove();
2900
- $duplicate.find('select').removeClass('select2-hidden-accessible');
2901
- }
2902
- }
2903
- });
2904
- acf.registerFieldType(Field);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2905
  })(jQuery);
2906
-
2907
- (function ($, undefined) {
2908
- // vars
2909
- var CONTEXT = 'tab';
2910
- var Field = acf.Field.extend({
2911
- type: 'tab',
2912
- wait: '',
2913
- tabs: false,
2914
- tab: false,
2915
- events: {
2916
- 'duplicateField': 'onDuplicate'
2917
- },
2918
- findFields: function () {
2919
- return this.$el.nextUntil('.acf-field-tab', '.acf-field');
2920
- },
2921
- getFields: function () {
2922
- return acf.getFields(this.findFields());
2923
- },
2924
- findTabs: function () {
2925
- return this.$el.prevAll('.acf-tab-wrap:first');
2926
- },
2927
- findTab: function () {
2928
- return this.$('.acf-tab-button');
2929
- },
2930
- initialize: function () {
2931
- // bail early if is td
2932
- if (this.$el.is('td')) {
2933
- this.events = {};
2934
- return false;
2935
- } // vars
2936
-
2937
-
2938
- var $tabs = this.findTabs();
2939
- var $tab = this.findTab();
2940
- var settings = acf.parseArgs($tab.data(), {
2941
- endpoint: false,
2942
- placement: '',
2943
- before: this.$el
2944
- }); // create wrap
2945
-
2946
- if (!$tabs.length || settings.endpoint) {
2947
- this.tabs = new Tabs(settings);
2948
- } else {
2949
- this.tabs = $tabs.data('acf');
2950
- } // add tab
2951
-
2952
-
2953
- this.tab = this.tabs.addTab($tab, this);
2954
- },
2955
- isActive: function () {
2956
- return this.tab.isActive();
2957
- },
2958
- showFields: function () {
2959
- // show fields
2960
- this.getFields().map(function (field) {
2961
- field.show(this.cid, CONTEXT);
2962
- field.hiddenByTab = false;
2963
- }, this);
2964
- },
2965
- hideFields: function () {
2966
- // hide fields
2967
- this.getFields().map(function (field) {
2968
- field.hide(this.cid, CONTEXT);
2969
- field.hiddenByTab = this.tab;
2970
- }, this);
2971
- },
2972
- show: function (lockKey) {
2973
- // show field and store result
2974
- var visible = acf.Field.prototype.show.apply(this, arguments); // check if now visible
2975
-
2976
- if (visible) {
2977
- // show tab
2978
- this.tab.show(); // check active tabs
2979
-
2980
- this.tabs.refresh();
2981
- } // return
2982
-
2983
-
2984
- return visible;
2985
- },
2986
- hide: function (lockKey) {
2987
- // hide field and store result
2988
- var hidden = acf.Field.prototype.hide.apply(this, arguments); // check if now hidden
2989
-
2990
- if (hidden) {
2991
- // hide tab
2992
- this.tab.hide(); // reset tabs if this was active
2993
-
2994
- if (this.isActive()) {
2995
- this.tabs.reset();
2996
- }
2997
- } // return
2998
-
2999
-
3000
- return hidden;
3001
- },
3002
- enable: function (lockKey) {
3003
- // enable fields
3004
- this.getFields().map(function (field) {
3005
- field.enable(CONTEXT);
3006
- });
3007
- },
3008
- disable: function (lockKey) {
3009
- // disable fields
3010
- this.getFields().map(function (field) {
3011
- field.disable(CONTEXT);
3012
- });
3013
- },
3014
- onDuplicate: function (e, $el, $duplicate) {
3015
- if (this.isActive()) {
3016
- $duplicate.prevAll('.acf-tab-wrap:first').remove();
3017
- }
3018
- }
3019
- });
3020
- acf.registerFieldType(Field);
3021
- /**
3022
- * tabs
3023
- *
3024
- * description
3025
- *
3026
- * @date 8/2/18
3027
- * @since 5.6.5
3028
- *
3029
- * @param type $var Description. Default.
3030
- * @return type Description.
3031
- */
3032
-
3033
- var i = 0;
3034
- var Tabs = acf.Model.extend({
3035
- tabs: [],
3036
- active: false,
3037
- actions: {
3038
- 'refresh': 'onRefresh'
3039
- },
3040
- data: {
3041
- before: false,
3042
- placement: 'top',
3043
- index: 0,
3044
- initialized: false
3045
- },
3046
- setup: function (settings) {
3047
- // data
3048
- $.extend(this.data, settings); // define this prop to avoid scope issues
3049
-
3050
- this.tabs = [];
3051
- this.active = false; // vars
3052
-
3053
- var placement = this.get('placement');
3054
- var $before = this.get('before');
3055
- var $parent = $before.parent(); // add sidebar for left placement
3056
-
3057
- if (placement == 'left' && $parent.hasClass('acf-fields')) {
3058
- $parent.addClass('-sidebar');
3059
- } // create wrap
3060
-
3061
-
3062
- if ($before.is('tr')) {
3063
- this.$el = $('<tr class="acf-tab-wrap"><td colspan="2"><ul class="acf-hl acf-tab-group"></ul></td></tr>');
3064
- } else {
3065
- this.$el = $('<div class="acf-tab-wrap -' + placement + '"><ul class="acf-hl acf-tab-group"></ul></div>');
3066
- } // append
3067
-
3068
-
3069
- $before.before(this.$el); // set index
3070
-
3071
- this.set('index', i, true);
3072
- i++;
3073
- },
3074
- initializeTabs: function () {
3075
- // find first visible tab
3076
- var tab = this.getVisible().shift(); // remember previous tab state
3077
-
3078
- var order = acf.getPreference('this.tabs') || [];
3079
- var groupIndex = this.get('index');
3080
- var tabIndex = order[groupIndex];
3081
-
3082
- if (this.tabs[tabIndex] && this.tabs[tabIndex].isVisible()) {
3083
- tab = this.tabs[tabIndex];
3084
- } // select
3085
-
3086
-
3087
- if (tab) {
3088
- this.selectTab(tab);
3089
- } else {
3090
- this.closeTabs();
3091
- } // set local variable used by tabsManager
3092
-
3093
-
3094
- this.set('initialized', true);
3095
- },
3096
- getVisible: function () {
3097
- return this.tabs.filter(function (tab) {
3098
- return tab.isVisible();
3099
- });
3100
- },
3101
- getActive: function () {
3102
- return this.active;
3103
- },
3104
- setActive: function (tab) {
3105
- return this.active = tab;
3106
- },
3107
- hasActive: function () {
3108
- return this.active !== false;
3109
- },
3110
- isActive: function (tab) {
3111
- var active = this.getActive();
3112
- return active && active.cid === tab.cid;
3113
- },
3114
- closeActive: function () {
3115
- if (this.hasActive()) {
3116
- this.closeTab(this.getActive());
3117
- }
3118
- },
3119
- openTab: function (tab) {
3120
- // close existing tab
3121
- this.closeActive(); // open
3122
-
3123
- tab.open(); // set active
3124
-
3125
- this.setActive(tab);
3126
- },
3127
- closeTab: function (tab) {
3128
- // close
3129
- tab.close(); // set active
3130
-
3131
- this.setActive(false);
3132
- },
3133
- closeTabs: function () {
3134
- this.tabs.map(this.closeTab, this);
3135
- },
3136
- selectTab: function (tab) {
3137
- // close other tabs
3138
- this.tabs.map(function (t) {
3139
- if (tab.cid !== t.cid) {
3140
- this.closeTab(t);
3141
- }
3142
- }, this); // open
3143
-
3144
- this.openTab(tab);
3145
- },
3146
- addTab: function ($a, field) {
3147
- // create <li>
3148
- var $li = $('<li>' + $a.outerHTML() + '</li>'); // append
3149
-
3150
- this.$('ul').append($li); // initialize
3151
-
3152
- var tab = new Tab({
3153
- $el: $li,
3154
- field: field,
3155
- group: this
3156
- }); // store
3157
-
3158
- this.tabs.push(tab); // return
3159
-
3160
- return tab;
3161
- },
3162
- reset: function () {
3163
- // close existing tab
3164
- this.closeActive(); // find and active a tab
3165
-
3166
- return this.refresh();
3167
- },
3168
- refresh: function () {
3169
- // bail early if active already exists
3170
- if (this.hasActive()) {
3171
- return false;
3172
- } // find next active tab
3173
-
3174
-
3175
- var tab = this.getVisible().shift(); // open tab
3176
-
3177
- if (tab) {
3178
- this.openTab(tab);
3179
- } // return
3180
-
3181
-
3182
- return tab;
3183
- },
3184
- onRefresh: function () {
3185
- // only for left placements
3186
- if (this.get('placement') !== 'left') {
3187
- return;
3188
- } // vars
3189
-
3190
-
3191
- var $parent = this.$el.parent();
3192
- var $list = this.$el.children('ul');
3193
- var attribute = $parent.is('td') ? 'height' : 'min-height'; // find height (minus 1 for border-bottom)
3194
-
3195
- var height = $list.position().top + $list.outerHeight(true) - 1; // add css
3196
-
3197
- $parent.css(attribute, height);
3198
- }
3199
- });
3200
- var Tab = acf.Model.extend({
3201
- group: false,
3202
- field: false,
3203
- events: {
3204
- 'click a': 'onClick'
3205
- },
3206
- index: function () {
3207
- return this.$el.index();
3208
- },
3209
- isVisible: function () {
3210
- return acf.isVisible(this.$el);
3211
- },
3212
- isActive: function () {
3213
- return this.$el.hasClass('active');
3214
- },
3215
- open: function () {
3216
- // add class
3217
- this.$el.addClass('active'); // show field
3218
-
3219
- this.field.showFields();
3220
- },
3221
- close: function () {
3222
- // remove class
3223
- this.$el.removeClass('active'); // hide field
3224
-
3225
- this.field.hideFields();
3226
- },
3227
- onClick: function (e, $el) {
3228
- // prevent default
3229
- e.preventDefault(); // toggle
3230
-
3231
- this.toggle();
3232
- },
3233
- toggle: function () {
3234
- // bail early if already active
3235
- if (this.isActive()) {
3236
- return;
3237
- } // toggle this tab
3238
-
3239
-
3240
- this.group.openTab(this);
3241
- }
3242
- });
3243
- var tabsManager = new acf.Model({
3244
- priority: 50,
3245
- actions: {
3246
- 'prepare': 'render',
3247
- 'append': 'render',
3248
- 'unload': 'onUnload',
3249
- 'invalid_field': 'onInvalidField'
3250
- },
3251
- findTabs: function () {
3252
- return $('.acf-tab-wrap');
3253
- },
3254
- getTabs: function () {
3255
- return acf.getInstances(this.findTabs());
3256
- },
3257
- render: function ($el) {
3258
- this.getTabs().map(function (tabs) {
3259
- if (!tabs.get('initialized')) {
3260
- tabs.initializeTabs();
3261
- }
3262
- });
3263
- },
3264
- onInvalidField: function (field) {
3265
- // bail early if busy
3266
- if (this.busy) {
3267
- return;
3268
- } // ignore if not hidden by tab
3269
-
3270
-
3271
- if (!field.hiddenByTab) {
3272
- return;
3273
- } // toggle tab
3274
-
3275
-
3276
- field.hiddenByTab.toggle(); // ignore other invalid fields
3277
-
3278
- this.busy = true;
3279
- this.setTimeout(function () {
3280
- this.busy = false;
3281
- }, 100);
3282
- },
3283
- onUnload: function () {
3284
- // vars
3285
- var order = []; // loop
3286
-
3287
- this.getTabs().map(function (group) {
3288
- var active = group.hasActive() ? group.getActive().index() : 0;
3289
- order.push(active);
3290
- }); // bail if no tabs
3291
-
3292
- if (!order.length) {
3293
- return;
3294
- } // update
3295
-
3296
-
3297
- acf.setPreference('this.tabs', order);
3298
- }
3299
- });
3300
- })(jQuery);
3301
-
3302
- (function ($, undefined) {
3303
- var Field = acf.models.SelectField.extend({
3304
- type: 'post_object'
3305
- });
3306
- acf.registerFieldType(Field);
3307
- })(jQuery);
3308
-
3309
- (function ($, undefined) {
3310
- var Field = acf.models.SelectField.extend({
3311
- type: 'page_link'
3312
- });
3313
- acf.registerFieldType(Field);
3314
- })(jQuery);
3315
-
3316
- (function ($, undefined) {
3317
- var Field = acf.models.SelectField.extend({
3318
- type: 'user'
3319
- });
3320
- acf.registerFieldType(Field);
3321
- })(jQuery);
3322
-
3323
- (function ($, undefined) {
3324
- var Field = acf.Field.extend({
3325
- type: 'taxonomy',
3326
- data: {
3327
- 'ftype': 'select'
3328
- },
3329
- select2: false,
3330
- wait: 'load',
3331
- events: {
3332
- 'click a[data-name="add"]': 'onClickAdd',
3333
- 'click input[type="radio"]': 'onClickRadio',
3334
- 'removeField': 'onRemove'
3335
- },
3336
- $control: function () {
3337
- return this.$('.acf-taxonomy-field');
3338
- },
3339
- $input: function () {
3340
- return this.getRelatedPrototype().$input.apply(this, arguments);
3341
- },
3342
- getRelatedType: function () {
3343
- // vars
3344
- var fieldType = this.get('ftype'); // normalize
3345
-
3346
- if (fieldType == 'multi_select') {
3347
- fieldType = 'select';
3348
- } // return
3349
-
3350
-
3351
- return fieldType;
3352
- },
3353
- getRelatedPrototype: function () {
3354
- return acf.getFieldType(this.getRelatedType()).prototype;
3355
- },
3356
- getValue: function () {
3357
- return this.getRelatedPrototype().getValue.apply(this, arguments);
3358
- },
3359
- setValue: function () {
3360
- return this.getRelatedPrototype().setValue.apply(this, arguments);
3361
- },
3362
- initialize: function () {
3363
- this.getRelatedPrototype().initialize.apply(this, arguments);
3364
- },
3365
- onRemove: function () {
3366
- var proto = this.getRelatedPrototype();
3367
-
3368
- if (proto.onRemove) {
3369
- proto.onRemove.apply(this, arguments);
3370
- }
3371
- },
3372
- onClickAdd: function (e, $el) {
3373
- // vars
3374
- var field = this;
3375
- var popup = false;
3376
- var $form = false;
3377
- var $name = false;
3378
- var $parent = false;
3379
- var $button = false;
3380
- var $message = false;
3381
- var notice = false; // step 1.
3382
-
3383
- var step1 = function () {
3384
- // popup
3385
- popup = acf.newPopup({
3386
- title: $el.attr('title'),
3387
- loading: true,
3388
- width: '300px'
3389
- }); // ajax
3390
-
3391
- var ajaxData = {
3392
- action: 'acf/fields/taxonomy/add_term',
3393
- field_key: field.get('key')
3394
- }; // get HTML
3395
-
3396
- $.ajax({
3397
- url: acf.get('ajaxurl'),
3398
- data: acf.prepareForAjax(ajaxData),
3399
- type: 'post',
3400
- dataType: 'html',
3401
- success: step2
3402
- });
3403
- }; // step 2.
3404
-
3405
-
3406
- var step2 = function (html) {
3407
- // update popup
3408
- popup.loading(false);
3409
- popup.content(html); // vars
3410
-
3411
- $form = popup.$('form');
3412
- $name = popup.$('input[name="term_name"]');
3413
- $parent = popup.$('select[name="term_parent"]');
3414
- $button = popup.$('.acf-submit-button'); // focus
3415
-
3416
- $name.trigger('focus'); // submit form
3417
-
3418
- popup.on('submit', 'form', step3);
3419
- }; // step 3.
3420
-
3421
-
3422
- var step3 = function (e, $el) {
3423
- // prevent
3424
- e.preventDefault();
3425
- e.stopImmediatePropagation(); // basic validation
3426
-
3427
- if ($name.val() === '') {
3428
- $name.trigger('focus');
3429
- return false;
3430
- } // disable
3431
-
3432
-
3433
- acf.startButtonLoading($button); // ajax
3434
-
3435
- var ajaxData = {
3436
- action: 'acf/fields/taxonomy/add_term',
3437
- field_key: field.get('key'),
3438
- term_name: $name.val(),
3439
- term_parent: $parent.length ? $parent.val() : 0
3440
- };
3441
- $.ajax({
3442
- url: acf.get('ajaxurl'),
3443
- data: acf.prepareForAjax(ajaxData),
3444
- type: 'post',
3445
- dataType: 'json',
3446
- success: step4
3447
- });
3448
- }; // step 4.
3449
-
3450
-
3451
- var step4 = function (json) {
3452
- // enable
3453
- acf.stopButtonLoading($button); // remove prev notice
3454
-
3455
- if (notice) {
3456
- notice.remove();
3457
- } // success
3458
-
3459
-
3460
- if (acf.isAjaxSuccess(json)) {
3461
- // clear name
3462
- $name.val(''); // update term lists
3463
-
3464
- step5(json.data); // notice
3465
-
3466
- notice = acf.newNotice({
3467
- type: 'success',
3468
- text: acf.getAjaxMessage(json),
3469
- target: $form,
3470
- timeout: 2000,
3471
- dismiss: false
3472
- });
3473
- } else {
3474
- // notice
3475
- notice = acf.newNotice({
3476
- type: 'error',
3477
- text: acf.getAjaxError(json),
3478
- target: $form,
3479
- timeout: 2000,
3480
- dismiss: false
3481
- });
3482
- } // focus
3483
-
3484
-
3485
- $name.trigger('focus');
3486
- }; // step 5.
3487
-
3488
-
3489
- var step5 = function (term) {
3490
- // update parent dropdown
3491
- var $option = $('<option value="' + term.term_id + '">' + term.term_label + '</option>');
3492
-
3493
- if (term.term_parent) {
3494
- $parent.children('option[value="' + term.term_parent + '"]').after($option);
3495
- } else {
3496
- $parent.append($option);
3497
- } // add this new term to all taxonomy field
3498
-
3499
-
3500
- var fields = acf.getFields({
3501
- type: 'taxonomy'
3502
- });
3503
- fields.map(function (otherField) {
3504
- if (otherField.get('taxonomy') == field.get('taxonomy')) {
3505
- otherField.appendTerm(term);
3506
- }
3507
- }); // select
3508
-
3509
- field.selectTerm(term.term_id);
3510
- }; // run
3511
-
3512
-
3513
- step1();
3514
- },
3515
- appendTerm: function (term) {
3516
- if (this.getRelatedType() == 'select') {
3517
- this.appendTermSelect(term);
3518
- } else {
3519
- this.appendTermCheckbox(term);
3520
- }
3521
- },
3522
- appendTermSelect: function (term) {
3523
- this.select2.addOption({
3524
- id: term.term_id,
3525
- text: term.term_label
3526
- });
3527
- },
3528
- appendTermCheckbox: function (term) {
3529
- // vars
3530
- var name = this.$('[name]:first').attr('name');
3531
- var $ul = this.$('ul:first'); // allow multiple selection
3532
-
3533
- if (this.getRelatedType() == 'checkbox') {
3534
- name += '[]';
3535
- } // create new li
3536
-
3537
-
3538
- 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('')); // find parent
3539
-
3540
- if (term.term_parent) {
3541
- // vars
3542
- var $parent = $ul.find('li[data-id="' + term.term_parent + '"]'); // update vars
3543
-
3544
- $ul = $parent.children('ul'); // create ul
3545
-
3546
- if (!$ul.exists()) {
3547
- $ul = $('<ul class="children acf-bl"></ul>');
3548
- $parent.append($ul);
3549
- }
3550
- } // append
3551
-
3552
-
3553
- $ul.append($li);
3554
- },
3555
- selectTerm: function (id) {
3556
- if (this.getRelatedType() == 'select') {
3557
- this.select2.selectOption(id);
3558
- } else {
3559
- var $input = this.$('input[value="' + id + '"]');
3560
- $input.prop('checked', true).trigger('change');
3561
- }
3562
- },
3563
- onClickRadio: function (e, $el) {
3564
- // vars
3565
- var $label = $el.parent('label');
3566
- var selected = $label.hasClass('selected'); // remove previous selected
3567
-
3568
- this.$('.selected').removeClass('selected'); // add active class
3569
-
3570
- $label.addClass('selected'); // allow null
3571
-
3572
- if (this.get('allow_null') && selected) {
3573
- $label.removeClass('selected');
3574
- $el.prop('checked', false).trigger('change');
3575
- }
3576
- }
3577
- });
3578
- acf.registerFieldType(Field);
3579
- })(jQuery);
3580
-
3581
- (function ($, undefined) {
3582
- var Field = acf.models.DatePickerField.extend({
3583
- type: 'time_picker',
3584
- $control: function () {
3585
- return this.$('.acf-time-picker');
3586
- },
3587
- initialize: function () {
3588
- // vars
3589
- var $input = this.$input();
3590
- var $inputText = this.$inputText(); // args
3591
-
3592
- var args = {
3593
- timeFormat: this.get('time_format'),
3594
- altField: $input,
3595
- altFieldTimeOnly: false,
3596
- altTimeFormat: 'HH:mm:ss',
3597
- showButtonPanel: true,
3598
- controlType: 'select',
3599
- oneLine: true,
3600
- closeText: acf.get('dateTimePickerL10n').selectText,
3601
- timeOnly: true
3602
- }; // add custom 'Close = Select' functionality
3603
-
3604
- args.onClose = function (value, dp_instance, t_instance) {
3605
- // vars
3606
- var $close = dp_instance.dpDiv.find('.ui-datepicker-close'); // if clicking close button
3607
-
3608
- if (!value && $close.is(':hover')) {
3609
- t_instance._updateDateTime();
3610
- }
3611
- }; // filter
3612
-
3613
-
3614
- args = acf.applyFilters('time_picker_args', args, this); // add date time picker
3615
-
3616
- acf.newTimePicker($inputText, args); // action
3617
-
3618
- acf.doAction('time_picker_init', $inputText, args, this);
3619
- }
3620
- });
3621
- acf.registerFieldType(Field); // add
3622
-
3623
- acf.newTimePicker = function ($input, args) {
3624
- // bail ealry if no datepicker library
3625
- if (typeof $.timepicker === 'undefined') {
3626
- return false;
3627
- } // defaults
3628
-
3629
-
3630
- args = args || {}; // initialize
3631
-
3632
- $input.timepicker(args); // wrap the datepicker (only if it hasn't already been wrapped)
3633
-
3634
- if ($('body > #ui-datepicker-div').exists()) {
3635
- $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
3636
- }
3637
- };
3638
- })(jQuery);
3639
-
3640
- (function ($, undefined) {
3641
- var Field = acf.Field.extend({
3642
- type: 'true_false',
3643
- events: {
3644
- 'change .acf-switch-input': 'onChange',
3645
- 'focus .acf-switch-input': 'onFocus',
3646
- 'blur .acf-switch-input': 'onBlur',
3647
- 'keypress .acf-switch-input': 'onKeypress'
3648
- },
3649
- $input: function () {
3650
- return this.$('input[type="checkbox"]');
3651
- },
3652
- $switch: function () {
3653
- return this.$('.acf-switch');
3654
- },
3655
- getValue: function () {
3656
- return this.$input().prop('checked') ? 1 : 0;
3657
- },
3658
- initialize: function () {
3659
- this.render();
3660
- },
3661
- render: function () {
3662
- // vars
3663
- var $switch = this.$switch(); // bail ealry if no $switch
3664
-
3665
- if (!$switch.length) return; // vars
3666
-
3667
- var $on = $switch.children('.acf-switch-on');
3668
- var $off = $switch.children('.acf-switch-off');
3669
- var width = Math.max($on.width(), $off.width()); // bail ealry if no width
3670
-
3671
- if (!width) return; // set widths
3672
-
3673
- $on.css('min-width', width);
3674
- $off.css('min-width', width);
3675
- },
3676
- switchOn: function () {
3677
- this.$input().prop('checked', true);
3678
- this.$switch().addClass('-on');
3679
- },
3680
- switchOff: function () {
3681
- this.$input().prop('checked', false);
3682
- this.$switch().removeClass('-on');
3683
- },
3684
- onChange: function (e, $el) {
3685
- if ($el.prop('checked')) {
3686
- this.switchOn();
3687
- } else {
3688
- this.switchOff();
3689
- }
3690
- },
3691
- onFocus: function (e, $el) {
3692
- this.$switch().addClass('-focus');
3693
- },
3694
- onBlur: function (e, $el) {
3695
- this.$switch().removeClass('-focus');
3696
- },
3697
- onKeypress: function (e, $el) {
3698
- // left
3699
- if (e.keyCode === 37) {
3700
- return this.switchOff();
3701
- } // right
3702
-
3703
-
3704
- if (e.keyCode === 39) {
3705
- return this.switchOn();
3706
- }
3707
- }
3708
- });
3709
- acf.registerFieldType(Field);
3710
- })(jQuery);
3711
-
3712
- (function ($, undefined) {
3713
- var Field = acf.Field.extend({
3714
- type: 'url',
3715
- events: {
3716
- 'keyup input[type="url"]': 'onkeyup'
3717
- },
3718
- $control: function () {
3719
- return this.$('.acf-input-wrap');
3720
- },
3721
- $input: function () {
3722
- return this.$('input[type="url"]');
3723
- },
3724
- initialize: function () {
3725
- this.render();
3726
- },
3727
- isValid: function () {
3728
- // vars
3729
- var val = this.val(); // bail early if no val
3730
-
3731
- if (!val) {
3732
- return false;
3733
- } // url
3734
-
3735
-
3736
- if (val.indexOf('://') !== -1) {
3737
- return true;
3738
- } // protocol relative url
3739
-
3740
-
3741
- if (val.indexOf('//') === 0) {
3742
- return true;
3743
- } // return
3744
-
3745
-
3746
- return false;
3747
- },
3748
- render: function () {
3749
- // add class
3750
- if (this.isValid()) {
3751
- this.$control().addClass('-valid');
3752
- } else {
3753
- this.$control().removeClass('-valid');
3754
- }
3755
- },
3756
- onkeyup: function (e, $el) {
3757
- this.render();
3758
- }
3759
- });
3760
- acf.registerFieldType(Field);
3761
- })(jQuery);
3762
-
3763
- (function ($, undefined) {
3764
- var Field = acf.Field.extend({
3765
- type: 'wysiwyg',
3766
- wait: 'load',
3767
- events: {
3768
- 'mousedown .acf-editor-wrap.delay': 'onMousedown',
3769
- 'unmountField': 'disableEditor',
3770
- 'remountField': 'enableEditor',
3771
- 'removeField': 'disableEditor'
3772
- },
3773
- $control: function () {
3774
- return this.$('.acf-editor-wrap');
3775
- },
3776
- $input: function () {
3777
- return this.$('textarea');
3778
- },
3779
- getMode: function () {
3780
- return this.$control().hasClass('tmce-active') ? 'visual' : 'text';
3781
- },
3782
- initialize: function () {
3783
- // initializeEditor if no delay
3784
- if (!this.$control().hasClass('delay')) {
3785
- this.initializeEditor();
3786
- }
3787
- },
3788
- initializeEditor: function () {
3789
- // vars
3790
- var $wrap = this.$control();
3791
- var $textarea = this.$input();
3792
- var args = {
3793
- tinymce: true,
3794
- quicktags: true,
3795
- toolbar: this.get('toolbar'),
3796
- mode: this.getMode(),
3797
- field: this
3798
- }; // generate new id
3799
-
3800
- var oldId = $textarea.attr('id');
3801
- var newId = acf.uniqueId('acf-editor-'); // Backup textarea data.
3802
-
3803
- var inputData = $textarea.data();
3804
- var inputVal = $textarea.val(); // rename
3805
-
3806
- acf.rename({
3807
- target: $wrap,
3808
- search: oldId,
3809
- replace: newId,
3810
- destructive: true
3811
- }); // update id
3812
-
3813
- this.set('id', newId, true); // apply data to new textarea (acf.rename creates a new textarea element due to destructive mode)
3814
- // fixes bug where conditional logic "disabled" is lost during "screen_check"
3815
-
3816
- this.$input().data(inputData).val(inputVal); // initialize
3817
-
3818
- acf.tinymce.initialize(newId, args);
3819
- },
3820
- onMousedown: function (e) {
3821
- // prevent default
3822
- e.preventDefault(); // remove delay class
3823
-
3824
- var $wrap = this.$control();
3825
- $wrap.removeClass('delay');
3826
- $wrap.find('.acf-editor-toolbar').remove(); // initialize
3827
-
3828
- this.initializeEditor();
3829
- },
3830
- enableEditor: function () {
3831
- if (this.getMode() == 'visual') {
3832
- acf.tinymce.enable(this.get('id'));
3833
- }
3834
- },
3835
- disableEditor: function () {
3836
- acf.tinymce.destroy(this.get('id'));
3837
- }
3838
- });
3839
- acf.registerFieldType(Field);
3840
- })(jQuery);
3841
-
3842
- (function ($, undefined) {
3843
- // vars
3844
- var storage = [];
3845
- /**
3846
- * acf.Condition
3847
- *
3848
- * description
3849
- *
3850
- * @date 23/3/18
3851
- * @since 5.6.9
3852
- *
3853
- * @param type $var Description. Default.
3854
- * @return type Description.
3855
- */
3856
-
3857
- acf.Condition = acf.Model.extend({
3858
- type: '',
3859
- // used for model name
3860
- operator: '==',
3861
- // rule operator
3862
- label: '',
3863
- // label shown when editing fields
3864
- choiceType: 'input',
3865
- // input, select
3866
- fieldTypes: [],
3867
- // auto connect this conditions with these field types
3868
- data: {
3869
- conditions: false,
3870
- // the parent instance
3871
- field: false,
3872
- // the field which we query against
3873
- rule: {} // the rule [field, operator, value]
3874
-
3875
- },
3876
- events: {
3877
- 'change': 'change',
3878
- 'keyup': 'change',
3879
- 'enableField': 'change',
3880
- 'disableField': 'change'
3881
- },
3882
- setup: function (props) {
3883
- $.extend(this.data, props);
3884
- },
3885
- getEventTarget: function ($el, event) {
3886
- return $el || this.get('field').$el;
3887
- },
3888
- change: function (e, $el) {
3889
- this.get('conditions').change(e);
3890
- },
3891
- match: function (rule, field) {
3892
- return false;
3893
- },
3894
- calculate: function () {
3895
- return this.match(this.get('rule'), this.get('field'));
3896
- },
3897
- choices: function (field) {
3898
- return '<input type="text" />';
3899
- }
3900
- });
3901
- /**
3902
- * acf.newCondition
3903
- *
3904
- * description
3905
- *
3906
- * @date 1/2/18
3907
- * @since 5.6.5
3908
- *
3909
- * @param type $var Description. Default.
3910
- * @return type Description.
3911
- */
3912
-
3913
- acf.newCondition = function (rule, conditions) {
3914
- // currently setting up conditions for fieldX, this field is the 'target'
3915
- var target = conditions.get('field'); // use the 'target' to find the 'trigger' field.
3916
- // - this field is used to setup the conditional logic events
3917
-
3918
- var field = target.getField(rule.field); // bail ealry if no target or no field (possible if field doesn't exist due to HTML error)
3919
-
3920
- if (!target || !field) {
3921
- return false;
3922
- } // vars
3923
-
3924
-
3925
- var args = {
3926
- rule: rule,
3927
- target: target,
3928
- conditions: conditions,
3929
- field: field
3930
- }; // vars
3931
-
3932
- var fieldType = field.get('type');
3933
- var operator = rule.operator; // get avaibale conditions
3934
-
3935
- var conditionTypes = acf.getConditionTypes({
3936
- fieldType: fieldType,
3937
- operator: operator
3938
- }); // instantiate
3939
-
3940
- var model = conditionTypes[0] || acf.Condition; // instantiate
3941
-
3942
- var condition = new model(args); // return
3943
-
3944
- return condition;
3945
- };
3946
- /**
3947
- * mid
3948
- *
3949
- * Calculates the model ID for a field type
3950
- *
3951
- * @date 15/12/17
3952
- * @since 5.6.5
3953
- *
3954
- * @param string type
3955
- * @return string
3956
- */
3957
-
3958
-
3959
- var modelId = function (type) {
3960
- return acf.strPascalCase(type || '') + 'Condition';
3961
- };
3962
- /**
3963
- * acf.registerConditionType
3964
- *
3965
- * description
3966
- *
3967
- * @date 1/2/18
3968
- * @since 5.6.5
3969
- *
3970
- * @param type $var Description. Default.
3971
- * @return type Description.
3972
- */
3973
-
3974
-
3975
- acf.registerConditionType = function (model) {
3976
- // vars
3977
- var proto = model.prototype;
3978
- var type = proto.type;
3979
- var mid = modelId(type); // store model
3980
-
3981
- acf.models[mid] = model; // store reference
3982
-
3983
- storage.push(type);
3984
- };
3985
- /**
3986
- * acf.getConditionType
3987
- *
3988
- * description
3989
- *
3990
- * @date 1/2/18
3991
- * @since 5.6.5
3992
- *
3993
- * @param type $var Description. Default.
3994
- * @return type Description.
3995
- */
3996
-
3997
-
3998
- acf.getConditionType = function (type) {
3999
- var mid = modelId(type);
4000
- return acf.models[mid] || false;
4001
- };
4002
- /**
4003
- * acf.registerConditionForFieldType
4004
- *
4005
- * description
4006
- *
4007
- * @date 1/2/18
4008
- * @since 5.6.5
4009
- *
4010
- * @param type $var Description. Default.
4011
- * @return type Description.
4012
- */
4013
-
4014
-
4015
- acf.registerConditionForFieldType = function (conditionType, fieldType) {
4016
- // get model
4017
- var model = acf.getConditionType(conditionType); // append
4018
-
4019
- if (model) {
4020
- model.prototype.fieldTypes.push(fieldType);
4021
- }
4022
- };
4023
- /**
4024
- * acf.getConditionTypes
4025
- *
4026
- * description
4027
- *
4028
- * @date 1/2/18
4029
- * @since 5.6.5
4030
- *
4031
- * @param type $var Description. Default.
4032
- * @return type Description.
4033
- */
4034
-
4035
-
4036
- acf.getConditionTypes = function (args) {
4037
- // defaults
4038
- args = acf.parseArgs(args, {
4039
- fieldType: '',
4040
- operator: ''
4041
- }); // clonse available types
4042
-
4043
- var types = []; // loop
4044
-
4045
- storage.map(function (type) {
4046
- // vars
4047
- var model = acf.getConditionType(type);
4048
- var ProtoFieldTypes = model.prototype.fieldTypes;
4049
- var ProtoOperator = model.prototype.operator; // check fieldType
4050
-
4051
- if (args.fieldType && ProtoFieldTypes.indexOf(args.fieldType) === -1) {
4052
- return;
4053
- } // check operator
4054
-
4055
-
4056
- if (args.operator && ProtoOperator !== args.operator) {
4057
- return;
4058
- } // append
4059
-
4060
-
4061
- types.push(model);
4062
- }); // return
4063
-
4064
- return types;
4065
- };
4066
- })(jQuery);
4067
-
4068
- (function ($, undefined) {
4069
- // vars
4070
- var CONTEXT = 'conditional_logic';
4071
- /**
4072
- * conditionsManager
4073
- *
4074
- * description
4075
- *
4076
- * @date 1/2/18
4077
- * @since 5.6.5
4078
- *
4079
- * @param type $var Description. Default.
4080
- * @return type Description.
4081
- */
4082
-
4083
- var conditionsManager = new acf.Model({
4084
- id: 'conditionsManager',
4085
- priority: 20,
4086
- // run actions later
4087
- actions: {
4088
- 'new_field': 'onNewField'
4089
- },
4090
- onNewField: function (field) {
4091
- if (field.has('conditions')) {
4092
- field.getConditions().render();
4093
- }
4094
- }
4095
- });
4096
- /**
4097
- * acf.Field.prototype.getField
4098
- *
4099
- * Finds a field that is related to another field
4100
- *
4101
- * @date 1/2/18
4102
- * @since 5.6.5
4103
- *
4104
- * @param type $var Description. Default.
4105
- * @return type Description.
4106
- */
4107
-
4108
- var getSiblingField = function (field, key) {
4109
- // find sibling (very fast)
4110
- var fields = acf.getFields({
4111
- key: key,
4112
- sibling: field.$el,
4113
- suppressFilters: true
4114
- }); // find sibling-children (fast)
4115
- // needed for group fields, accordions, etc
4116
-
4117
- if (!fields.length) {
4118
- fields = acf.getFields({
4119
- key: key,
4120
- parent: field.$el.parent(),
4121
- suppressFilters: true
4122
- });
4123
- } // return
4124
-
4125
-
4126
- if (fields.length) {
4127
- return fields[0];
4128
- }
4129
-
4130
- return false;
4131
- };
4132
-
4133
- acf.Field.prototype.getField = function (key) {
4134
- // get sibling field
4135
- var field = getSiblingField(this, key); // return early
4136
-
4137
- if (field) {
4138
- return field;
4139
- } // move up through each parent and try again
4140
-
4141
-
4142
- var parents = this.parents();
4143
-
4144
- for (var i = 0; i < parents.length; i++) {
4145
- // get sibling field
4146
- field = getSiblingField(parents[i], key); // return early
4147
-
4148
- if (field) {
4149
- return field;
4150
- }
4151
- } // return
4152
-
4153
-
4154
- return false;
4155
- };
4156
- /**
4157
- * acf.Field.prototype.getConditions
4158
- *
4159
- * Returns the field's conditions instance
4160
- *
4161
- * @date 1/2/18
4162
- * @since 5.6.5
4163
- *
4164
- * @param type $var Description. Default.
4165
- * @return type Description.
4166
- */
4167
-
4168
-
4169
- acf.Field.prototype.getConditions = function () {
4170
- // instantiate
4171
- if (!this.conditions) {
4172
- this.conditions = new Conditions(this);
4173
- } // return
4174
-
4175
-
4176
- return this.conditions;
4177
- };
4178
- /**
4179
- * Conditions
4180
- *
4181
- * description
4182
- *
4183
- * @date 1/2/18
4184
- * @since 5.6.5
4185
- *
4186
- * @param type $var Description. Default.
4187
- * @return type Description.
4188
- */
4189
-
4190
-
4191
- var timeout = false;
4192
- var Conditions = acf.Model.extend({
4193
- id: 'Conditions',
4194
- data: {
4195
- field: false,
4196
- // The field with "data-conditions" (target).
4197
- timeStamp: false,
4198
- // Reference used during "change" event.
4199
- groups: [] // The groups of condition instances.
4200
-
4201
- },
4202
- setup: function (field) {
4203
- // data
4204
- this.data.field = field; // vars
4205
-
4206
- var conditions = field.get('conditions'); // detect groups
4207
-
4208
- if (conditions instanceof Array) {
4209
- // detect groups
4210
- if (conditions[0] instanceof Array) {
4211
- // loop
4212
- conditions.map(function (rules, i) {
4213
- this.addRules(rules, i);
4214
- }, this); // detect rules
4215
- } else {
4216
- this.addRules(conditions);
4217
- } // detect rule
4218
-
4219
- } else {
4220
- this.addRule(conditions);
4221
- }
4222
- },
4223
- change: function (e) {
4224
- // this function may be triggered multiple times per event due to multiple condition classes
4225
- // compare timestamp to allow only 1 trigger per event
4226
- if (this.get('timeStamp') === e.timeStamp) {
4227
- return false;
4228
- } else {
4229
- this.set('timeStamp', e.timeStamp, true);
4230
- } // render condition and store result
4231
-
4232
-
4233
- var changed = this.render();
4234
- },
4235
- render: function () {
4236
- return this.calculate() ? this.show() : this.hide();
4237
- },
4238
- show: function () {
4239
- return this.get('field').showEnable(this.cid, CONTEXT);
4240
- },
4241
- hide: function () {
4242
- return this.get('field').hideDisable(this.cid, CONTEXT);
4243
- },
4244
- calculate: function () {
4245
- // vars
4246
- var pass = false; // loop
4247
-
4248
- this.getGroups().map(function (group) {
4249
- // igrnore this group if another group passed
4250
- if (pass) return; // find passed
4251
-
4252
- var passed = group.filter(function (condition) {
4253
- return condition.calculate();
4254
- }); // if all conditions passed, update the global var
4255
-
4256
- if (passed.length == group.length) {
4257
- pass = true;
4258
- }
4259
- });
4260
- return pass;
4261
- },
4262
- hasGroups: function () {
4263
- return this.data.groups != null;
4264
- },
4265
- getGroups: function () {
4266
- return this.data.groups;
4267
- },
4268
- addGroup: function () {
4269
- var group = [];
4270
- this.data.groups.push(group);
4271
- return group;
4272
- },
4273
- hasGroup: function (i) {
4274
- return this.data.groups[i] != null;
4275
- },
4276
- getGroup: function (i) {
4277
- return this.data.groups[i];
4278
- },
4279
- removeGroup: function (i) {
4280
- this.data.groups[i].delete;
4281
- return this;
4282
- },
4283
- addRules: function (rules, group) {
4284
- rules.map(function (rule) {
4285
- this.addRule(rule, group);
4286
- }, this);
4287
- },
4288
- addRule: function (rule, group) {
4289
- // defaults
4290
- group = group || 0; // vars
4291
-
4292
- var groupArray; // get group
4293
-
4294
- if (this.hasGroup(group)) {
4295
- groupArray = this.getGroup(group);
4296
- } else {
4297
- groupArray = this.addGroup();
4298
- } // instantiate
4299
-
4300
-
4301
- var condition = acf.newCondition(rule, this); // bail ealry if condition failed (field did not exist)
4302
-
4303
- if (!condition) {
4304
- return false;
4305
- } // add rule
4306
-
4307
-
4308
- groupArray.push(condition);
4309
- },
4310
- hasRule: function () {},
4311
- getRule: function (rule, group) {
4312
- // defaults
4313
- rule = rule || 0;
4314
- group = group || 0;
4315
- return this.data.groups[group][rule];
4316
- },
4317
- removeRule: function () {}
4318
- });
4319
- })(jQuery);
4320
-
4321
- (function ($, undefined) {
4322
- var __ = acf.__;
4323
-
4324
- var parseString = function (val) {
4325
- return val ? '' + val : '';
4326
- };
4327
-
4328
- var isEqualTo = function (v1, v2) {
4329
- return parseString(v1).toLowerCase() === parseString(v2).toLowerCase();
4330
- };
4331
-
4332
- var isEqualToNumber = function (v1, v2) {
4333
- return parseFloat(v1) === parseFloat(v2);
4334
- };
4335
-
4336
- var isGreaterThan = function (v1, v2) {
4337
- return parseFloat(v1) > parseFloat(v2);
4338
- };
4339
-
4340
- var isLessThan = function (v1, v2) {
4341
- return parseFloat(v1) < parseFloat(v2);
4342
- };
4343
-
4344
- var inArray = function (v1, array) {
4345
- // cast all values as string
4346
- array = array.map(function (v2) {
4347
- return parseString(v2);
4348
- });
4349
- return array.indexOf(v1) > -1;
4350
- };
4351
-
4352
- var containsString = function (haystack, needle) {
4353
- return parseString(haystack).indexOf(parseString(needle)) > -1;
4354
- };
4355
-
4356
- var matchesPattern = function (v1, pattern) {
4357
- var regexp = new RegExp(parseString(pattern), 'gi');
4358
- return parseString(v1).match(regexp);
4359
- };
4360
- /**
4361
- * hasValue
4362
- *
4363
- * description
4364
- *
4365
- * @date 1/2/18
4366
- * @since 5.6.5
4367
- *
4368
- * @param void
4369
- * @return void
4370
- */
4371
-
4372
-
4373
- var HasValue = acf.Condition.extend({
4374
- type: 'hasValue',
4375
- operator: '!=empty',
4376
- label: __('Has any value'),
4377
- fieldTypes: ['text', 'textarea', 'number', 'range', 'email', 'url', 'password', 'image', 'file', 'wysiwyg', 'oembed', 'select', 'checkbox', 'radio', 'button_group', 'link', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user', 'google_map', 'date_picker', 'date_time_picker', 'time_picker', 'color_picker'],
4378
- match: function (rule, field) {
4379
- return field.val() ? true : false;
4380
- },
4381
- choices: function (fieldObject) {
4382
- return '<input type="text" disabled="" />';
4383
- }
4384
- });
4385
- acf.registerConditionType(HasValue);
4386
- /**
4387
- * hasValue
4388
- *
4389
- * description
4390
- *
4391
- * @date 1/2/18
4392
- * @since 5.6.5
4393
- *
4394
- * @param void
4395
- * @return void
4396
- */
4397
-
4398
- var HasNoValue = HasValue.extend({
4399
- type: 'hasNoValue',
4400
- operator: '==empty',
4401
- label: __('Has no value'),
4402
- match: function (rule, field) {
4403
- return !HasValue.prototype.match.apply(this, arguments);
4404
- }
4405
- });
4406
- acf.registerConditionType(HasNoValue);
4407
- /**
4408
- * EqualTo
4409
- *
4410
- * description
4411
- *
4412
- * @date 1/2/18
4413
- * @since 5.6.5
4414
- *
4415
- * @param void
4416
- * @return void
4417
- */
4418
-
4419
- var EqualTo = acf.Condition.extend({
4420
- type: 'equalTo',
4421
- operator: '==',
4422
- label: __('Value is equal to'),
4423
- fieldTypes: ['text', 'textarea', 'number', 'range', 'email', 'url', 'password'],
4424
- match: function (rule, field) {
4425
- if (acf.isNumeric(rule.value)) {
4426
- return isEqualToNumber(rule.value, field.val());
4427
- } else {
4428
- return isEqualTo(rule.value, field.val());
4429
- }
4430
- },
4431
- choices: function (fieldObject) {
4432
- return '<input type="text" />';
4433
- }
4434
- });
4435
- acf.registerConditionType(EqualTo);
4436
- /**
4437
- * NotEqualTo
4438
- *
4439
- * description
4440
- *
4441
- * @date 1/2/18
4442
- * @since 5.6.5
4443
- *
4444
- * @param void
4445
- * @return void
4446
- */
4447
-
4448
- var NotEqualTo = EqualTo.extend({
4449
- type: 'notEqualTo',
4450
- operator: '!=',
4451
- label: __('Value is not equal to'),
4452
- match: function (rule, field) {
4453
- return !EqualTo.prototype.match.apply(this, arguments);
4454
- }
4455
- });
4456
- acf.registerConditionType(NotEqualTo);
4457
- /**
4458
- * PatternMatch
4459
- *
4460
- * description
4461
- *
4462
- * @date 1/2/18
4463
- * @since 5.6.5
4464
- *
4465
- * @param void
4466
- * @return void
4467
- */
4468
-
4469
- var PatternMatch = acf.Condition.extend({
4470
- type: 'patternMatch',
4471
- operator: '==pattern',
4472
- label: __('Value matches pattern'),
4473
- fieldTypes: ['text', 'textarea', 'email', 'url', 'password', 'wysiwyg'],
4474
- match: function (rule, field) {
4475
- return matchesPattern(field.val(), rule.value);
4476
- },
4477
- choices: function (fieldObject) {
4478
- return '<input type="text" placeholder="[a-z0-9]" />';
4479
- }
4480
- });
4481
- acf.registerConditionType(PatternMatch);
4482
- /**
4483
- * Contains
4484
- *
4485
- * description
4486
- *
4487
- * @date 1/2/18
4488
- * @since 5.6.5
4489
- *
4490
- * @param void
4491
- * @return void
4492
- */
4493
-
4494
- var Contains = acf.Condition.extend({
4495
- type: 'contains',
4496
- operator: '==contains',
4497
- label: __('Value contains'),
4498
- fieldTypes: ['text', 'textarea', 'number', 'email', 'url', 'password', 'wysiwyg', 'oembed', 'select'],
4499
- match: function (rule, field) {
4500
- return containsString(field.val(), rule.value);
4501
- },
4502
- choices: function (fieldObject) {
4503
- return '<input type="text" />';
4504
- }
4505
- });
4506
- acf.registerConditionType(Contains);
4507
- /**
4508
- * TrueFalseEqualTo
4509
- *
4510
- * description
4511
- *
4512
- * @date 1/2/18
4513
- * @since 5.6.5
4514
- *
4515
- * @param void
4516
- * @return void
4517
- */
4518
-
4519
- var TrueFalseEqualTo = EqualTo.extend({
4520
- type: 'trueFalseEqualTo',
4521
- choiceType: 'select',
4522
- fieldTypes: ['true_false'],
4523
- choices: function (field) {
4524
- return [{
4525
- id: 1,
4526
- text: __('Checked')
4527
- }];
4528
- }
4529
- });
4530
- acf.registerConditionType(TrueFalseEqualTo);
4531
- /**
4532
- * TrueFalseNotEqualTo
4533
- *
4534
- * description
4535
- *
4536
- * @date 1/2/18
4537
- * @since 5.6.5
4538
- *
4539
- * @param void
4540
- * @return void
4541
- */
4542
-
4543
- var TrueFalseNotEqualTo = NotEqualTo.extend({
4544
- type: 'trueFalseNotEqualTo',
4545
- choiceType: 'select',
4546
- fieldTypes: ['true_false'],
4547
- choices: function (field) {
4548
- return [{
4549
- id: 1,
4550
- text: __('Checked')
4551
- }];
4552
- }
4553
- });
4554
- acf.registerConditionType(TrueFalseNotEqualTo);
4555
- /**
4556
- * SelectEqualTo
4557
- *
4558
- * description
4559
- *
4560
- * @date 1/2/18
4561
- * @since 5.6.5
4562
- *
4563
- * @param void
4564
- * @return void
4565
- */
4566
-
4567
- var SelectEqualTo = acf.Condition.extend({
4568
- type: 'selectEqualTo',
4569
- operator: '==',
4570
- label: __('Value is equal to'),
4571
- fieldTypes: ['select', 'checkbox', 'radio', 'button_group'],
4572
- match: function (rule, field) {
4573
- var val = field.val();
4574
-
4575
- if (val instanceof Array) {
4576
- return inArray(rule.value, val);
4577
- } else {
4578
- return isEqualTo(rule.value, val);
4579
- }
4580
- },
4581
- choices: function (fieldObject) {
4582
- // vars
4583
- var choices = [];
4584
- var lines = fieldObject.$setting('choices textarea').val().split("\n"); // allow null
4585
-
4586
- if (fieldObject.$input('allow_null').prop('checked')) {
4587
- choices.push({
4588
- id: '',
4589
- text: __('Null')
4590
- });
4591
- } // loop
4592
-
4593
-
4594
- lines.map(function (line) {
4595
- // split
4596
- line = line.split(':'); // default label to value
4597
-
4598
- line[1] = line[1] || line[0]; // append
4599
-
4600
- choices.push({
4601
- id: line[0].trim(),
4602
- text: line[1].trim()
4603
- });
4604
- }); // return
4605
-
4606
- return choices;
4607
- }
4608
- });
4609
- acf.registerConditionType(SelectEqualTo);
4610
- /**
4611
- * SelectNotEqualTo
4612
- *
4613
- * description
4614
- *
4615
- * @date 1/2/18
4616
- * @since 5.6.5
4617
- *
4618
- * @param void
4619
- * @return void
4620
- */
4621
-
4622
- var SelectNotEqualTo = SelectEqualTo.extend({
4623
- type: 'selectNotEqualTo',
4624
- operator: '!=',
4625
- label: __('Value is not equal to'),
4626
- match: function (rule, field) {
4627
- return !SelectEqualTo.prototype.match.apply(this, arguments);
4628
- }
4629
- });
4630
- acf.registerConditionType(SelectNotEqualTo);
4631
- /**
4632
- * GreaterThan
4633
- *
4634
- * description
4635
- *
4636
- * @date 1/2/18
4637
- * @since 5.6.5
4638
- *
4639
- * @param void
4640
- * @return void
4641
- */
4642
-
4643
- var GreaterThan = acf.Condition.extend({
4644
- type: 'greaterThan',
4645
- operator: '>',
4646
- label: __('Value is greater than'),
4647
- fieldTypes: ['number', 'range'],
4648
- match: function (rule, field) {
4649
- var val = field.val();
4650
-
4651
- if (val instanceof Array) {
4652
- val = val.length;
4653
- }
4654
-
4655
- return isGreaterThan(val, rule.value);
4656
- },
4657
- choices: function (fieldObject) {
4658
- return '<input type="number" />';
4659
- }
4660
- });
4661
- acf.registerConditionType(GreaterThan);
4662
- /**
4663
- * LessThan
4664
- *
4665
- * description
4666
- *
4667
- * @date 1/2/18
4668
- * @since 5.6.5
4669
- *
4670
- * @param void
4671
- * @return void
4672
- */
4673
-
4674
- var LessThan = GreaterThan.extend({
4675
- type: 'lessThan',
4676
- operator: '<',
4677
- label: __('Value is less than'),
4678
- match: function (rule, field) {
4679
- var val = field.val();
4680
-
4681
- if (val instanceof Array) {
4682
- val = val.length;
4683
- }
4684
-
4685
- return isLessThan(val, rule.value);
4686
- },
4687
- choices: function (fieldObject) {
4688
- return '<input type="number" />';
4689
- }
4690
- });
4691
- acf.registerConditionType(LessThan);
4692
- /**
4693
- * SelectedGreaterThan
4694
- *
4695
- * description
4696
- *
4697
- * @date 1/2/18
4698
- * @since 5.6.5
4699
- *
4700
- * @param void
4701
- * @return void
4702
- */
4703
-
4704
- var SelectionGreaterThan = GreaterThan.extend({
4705
- type: 'selectionGreaterThan',
4706
- label: __('Selection is greater than'),
4707
- fieldTypes: ['checkbox', 'select', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user']
4708
- });
4709
- acf.registerConditionType(SelectionGreaterThan);
4710
- /**
4711
- * SelectedGreaterThan
4712
- *
4713
- * description
4714
- *
4715
- * @date 1/2/18
4716
- * @since 5.6.5
4717
- *
4718
- * @param void
4719
- * @return void
4720
- */
4721
-
4722
- var SelectionLessThan = LessThan.extend({
4723
- type: 'selectionLessThan',
4724
- label: __('Selection is less than'),
4725
- fieldTypes: ['checkbox', 'select', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user']
4726
- });
4727
- acf.registerConditionType(SelectionLessThan);
4728
- })(jQuery);
4729
-
4730
- (function ($, undefined) {
4731
- acf.unload = new acf.Model({
4732
- wait: 'load',
4733
- active: true,
4734
- changed: false,
4735
- actions: {
4736
- 'validation_failure': 'startListening',
4737
- 'validation_success': 'stopListening'
4738
- },
4739
- events: {
4740
- 'change form .acf-field': 'startListening',
4741
- 'submit form': 'stopListening'
4742
- },
4743
- enable: function () {
4744
- this.active = true;
4745
- },
4746
- disable: function () {
4747
- this.active = false;
4748
- },
4749
- reset: function () {
4750
- this.stopListening();
4751
- },
4752
- startListening: function () {
4753
- // bail ealry if already changed, not active
4754
- if (this.changed || !this.active) {
4755
- return;
4756
- } // update
4757
-
4758
-
4759
- this.changed = true; // add event
4760
-
4761
- $(window).on('beforeunload', this.onUnload);
4762
- },
4763
- stopListening: function () {
4764
- // update
4765
- this.changed = false; // remove event
4766
-
4767
- $(window).off('beforeunload', this.onUnload);
4768
- },
4769
- onUnload: function () {
4770
- return acf.__('The changes you made will be lost if you navigate away from this page');
4771
- }
4772
- });
4773
- })(jQuery);
4774
-
4775
- (function ($, undefined) {
4776
- /**
4777
- * postboxManager
4778
- *
4779
- * Manages postboxes on the screen.
4780
- *
4781
- * @date 25/5/19
4782
- * @since 5.8.1
4783
- *
4784
- * @param void
4785
- * @return void
4786
- */
4787
- var postboxManager = new acf.Model({
4788
- wait: 'prepare',
4789
- priority: 1,
4790
- initialize: function () {
4791
- (acf.get('postboxes') || []).map(acf.newPostbox);
4792
- }
4793
- });
4794
- /**
4795
- * acf.getPostbox
4796
- *
4797
- * Returns a postbox instance.
4798
- *
4799
- * @date 23/9/18
4800
- * @since 5.7.7
4801
- *
4802
- * @param mixed $el Either a jQuery element or the postbox id.
4803
- * @return object
4804
- */
4805
-
4806
- acf.getPostbox = function ($el) {
4807
- // allow string parameter
4808
- if (typeof arguments[0] == 'string') {
4809
- $el = $('#' + arguments[0]);
4810
- } // return instance
4811
-
4812
-
4813
- return acf.getInstance($el);
4814
- };
4815
- /**
4816
- * acf.getPostboxes
4817
- *
4818
- * Returns an array of postbox instances.
4819
- *
4820
- * @date 23/9/18
4821
- * @since 5.7.7
4822
- *
4823
- * @param void
4824
- * @return array
4825
- */
4826
-
4827
-
4828
- acf.getPostboxes = function () {
4829
- return acf.getInstances($('.acf-postbox'));
4830
- };
4831
- /**
4832
- * acf.newPostbox
4833
- *
4834
- * Returns a new postbox instance for the given props.
4835
- *
4836
- * @date 20/9/18
4837
- * @since 5.7.6
4838
- *
4839
- * @param object props The postbox properties.
4840
- * @return object
4841
- */
4842
-
4843
-
4844
- acf.newPostbox = function (props) {
4845
- return new acf.models.Postbox(props);
4846
- };
4847
- /**
4848
- * acf.models.Postbox
4849
- *
4850
- * The postbox model.
4851
- *
4852
- * @date 20/9/18
4853
- * @since 5.7.6
4854
- *
4855
- * @param void
4856
- * @return void
4857
- */
4858
-
4859
-
4860
- acf.models.Postbox = acf.Model.extend({
4861
- data: {
4862
- id: '',
4863
- key: '',
4864
- style: 'default',
4865
- label: 'top',
4866
- edit: ''
4867
- },
4868
- setup: function (props) {
4869
- // compatibilty
4870
- if (props.editLink) {
4871
- props.edit = props.editLink;
4872
- } // extend data
4873
-
4874
-
4875
- $.extend(this.data, props); // set $el
4876
-
4877
- this.$el = this.$postbox();
4878
- },
4879
- $postbox: function () {
4880
- return $('#' + this.get('id'));
4881
- },
4882
- $hide: function () {
4883
- return $('#' + this.get('id') + '-hide');
4884
- },
4885
- $hideLabel: function () {
4886
- return this.$hide().parent();
4887
- },
4888
- $hndle: function () {
4889
- return this.$('> .hndle');
4890
- },
4891
- $handleActions: function () {
4892
- return this.$('> .postbox-header .handle-actions');
4893
- },
4894
- $inside: function () {
4895
- return this.$('> .inside');
4896
- },
4897
- isVisible: function () {
4898
- return this.$el.hasClass('acf-hidden');
4899
- },
4900
- initialize: function () {
4901
- // Add default class.
4902
- this.$el.addClass('acf-postbox'); // Remove 'hide-if-js class.
4903
- // This class is added by WP to postboxes that are hidden via the "Screen Options" tab.
4904
-
4905
- this.$el.removeClass('hide-if-js'); // Add field group style class (ignore in block editor).
4906
-
4907
- if (acf.get('editor') !== 'block') {
4908
- var style = this.get('style');
4909
-
4910
- if (style !== 'default') {
4911
- this.$el.addClass(style);
4912
- }
4913
- } // Add .inside class.
4914
-
4915
-
4916
- this.$inside().addClass('acf-fields').addClass('-' + this.get('label')); // Append edit link.
4917
-
4918
- var edit = this.get('edit');
4919
-
4920
- if (edit) {
4921
- var html = '<a href="' + edit + '" class="dashicons dashicons-admin-generic acf-hndle-cog acf-js-tooltip" title="' + acf.__('Edit field group') + '"></a>';
4922
- var $handleActions = this.$handleActions();
4923
-
4924
- if ($handleActions.length) {
4925
- $handleActions.prepend(html);
4926
- } else {
4927
- this.$hndle().append(html);
4928
- }
4929
- } // Show postbox.
4930
-
4931
-
4932
- this.show();
4933
- },
4934
- show: function () {
4935
- // Show label.
4936
- this.$hideLabel().show(); // toggle on checkbox
4937
-
4938
- this.$hide().prop('checked', true); // Show postbox
4939
-
4940
- this.$el.show().removeClass('acf-hidden'); // Do action.
4941
-
4942
- acf.doAction('show_postbox', this);
4943
- },
4944
- enable: function () {
4945
- acf.enable(this.$el, 'postbox');
4946
- },
4947
- showEnable: function () {
4948
- this.enable();
4949
- this.show();
4950
- },
4951
- hide: function () {
4952
- // Hide label.
4953
- this.$hideLabel().hide(); // Hide postbox
4954
-
4955
- this.$el.hide().addClass('acf-hidden'); // Do action.
4956
-
4957
- acf.doAction('hide_postbox', this);
4958
- },
4959
- disable: function () {
4960
- acf.disable(this.$el, 'postbox');
4961
- },
4962
- hideDisable: function () {
4963
- this.disable();
4964
- this.hide();
4965
- },
4966
- html: function (html) {
4967
- // Update HTML.
4968
- this.$inside().html(html); // Do action.
4969
-
4970
- acf.doAction('append', this.$el);
4971
- }
4972
- });
4973
- })(jQuery);
4974
-
4975
- (function ($, undefined) {
4976
- /**
4977
- * acf.newMediaPopup
4978
- *
4979
- * description
4980
- *
4981
- * @date 10/1/18
4982
- * @since 5.6.5
4983
- *
4984
- * @param type $var Description. Default.
4985
- * @return type Description.
4986
- */
4987
- acf.newMediaPopup = function (args) {
4988
- // args
4989
- var popup = null;
4990
- var args = acf.parseArgs(args, {
4991
- mode: 'select',
4992
- // 'select', 'edit'
4993
- title: '',
4994
- // 'Upload Image'
4995
- button: '',
4996
- // 'Select Image'
4997
- type: '',
4998
- // 'image', ''
4999
- field: false,
5000
- // field instance
5001
- allowedTypes: '',
5002
- // '.jpg, .png, etc'
5003
- library: 'all',
5004
- // 'all', 'uploadedTo'
5005
- multiple: false,
5006
- // false, true, 'add'
5007
- attachment: 0,
5008
- // the attachment to edit
5009
- autoOpen: true,
5010
- // open the popup automatically
5011
- open: function () {},
5012
- // callback after close
5013
- select: function () {},
5014
- // callback after select
5015
- close: function () {} // callback after close
5016
-
5017
- }); // initialize
5018
-
5019
- if (args.mode == 'edit') {
5020
- popup = new acf.models.EditMediaPopup(args);
5021
- } else {
5022
- popup = new acf.models.SelectMediaPopup(args);
5023
- } // open popup (allow frame customization before opening)
5024
-
5025
-
5026
- if (args.autoOpen) {
5027
- setTimeout(function () {
5028
- popup.open();
5029
- }, 1);
5030
- } // action
5031
-
5032
-
5033
- acf.doAction('new_media_popup', popup); // return
5034
-
5035
- return popup;
5036
- };
5037
- /**
5038
- * getPostID
5039
- *
5040
- * description
5041
- *
5042
- * @date 10/1/18
5043
- * @since 5.6.5
5044
- *
5045
- * @param type $var Description. Default.
5046
- * @return type Description.
5047
- */
5048
-
5049
-
5050
- var getPostID = function () {
5051
- var postID = acf.get('post_id');
5052
- return acf.isNumeric(postID) ? postID : 0;
5053
- };
5054
- /**
5055
- * acf.getMimeTypes
5056
- *
5057
- * description
5058
- *
5059
- * @date 11/1/18
5060
- * @since 5.6.5
5061
- *
5062
- * @param type $var Description. Default.
5063
- * @return type Description.
5064
- */
5065
-
5066
-
5067
- acf.getMimeTypes = function () {
5068
- return this.get('mimeTypes');
5069
- };
5070
-
5071
- acf.getMimeType = function (name) {
5072
- // vars
5073
- var allTypes = acf.getMimeTypes(); // search
5074
-
5075
- if (allTypes[name] !== undefined) {
5076
- return allTypes[name];
5077
- } // some types contain a mixed key such as "jpg|jpeg|jpe"
5078
-
5079
-
5080
- for (var key in allTypes) {
5081
- if (key.indexOf(name) !== -1) {
5082
- return allTypes[key];
5083
- }
5084
- } // return
5085
-
5086
-
5087
- return false;
5088
- };
5089
- /**
5090
- * MediaPopup
5091
- *
5092
- * description
5093
- *
5094
- * @date 10/1/18
5095
- * @since 5.6.5
5096
- *
5097
- * @param type $var Description. Default.
5098
- * @return type Description.
5099
- */
5100
-
5101
-
5102
- var MediaPopup = acf.Model.extend({
5103
- id: 'MediaPopup',
5104
- data: {},
5105
- defaults: {},
5106
- frame: false,
5107
- setup: function (props) {
5108
- $.extend(this.data, props);
5109
- },
5110
- initialize: function () {
5111
- // vars
5112
- var options = this.getFrameOptions(); // add states
5113
-
5114
- this.addFrameStates(options); // create frame
5115
-
5116
- var frame = wp.media(options); // add args reference
5117
-
5118
- frame.acf = this; // add events
5119
-
5120
- this.addFrameEvents(frame, options); // strore frame
5121
-
5122
- this.frame = frame;
5123
- },
5124
- open: function () {
5125
- this.frame.open();
5126
- },
5127
- close: function () {
5128
- this.frame.close();
5129
- },
5130
- remove: function () {
5131
- this.frame.detach();
5132
- this.frame.remove();
5133
- },
5134
- getFrameOptions: function () {
5135
- // vars
5136
- var options = {
5137
- title: this.get('title'),
5138
- multiple: this.get('multiple'),
5139
- library: {},
5140
- states: []
5141
- }; // type
5142
-
5143
- if (this.get('type')) {
5144
- options.library.type = this.get('type');
5145
- } // type
5146
-
5147
-
5148
- if (this.get('library') === 'uploadedTo') {
5149
- options.library.uploadedTo = getPostID();
5150
- } // attachment
5151
-
5152
-
5153
- if (this.get('attachment')) {
5154
- options.library.post__in = [this.get('attachment')];
5155
- } // button
5156
-
5157
-
5158
- if (this.get('button')) {
5159
- options.button = {
5160
- text: this.get('button')
5161
- };
5162
- } // return
5163
-
5164
-
5165
- return options;
5166
- },
5167
- addFrameStates: function (options) {
5168
- // create query
5169
- var Query = wp.media.query(options.library); // add _acfuploader
5170
- // this is super wack!
5171
- // if you add _acfuploader to the options.library args, new uploads will not be added to the library view.
5172
- // this has been traced back to the wp.media.model.Query initialize function (which can't be overriden)
5173
- // Adding any custom args will cause the Attahcments to not observe the uploader queue
5174
- // To bypass this security issue, we add in the args AFTER the Query has been initialized
5175
- // options.library._acfuploader = settings.field;
5176
-
5177
- if (this.get('field') && acf.isset(Query, 'mirroring', 'args')) {
5178
- Query.mirroring.args._acfuploader = this.get('field');
5179
- } // add states
5180
-
5181
-
5182
- options.states.push( // main state
5183
- new wp.media.controller.Library({
5184
- library: Query,
5185
- multiple: this.get('multiple'),
5186
- title: this.get('title'),
5187
- priority: 20,
5188
- filterable: 'all',
5189
- editable: true,
5190
- allowLocalEdits: true
5191
- })); // edit image functionality (added in WP 3.9)
5192
-
5193
- if (acf.isset(wp, 'media', 'controller', 'EditImage')) {
5194
- options.states.push(new wp.media.controller.EditImage());
5195
- }
5196
- },
5197
- addFrameEvents: function (frame, options) {
5198
- // log all events
5199
- //frame.on('all', function( e ) {
5200
- // console.log( 'frame all: %o', e );
5201
- //});
5202
- // add class
5203
- frame.on('open', function () {
5204
- this.$el.closest('.media-modal').addClass('acf-media-modal -' + this.acf.get('mode'));
5205
- }, frame); // edit image view
5206
- // source: media-views.js:2410 editImageContent()
5207
-
5208
- frame.on('content:render:edit-image', function () {
5209
- var image = this.state().get('image');
5210
- var view = new wp.media.view.EditImage({
5211
- model: image,
5212
- controller: this
5213
- }).render();
5214
- this.content.set(view); // after creating the wrapper view, load the actual editor via an ajax call
5215
-
5216
- view.loadEditor();
5217
- }, frame); // update toolbar button
5218
- //frame.on( 'toolbar:create:select', function( toolbar ) {
5219
- // toolbar.view = new wp.media.view.Toolbar.Select({
5220
- // text: frame.options._button,
5221
- // controller: this
5222
- // });
5223
- //}, frame );
5224
- // on select
5225
-
5226
- frame.on('select', function () {
5227
- // vars
5228
- var selection = frame.state().get('selection'); // if selecting images
5229
-
5230
- if (selection) {
5231
- // loop
5232
- selection.each(function (attachment, i) {
5233
- frame.acf.get('select').apply(frame.acf, [attachment, i]);
5234
- });
5235
- }
5236
- }); // on close
5237
-
5238
- frame.on('close', function () {
5239
- // callback and remove
5240
- setTimeout(function () {
5241
- frame.acf.get('close').apply(frame.acf);
5242
- frame.acf.remove();
5243
- }, 1);
5244
- });
5245
- }
5246
- });
5247
- /**
5248
- * acf.models.SelectMediaPopup
5249
- *
5250
- * description
5251
- *
5252
- * @date 10/1/18
5253
- * @since 5.6.5
5254
- *
5255
- * @param type $var Description. Default.
5256
- * @return type Description.
5257
- */
5258
-
5259
- acf.models.SelectMediaPopup = MediaPopup.extend({
5260
- id: 'SelectMediaPopup',
5261
- setup: function (props) {
5262
- // default button
5263
- if (!props.button) {
5264
- props.button = acf._x('Select', 'verb');
5265
- } // parent
5266
-
5267
-
5268
- MediaPopup.prototype.setup.apply(this, arguments);
5269
- },
5270
- addFrameEvents: function (frame, options) {
5271
- // plupload
5272
- // adds _acfuploader param to validate uploads
5273
- if (acf.isset(_wpPluploadSettings, 'defaults', 'multipart_params')) {
5274
- // add _acfuploader so that Uploader will inherit
5275
- _wpPluploadSettings.defaults.multipart_params._acfuploader = this.get('field'); // remove acf_field so future Uploaders won't inherit
5276
-
5277
- frame.on('open', function () {
5278
- delete _wpPluploadSettings.defaults.multipart_params._acfuploader;
5279
- });
5280
- } // browse
5281
-
5282
-
5283
- frame.on('content:activate:browse', function () {
5284
- // vars
5285
- var toolbar = false; // populate above vars making sure to allow for failure
5286
- // perhaps toolbar does not exist because the frame open is Upload Files
5287
-
5288
- try {
5289
- toolbar = frame.content.get().toolbar;
5290
- } catch (e) {
5291
- console.log(e);
5292
- return;
5293
- } // callback
5294
-
5295
-
5296
- frame.acf.customizeFilters.apply(frame.acf, [toolbar]);
5297
- }); // parent
5298
-
5299
- MediaPopup.prototype.addFrameEvents.apply(this, arguments);
5300
- },
5301
- customizeFilters: function (toolbar) {
5302
- // vars
5303
- var filters = toolbar.get('filters'); // image
5304
-
5305
- if (this.get('type') == 'image') {
5306
- // update all
5307
- filters.filters.all.text = acf.__('All images'); // remove some filters
5308
-
5309
- delete filters.filters.audio;
5310
- delete filters.filters.video;
5311
- delete filters.filters.image; // update all filters to show images
5312
-
5313
- $.each(filters.filters, function (i, filter) {
5314
- filter.props.type = filter.props.type || 'image';
5315
- });
5316
- } // specific types
5317
-
5318
-
5319
- if (this.get('allowedTypes')) {
5320
- // convert ".jpg, .png" into ["jpg", "png"]
5321
- var allowedTypes = this.get('allowedTypes').split(' ').join('').split('.').join('').split(','); // loop
5322
-
5323
- allowedTypes.map(function (name) {
5324
- // get type
5325
- var mimeType = acf.getMimeType(name); // bail early if no type
5326
-
5327
- if (!mimeType) return; // create new filter
5328
-
5329
- var newFilter = {
5330
- text: mimeType,
5331
- props: {
5332
- status: null,
5333
- type: mimeType,
5334
- uploadedTo: null,
5335
- orderby: 'date',
5336
- order: 'DESC'
5337
- },
5338
- priority: 20
5339
- }; // append
5340
-
5341
- filters.filters[mimeType] = newFilter;
5342
- });
5343
- } // uploaded to post
5344
-
5345
-
5346
- if (this.get('library') === 'uploadedTo') {
5347
- // vars
5348
- var uploadedTo = this.frame.options.library.uploadedTo; // remove some filters
5349
-
5350
- delete filters.filters.unattached;
5351
- delete filters.filters.uploaded; // add uploadedTo to filters
5352
-
5353
- $.each(filters.filters, function (i, filter) {
5354
- filter.text += ' (' + acf.__('Uploaded to this post') + ')';
5355
- filter.props.uploadedTo = uploadedTo;
5356
- });
5357
- } // add _acfuploader to filters
5358
-
5359
-
5360
- var field = this.get('field');
5361
- $.each(filters.filters, function (k, filter) {
5362
- filter.props._acfuploader = field;
5363
- }); // add _acfuplaoder to search
5364
-
5365
- var search = toolbar.get('search');
5366
- search.model.attributes._acfuploader = field; // render (custom function added to prototype)
5367
-
5368
- if (filters.renderFilters) {
5369
- filters.renderFilters();
5370
- }
5371
- }
5372
- });
5373
- /**
5374
- * acf.models.EditMediaPopup
5375
- *
5376
- * description
5377
- *
5378
- * @date 10/1/18
5379
- * @since 5.6.5
5380
- *
5381
- * @param type $var Description. Default.
5382
- * @return type Description.
5383
- */
5384
-
5385
- acf.models.EditMediaPopup = MediaPopup.extend({
5386
- id: 'SelectMediaPopup',
5387
- setup: function (props) {
5388
- // default button
5389
- if (!props.button) {
5390
- props.button = acf._x('Update', 'verb');
5391
- } // parent
5392
-
5393
-
5394
- MediaPopup.prototype.setup.apply(this, arguments);
5395
- },
5396
- addFrameEvents: function (frame, options) {
5397
- // add class
5398
- frame.on('open', function () {
5399
- // add class
5400
- this.$el.closest('.media-modal').addClass('acf-expanded'); // set to browse
5401
-
5402
- if (this.content.mode() != 'browse') {
5403
- this.content.mode('browse');
5404
- } // set selection
5405
-
5406
-
5407
- var state = this.state();
5408
- var selection = state.get('selection');
5409
- var attachment = wp.media.attachment(frame.acf.get('attachment'));
5410
- selection.add(attachment);
5411
- }, frame); // parent
5412
-
5413
- MediaPopup.prototype.addFrameEvents.apply(this, arguments);
5414
- }
5415
- });
5416
- /**
5417
- * customizePrototypes
5418
- *
5419
- * description
5420
- *
5421
- * @date 11/1/18
5422
- * @since 5.6.5
5423
- *
5424
- * @param type $var Description. Default.
5425
- * @return type Description.
5426
- */
5427
-
5428
- var customizePrototypes = new acf.Model({
5429
- id: 'customizePrototypes',
5430
- wait: 'ready',
5431
- initialize: function () {
5432
- // bail early if no media views
5433
- if (!acf.isset(window, 'wp', 'media', 'view')) {
5434
- return;
5435
- } // fix bug where CPT without "editor" does not set post.id setting which then prevents uploadedTo from working
5436
-
5437
-
5438
- var postID = getPostID();
5439
-
5440
- if (postID && acf.isset(wp, 'media', 'view', 'settings', 'post')) {
5441
- wp.media.view.settings.post.id = postID;
5442
- } // customize
5443
-
5444
-
5445
- this.customizeAttachmentsButton();
5446
- this.customizeAttachmentsRouter();
5447
- this.customizeAttachmentFilters();
5448
- this.customizeAttachmentCompat();
5449
- this.customizeAttachmentLibrary();
5450
- },
5451
- customizeAttachmentsButton: function () {
5452
- // validate
5453
- if (!acf.isset(wp, 'media', 'view', 'Button')) {
5454
- return;
5455
- } // Extend
5456
-
5457
-
5458
- var Button = wp.media.view.Button;
5459
- wp.media.view.Button = Button.extend({
5460
- // Fix bug where "Select" button appears blank after editing an image.
5461
- // Do this by simplifying Button initialize function and avoid deleting this.options.
5462
- initialize: function () {
5463
- var options = _.defaults(this.options, this.defaults);
5464
-
5465
- this.model = new Backbone.Model(options);
5466
- this.listenTo(this.model, 'change', this.render);
5467
- }
5468
- });
5469
- },
5470
- customizeAttachmentsRouter: function () {
5471
- // validate
5472
- if (!acf.isset(wp, 'media', 'view', 'Router')) {
5473
- return;
5474
- } // vars
5475
-
5476
-
5477
- var Parent = wp.media.view.Router; // extend
5478
-
5479
- wp.media.view.Router = Parent.extend({
5480
- addExpand: function () {
5481
- // vars
5482
- 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('')); // add events
5483
-
5484
- $a.on('click', function (e) {
5485
- e.preventDefault();
5486
- var $div = $(this).closest('.media-modal');
5487
-
5488
- if ($div.hasClass('acf-expanded')) {
5489
- $div.removeClass('acf-expanded');
5490
- } else {
5491
- $div.addClass('acf-expanded');
5492
- }
5493
- }); // append
5494
-
5495
- this.$el.append($a);
5496
- },
5497
- initialize: function () {
5498
- // initialize
5499
- Parent.prototype.initialize.apply(this, arguments); // add buttons
5500
-
5501
- this.addExpand(); // return
5502
-
5503
- return this;
5504
- }
5505
- });
5506
- },
5507
- customizeAttachmentFilters: function () {
5508
- // validate
5509
- if (!acf.isset(wp, 'media', 'view', 'AttachmentFilters', 'All')) {
5510
- return;
5511
- } // vars
5512
-
5513
-
5514
- var Parent = wp.media.view.AttachmentFilters.All; // renderFilters
5515
- // copied from media-views.js:6939
5516
-
5517
- Parent.prototype.renderFilters = function () {
5518
- // Build `<option>` elements.
5519
- this.$el.html(_.chain(this.filters).map(function (filter, value) {
5520
- return {
5521
- el: $('<option></option>').val(value).html(filter.text)[0],
5522
- priority: filter.priority || 50
5523
- };
5524
- }, this).sortBy('priority').pluck('el').value());
5525
- };
5526
- },
5527
- customizeAttachmentCompat: function () {
5528
- // validate
5529
- if (!acf.isset(wp, 'media', 'view', 'AttachmentCompat')) {
5530
- return;
5531
- } // vars
5532
-
5533
-
5534
- var AttachmentCompat = wp.media.view.AttachmentCompat;
5535
- var timeout = false; // extend
5536
-
5537
- wp.media.view.AttachmentCompat = AttachmentCompat.extend({
5538
- render: function () {
5539
- // WP bug
5540
- // When multiple media frames exist on the same page (WP content, WYSIWYG, image, file ),
5541
- // WP creates multiple instances of this AttachmentCompat view.
5542
- // Each instance will attempt to render when a new modal is created.
5543
- // Use a property to avoid this and only render once per instance.
5544
- if (this.rendered) {
5545
- return this;
5546
- } // render HTML
5547
-
5548
-
5549
- AttachmentCompat.prototype.render.apply(this, arguments); // when uploading, render is called twice.
5550
- // ignore first render by checking for #acf-form-data element
5551
-
5552
- if (!this.$('#acf-form-data').length) {
5553
- return this;
5554
- } // clear timeout
5555
-
5556
-
5557
- clearTimeout(timeout); // setTimeout
5558
-
5559
- timeout = setTimeout($.proxy(function () {
5560
- this.rendered = true;
5561
- acf.doAction('append', this.$el);
5562
- }, this), 50); // return
5563
-
5564
- return this;
5565
- },
5566
- save: function (event) {
5567
- var data = {};
5568
-
5569
- if (event) {
5570
- event.preventDefault();
5571
- } //_.each( this.$el.serializeArray(), function( pair ) {
5572
- // data[ pair.name ] = pair.value;
5573
- //});
5574
- // Serialize data more thoroughly to allow chckbox inputs to save.
5575
-
5576
-
5577
- data = acf.serializeForAjax(this.$el);
5578
- this.controller.trigger('attachment:compat:waiting', ['waiting']);
5579
- this.model.saveCompat(data).always(_.bind(this.postSave, this));
5580
- }
5581
- });
5582
- },
5583
- customizeAttachmentLibrary: function () {
5584
- // validate
5585
- if (!acf.isset(wp, 'media', 'view', 'Attachment', 'Library')) {
5586
- return;
5587
- } // vars
5588
-
5589
-
5590
- var AttachmentLibrary = wp.media.view.Attachment.Library; // extend
5591
-
5592
- wp.media.view.Attachment.Library = AttachmentLibrary.extend({
5593
- render: function () {
5594
- // vars
5595
- var popup = acf.isget(this, 'controller', 'acf');
5596
- var attributes = acf.isget(this, 'model', 'attributes'); // check vars exist to avoid errors
5597
-
5598
- if (popup && attributes) {
5599
- // show errors
5600
- if (attributes.acf_errors) {
5601
- this.$el.addClass('acf-disabled');
5602
- } // disable selected
5603
-
5604
-
5605
- var selected = popup.get('selected');
5606
-
5607
- if (selected && selected.indexOf(attributes.id) > -1) {
5608
- this.$el.addClass('acf-selected');
5609
- }
5610
- } // render
5611
-
5612
-
5613
- return AttachmentLibrary.prototype.render.apply(this, arguments);
5614
- },
5615
-
5616
- /*
5617
- * toggleSelection
5618
- *
5619
- * This function is called before an attachment is selected
5620
- * A good place to check for errors and prevent the 'select' function from being fired
5621
- *
5622
- * @type function
5623
- * @date 29/09/2016
5624
- * @since 5.4.0
5625
- *
5626
- * @param options (object)
5627
- * @return n/a
5628
- */
5629
- toggleSelection: function (options) {
5630
- // vars
5631
- // source: wp-includes/js/media-views.js:2880
5632
- var collection = this.collection,
5633
- selection = this.options.selection,
5634
- model = this.model,
5635
- single = selection.single(); // vars
5636
-
5637
- var frame = this.controller;
5638
- var errors = acf.isget(this, 'model', 'attributes', 'acf_errors');
5639
- var $sidebar = frame.$el.find('.media-frame-content .media-sidebar'); // remove previous error
5640
-
5641
- $sidebar.children('.acf-selection-error').remove(); // show attachment details
5642
-
5643
- $sidebar.children().removeClass('acf-hidden'); // add message
5644
-
5645
- if (frame && errors) {
5646
- // vars
5647
- var filename = acf.isget(this, 'model', 'attributes', 'filename'); // hide attachment details
5648
- // Gallery field continues to show previously selected attachment...
5649
-
5650
- $sidebar.children().addClass('acf-hidden'); // append message
5651
-
5652
- $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('')); // reset selection (unselects all attachments)
5653
-
5654
- selection.reset(); // set single (attachment displayed in sidebar)
5655
-
5656
- selection.single(model); // return and prevent 'select' form being fired
5657
-
5658
- return;
5659
- } // return
5660
-
5661
-
5662
- return AttachmentLibrary.prototype.toggleSelection.apply(this, arguments);
5663
- }
5664
- });
5665
- }
5666
- });
5667
- })(jQuery);
5668
-
5669
- (function ($, undefined) {
5670
- acf.screen = new acf.Model({
5671
- active: true,
5672
- xhr: false,
5673
- timeout: false,
5674
- wait: 'load',
5675
- events: {
5676
- 'change #page_template': 'onChange',
5677
- 'change #parent_id': 'onChange',
5678
- 'change #post-formats-select': 'onChange',
5679
- 'change .categorychecklist': 'onChange',
5680
- 'change .tagsdiv': 'onChange',
5681
- 'change .acf-taxonomy-field[data-save="1"]': 'onChange',
5682
- 'change #product-type': 'onChange'
5683
- },
5684
- isPost: function () {
5685
- return acf.get('screen') === 'post';
5686
- },
5687
- isUser: function () {
5688
- return acf.get('screen') === 'user';
5689
- },
5690
- isTaxonomy: function () {
5691
- return acf.get('screen') === 'taxonomy';
5692
- },
5693
- isAttachment: function () {
5694
- return acf.get('screen') === 'attachment';
5695
- },
5696
- isNavMenu: function () {
5697
- return acf.get('screen') === 'nav_menu';
5698
- },
5699
- isWidget: function () {
5700
- return acf.get('screen') === 'widget';
5701
- },
5702
- isComment: function () {
5703
- return acf.get('screen') === 'comment';
5704
- },
5705
- getPageTemplate: function () {
5706
- var $el = $('#page_template');
5707
- return $el.length ? $el.val() : null;
5708
- },
5709
- getPageParent: function (e, $el) {
5710
- var $el = $('#parent_id');
5711
- return $el.length ? $el.val() : null;
5712
- },
5713
- getPageType: function (e, $el) {
5714
- return this.getPageParent() ? 'child' : 'parent';
5715
- },
5716
- getPostType: function () {
5717
- return $('#post_type').val();
5718
- },
5719
- getPostFormat: function (e, $el) {
5720
- var $el = $('#post-formats-select input:checked');
5721
-
5722
- if ($el.length) {
5723
- var val = $el.val();
5724
- return val == '0' ? 'standard' : val;
5725
- }
5726
-
5727
- return null;
5728
- },
5729
- getPostCoreTerms: function () {
5730
- // vars
5731
- var terms = {}; // serialize WP taxonomy postboxes
5732
-
5733
- var data = acf.serialize($('.categorydiv, .tagsdiv')); // use tax_input (tag, custom-taxonomy) when possible.
5734
- // this data is already formatted in taxonomy => [terms].
5735
-
5736
- if (data.tax_input) {
5737
- terms = data.tax_input;
5738
- } // append "category" which uses a different name
5739
-
5740
-
5741
- if (data.post_category) {
5742
- terms.category = data.post_category;
5743
- } // convert any string values (tags) into array format
5744
-
5745
-
5746
- for (var tax in terms) {
5747
- if (!acf.isArray(terms[tax])) {
5748
- terms[tax] = terms[tax].split(/,[\s]?/);
5749
- }
5750
- } // return
5751
-
5752
-
5753
- return terms;
5754
- },
5755
- getPostTerms: function () {
5756
- // Get core terms.
5757
- var terms = this.getPostCoreTerms(); // loop over taxonomy fields and add their values
5758
-
5759
- acf.getFields({
5760
- type: 'taxonomy'
5761
- }).map(function (field) {
5762
- // ignore fields that don't save
5763
- if (!field.get('save')) {
5764
- return;
5765
- } // vars
5766
-
5767
-
5768
- var val = field.val();
5769
- var tax = field.get('taxonomy'); // check val
5770
-
5771
- if (val) {
5772
- // ensure terms exists
5773
- terms[tax] = terms[tax] || []; // ensure val is an array
5774
-
5775
- val = acf.isArray(val) ? val : [val]; // append
5776
-
5777
- terms[tax] = terms[tax].concat(val);
5778
- }
5779
- }); // add WC product type
5780
-
5781
- if ((productType = this.getProductType()) !== null) {
5782
- terms.product_type = [productType];
5783
- } // remove duplicate values
5784
-
5785
-
5786
- for (var tax in terms) {
5787
- terms[tax] = acf.uniqueArray(terms[tax]);
5788
- } // return
5789
-
5790
-
5791
- return terms;
5792
- },
5793
- getProductType: function () {
5794
- var $el = $('#product-type');
5795
- return $el.length ? $el.val() : null;
5796
- },
5797
- check: function () {
5798
- // bail early if not for post
5799
- if (acf.get('screen') !== 'post') {
5800
- return;
5801
- } // abort XHR if is already loading AJAX data
5802
-
5803
-
5804
- if (this.xhr) {
5805
- this.xhr.abort();
5806
- } // vars
5807
-
5808
-
5809
- var ajaxData = acf.parseArgs(this.data, {
5810
- action: 'acf/ajax/check_screen',
5811
- screen: acf.get('screen'),
5812
- exists: []
5813
- }); // post id
5814
-
5815
- if (this.isPost()) {
5816
- ajaxData.post_id = acf.get('post_id');
5817
- } // post type
5818
-
5819
-
5820
- if ((postType = this.getPostType()) !== null) {
5821
- ajaxData.post_type = postType;
5822
- } // page template
5823
-
5824
-
5825
- if ((pageTemplate = this.getPageTemplate()) !== null) {
5826
- ajaxData.page_template = pageTemplate;
5827
- } // page parent
5828
-
5829
-
5830
- if ((pageParent = this.getPageParent()) !== null) {
5831
- ajaxData.page_parent = pageParent;
5832
- } // page type
5833
-
5834
-
5835
- if ((pageType = this.getPageType()) !== null) {
5836
- ajaxData.page_type = pageType;
5837
- } // post format
5838
-
5839
-
5840
- if ((postFormat = this.getPostFormat()) !== null) {
5841
- ajaxData.post_format = postFormat;
5842
- } // post terms
5843
-
5844
-
5845
- if ((postTerms = this.getPostTerms()) !== null) {
5846
- ajaxData.post_terms = postTerms;
5847
- } // add array of existing postboxes to increase performance and reduce JSON HTML
5848
-
5849
-
5850
- acf.getPostboxes().map(function (postbox) {
5851
- ajaxData.exists.push(postbox.get('key'));
5852
- }); // filter
5853
-
5854
- ajaxData = acf.applyFilters('check_screen_args', ajaxData); // success
5855
-
5856
- var onSuccess = function (json) {
5857
- // Render post screen.
5858
- if (acf.get('screen') == 'post') {
5859
- this.renderPostScreen(json); // Render user screen.
5860
- } else if (acf.get('screen') == 'user') {
5861
- this.renderUserScreen(json);
5862
- } // action
5863
-
5864
-
5865
- acf.doAction('check_screen_complete', json, ajaxData);
5866
- }; // ajax
5867
-
5868
-
5869
- this.xhr = $.ajax({
5870
- url: acf.get('ajaxurl'),
5871
- data: acf.prepareForAjax(ajaxData),
5872
- type: 'post',
5873
- dataType: 'json',
5874
- context: this,
5875
- success: onSuccess
5876
- });
5877
- },
5878
- onChange: function (e, $el) {
5879
- this.setTimeout(this.check, 1);
5880
- },
5881
- renderPostScreen: function (data) {
5882
- // Helper function to copy events
5883
- var copyEvents = function ($from, $to) {
5884
- var events = $._data($from[0]).events;
5885
-
5886
- for (var type in events) {
5887
- for (var i = 0; i < events[type].length; i++) {
5888
- $to.on(type, events[type][i].handler);
5889
- }
5890
- }
5891
- }; // Helper function to sort metabox.
5892
-
5893
-
5894
- var sortMetabox = function (id, ids) {
5895
- // Find position of id within ids.
5896
- var index = ids.indexOf(id); // Bail early if index not found.
5897
-
5898
- if (index == -1) {
5899
- return false;
5900
- } // Loop over metaboxes behind (in reverse order).
5901
-
5902
-
5903
- for (var i = index - 1; i >= 0; i--) {
5904
- if ($('#' + ids[i]).length) {
5905
- return $('#' + ids[i]).after($('#' + id));
5906
- }
5907
- } // Loop over metaboxes infront.
5908
-
5909
-
5910
- for (var i = index + 1; i < ids.length; i++) {
5911
- if ($('#' + ids[i]).length) {
5912
- return $('#' + ids[i]).before($('#' + id));
5913
- }
5914
- } // Return false if not sorted.
5915
-
5916
-
5917
- return false;
5918
- }; // Keep track of visible and hidden postboxes.
5919
-
5920
-
5921
- data.visible = [];
5922
- data.hidden = []; // Show these postboxes.
5923
-
5924
- data.results = data.results.map(function (result, i) {
5925
- // vars
5926
- var postbox = acf.getPostbox(result.id); // Prevent "acf_after_title" position in Block Editor.
5927
-
5928
- if (acf.isGutenberg() && result.position == "acf_after_title") {
5929
- result.position = 'normal';
5930
- } // Create postbox if doesn't exist.
5931
-
5932
-
5933
- if (!postbox) {
5934
- var wpMinorVersion = parseFloat(acf.get('wp_version'));
5935
-
5936
- if (wpMinorVersion >= 5.5) {
5937
- 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('');
5938
- } else {
5939
- 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('');
5940
- } // Create it.
5941
-
5942
-
5943
- var $postbox = $(['<div id="' + result.id + '" class="postbox">', postboxHeader, '<div class="inside">', result.html, '</div>', '</div>'].join('')); // Create new hide toggle.
5944
-
5945
- if ($('#adv-settings').length) {
5946
- var $prefs = $('#adv-settings .metabox-prefs');
5947
- 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('')); // Copy default WP events onto checkbox.
5948
-
5949
- copyEvents($prefs.find('input').first(), $label.find('input')); // Append hide label
5950
-
5951
- $prefs.append($label);
5952
- } // Copy default WP events onto metabox.
5953
-
5954
-
5955
- if ($('.postbox').length) {
5956
- copyEvents($('.postbox .handlediv').first(), $postbox.children('.handlediv'));
5957
- copyEvents($('.postbox .hndle').first(), $postbox.children('.hndle'));
5958
- } // Append metabox to the bottom of "side-sortables".
5959
-
5960
-
5961
- if (result.position === 'side') {
5962
- $('#' + result.position + '-sortables').append($postbox); // Prepend metabox to the top of "normal-sortbables".
5963
- } else {
5964
- $('#' + result.position + '-sortables').prepend($postbox);
5965
- } // Position metabox amongst existing ACF metaboxes within the same location.
5966
-
5967
-
5968
- var order = [];
5969
- data.results.map(function (_result) {
5970
- if (result.position === _result.position && $('#' + result.position + '-sortables #' + _result.id).length) {
5971
- order.push(_result.id);
5972
- }
5973
- });
5974
- sortMetabox(result.id, order); // Check 'sorted' for user preference.
5975
-
5976
- if (data.sorted) {
5977
- // Loop over each position (acf_after_title, side, normal).
5978
- for (var position in data.sorted) {
5979
- // Explode string into array of ids.
5980
- var order = data.sorted[position].split(','); // Position metabox relative to order.
5981
-
5982
- if (sortMetabox(result.id, order)) {
5983
- break;
5984
- }
5985
- }
5986
- } // Initalize it (modifies HTML).
5987
-
5988
-
5989
- postbox = acf.newPostbox(result); // Trigger action.
5990
-
5991
- acf.doAction('append', $postbox);
5992
- acf.doAction('append_postbox', postbox);
5993
- } // show postbox
5994
-
5995
-
5996
- postbox.showEnable(); // append
5997
-
5998
- data.visible.push(result.id); // Return result (may have changed).
5999
-
6000
- return result;
6001
- }); // Hide these postboxes.
6002
-
6003
- acf.getPostboxes().map(function (postbox) {
6004
- if (data.visible.indexOf(postbox.get('id')) === -1) {
6005
- // Hide postbox.
6006
- postbox.hideDisable(); // Append to data.
6007
-
6008
- data.hidden.push(postbox.get('id'));
6009
- }
6010
- }); // Update style.
6011
-
6012
- $('#acf-style').html(data.style); // Do action.
6013
-
6014
- acf.doAction('refresh_post_screen', data);
6015
- },
6016
- renderUserScreen: function (json) {}
6017
- });
6018
- /**
6019
- * gutenScreen
6020
- *
6021
- * Adds compatibility with the Gutenberg edit screen.
6022
- *
6023
- * @date 11/12/18
6024
- * @since 5.8.0
6025
- *
6026
- * @param void
6027
- * @return void
6028
- */
6029
-
6030
- var gutenScreen = new acf.Model({
6031
- // Keep a reference to the most recent post attributes.
6032
- postEdits: {},
6033
- // Wait until assets have been loaded.
6034
- wait: 'prepare',
6035
- initialize: function () {
6036
- // Bail early if not Gutenberg.
6037
- if (!acf.isGutenberg()) {
6038
- return;
6039
- } // Listen for changes (use debounced version as this can fires often).
6040
-
6041
-
6042
- wp.data.subscribe(acf.debounce(this.onChange).bind(this)); // Customize "acf.screen.get" functions.
6043
-
6044
- acf.screen.getPageTemplate = this.getPageTemplate;
6045
- acf.screen.getPageParent = this.getPageParent;
6046
- acf.screen.getPostType = this.getPostType;
6047
- acf.screen.getPostFormat = this.getPostFormat;
6048
- acf.screen.getPostCoreTerms = this.getPostCoreTerms; // Disable unload
6049
-
6050
- acf.unload.disable(); // Refresh metaboxes since WP 5.3.
6051
-
6052
- var wpMinorVersion = parseFloat(acf.get('wp_version'));
6053
-
6054
- if (wpMinorVersion >= 5.3) {
6055
- this.addAction('refresh_post_screen', this.onRefreshPostScreen);
6056
- } // Trigger "refresh" after WP has moved metaboxes into place.
6057
-
6058
-
6059
- wp.domReady(acf.refresh);
6060
- },
6061
- onChange: function () {
6062
- // Determine attributes that can trigger a refresh.
6063
- var attributes = ['template', 'parent', 'format']; // Append taxonomy attribute names to this list.
6064
-
6065
- (wp.data.select('core').getTaxonomies() || []).map(function (taxonomy) {
6066
- attributes.push(taxonomy.rest_base);
6067
- }); // Get relevant current post edits.
6068
-
6069
- var _postEdits = wp.data.select('core/editor').getPostEdits();
6070
-
6071
- var postEdits = {};
6072
- attributes.map(function (k) {
6073
- if (_postEdits[k] !== undefined) {
6074
- postEdits[k] = _postEdits[k];
6075
- }
6076
- }); // Detect change.
6077
-
6078
- if (JSON.stringify(postEdits) !== JSON.stringify(this.postEdits)) {
6079
- this.postEdits = postEdits; // Check screen.
6080
-
6081
- acf.screen.check();
6082
- }
6083
- },
6084
- getPageTemplate: function () {
6085
- return wp.data.select('core/editor').getEditedPostAttribute('template');
6086
- },
6087
- getPageParent: function (e, $el) {
6088
- return wp.data.select('core/editor').getEditedPostAttribute('parent');
6089
- },
6090
- getPostType: function () {
6091
- return wp.data.select('core/editor').getEditedPostAttribute('type');
6092
- },
6093
- getPostFormat: function (e, $el) {
6094
- return wp.data.select('core/editor').getEditedPostAttribute('format');
6095
- },
6096
- getPostCoreTerms: function () {
6097
- // vars
6098
- var terms = {}; // Loop over taxonomies.
6099
-
6100
- var taxonomies = wp.data.select('core').getTaxonomies() || [];
6101
- taxonomies.map(function (taxonomy) {
6102
- // Append selected taxonomies to terms object.
6103
- var postTerms = wp.data.select('core/editor').getEditedPostAttribute(taxonomy.rest_base);
6104
-
6105
- if (postTerms) {
6106
- terms[taxonomy.slug] = postTerms;
6107
- }
6108
- }); // return
6109
-
6110
- return terms;
6111
- },
6112
-
6113
- /**
6114
- * onRefreshPostScreen
6115
- *
6116
- * Fires after the Post edit screen metaboxs are refreshed to update the Block Editor API state.
6117
- *
6118
- * @date 11/11/19
6119
- * @since 5.8.7
6120
- *
6121
- * @param object data The "check_screen" JSON response data.
6122
- * @return void
6123
- */
6124
- onRefreshPostScreen: function (data) {
6125
- // Extract vars.
6126
- var select = wp.data.select('core/edit-post');
6127
- var dispatch = wp.data.dispatch('core/edit-post'); // Load current metabox locations and data.
6128
-
6129
- var locations = {};
6130
- select.getActiveMetaBoxLocations().map(function (location) {
6131
- locations[location] = select.getMetaBoxesPerLocation(location);
6132
- }); // Generate flat array of existing ids.
6133
-
6134
- var ids = [];
6135
-
6136
- for (var k in locations) {
6137
- locations[k].map(function (m) {
6138
- ids.push(m.id);
6139
- });
6140
- } // Append new ACF metaboxes (ignore those which already exist).
6141
-
6142
-
6143
- data.results.filter(function (r) {
6144
- return ids.indexOf(r.id) === -1;
6145
- }).map(function (result, i) {
6146
- // Ensure location exists.
6147
- var location = result.position;
6148
- locations[location] = locations[location] || []; // Append.
6149
-
6150
- locations[location].push({
6151
- id: result.id,
6152
- title: result.title
6153
- });
6154
- }); // Remove hidden ACF metaboxes.
6155
-
6156
- for (var k in locations) {
6157
- locations[k] = locations[k].filter(function (m) {
6158
- return data.hidden.indexOf(m.id) === -1;
6159
- });
6160
- } // Update state.
6161
-
6162
-
6163
- dispatch.setAvailableMetaBoxesPerLocation(locations);
6164
- }
6165
- });
6166
- })(jQuery);
6167
-
6168
- (function ($, undefined) {
6169
- /**
6170
- * acf.newSelect2
6171
- *
6172
- * description
6173
- *
6174
- * @date 13/1/18
6175
- * @since 5.6.5
6176
- *
6177
- * @param type $var Description. Default.
6178
- * @return type Description.
6179
- */
6180
- acf.newSelect2 = function ($select, props) {
6181
- // defaults
6182
- props = acf.parseArgs(props, {
6183
- allowNull: false,
6184
- placeholder: '',
6185
- multiple: false,
6186
- field: false,
6187
- ajax: false,
6188
- ajaxAction: '',
6189
- ajaxData: function (data) {
6190
- return data;
6191
- },
6192
- ajaxResults: function (json) {
6193
- return json;
6194
- }
6195
- }); // initialize
6196
-
6197
- if (getVersion() == 4) {
6198
- var select2 = new Select2_4($select, props);
6199
- } else {
6200
- var select2 = new Select2_3($select, props);
6201
- } // actions
6202
-
6203
-
6204
- acf.doAction('new_select2', select2); // return
6205
-
6206
- return select2;
6207
- };
6208
- /**
6209
- * getVersion
6210
- *
6211
- * description
6212
- *
6213
- * @date 13/1/18
6214
- * @since 5.6.5
6215
- *
6216
- * @param type $var Description. Default.
6217
- * @return type Description.
6218
- */
6219
-
6220
-
6221
- function getVersion() {
6222
- // v4
6223
- if (acf.isset(window, 'jQuery', 'fn', 'select2', 'amd')) {
6224
- return 4;
6225
- } // v3
6226
-
6227
-
6228
- if (acf.isset(window, 'Select2')) {
6229
- return 3;
6230
- } // return
6231
-
6232
-
6233
- return false;
6234
- }
6235
- /**
6236
- * Select2
6237
- *
6238
- * description
6239
- *
6240
- * @date 13/1/18
6241
- * @since 5.6.5
6242
- *
6243
- * @param type $var Description. Default.
6244
- * @return type Description.
6245
- */
6246
-
6247
-
6248
- var Select2 = acf.Model.extend({
6249
- setup: function ($select, props) {
6250
- $.extend(this.data, props);
6251
- this.$el = $select;
6252
- },
6253
- initialize: function () {},
6254
- selectOption: function (value) {
6255
- var $option = this.getOption(value);
6256
-
6257
- if (!$option.prop('selected')) {
6258
- $option.prop('selected', true).trigger('change');
6259
- }
6260
- },
6261
- unselectOption: function (value) {
6262
- var $option = this.getOption(value);
6263
-
6264
- if ($option.prop('selected')) {
6265
- $option.prop('selected', false).trigger('change');
6266
- }
6267
- },
6268
- getOption: function (value) {
6269
- return this.$('option[value="' + value + '"]');
6270
- },
6271
- addOption: function (option) {
6272
- // defaults
6273
- option = acf.parseArgs(option, {
6274
- id: '',
6275
- text: '',
6276
- selected: false
6277
- }); // vars
6278
-
6279
- var $option = this.getOption(option.id); // append
6280
-
6281
- if (!$option.length) {
6282
- $option = $('<option></option>');
6283
- $option.html(option.text);
6284
- $option.attr('value', option.id);
6285
- $option.prop('selected', option.selected);
6286
- this.$el.append($option);
6287
- } // chain
6288
-
6289
-
6290
- return $option;
6291
- },
6292
- getValue: function () {
6293
- // vars
6294
- var val = [];
6295
- var $options = this.$el.find('option:selected'); // bail early if no selected
6296
-
6297
- if (!$options.exists()) {
6298
- return val;
6299
- } // sort by attribute
6300
-
6301
-
6302
- $options = $options.sort(function (a, b) {
6303
- return +a.getAttribute('data-i') - +b.getAttribute('data-i');
6304
- }); // loop
6305
-
6306
- $options.each(function () {
6307
- var $el = $(this);
6308
- val.push({
6309
- $el: $el,
6310
- id: $el.attr('value'),
6311
- text: $el.text()
6312
- });
6313
- }); // return
6314
-
6315
- return val;
6316
- },
6317
- mergeOptions: function () {},
6318
- getChoices: function () {
6319
- // callback
6320
- var crawl = function ($parent) {
6321
- // vars
6322
- var choices = []; // loop
6323
-
6324
- $parent.children().each(function () {
6325
- // vars
6326
- var $child = $(this); // optgroup
6327
-
6328
- if ($child.is('optgroup')) {
6329
- choices.push({
6330
- text: $child.attr('label'),
6331
- children: crawl($child)
6332
- }); // option
6333
- } else {
6334
- choices.push({
6335
- id: $child.attr('value'),
6336
- text: $child.text()
6337
- });
6338
- }
6339
- }); // return
6340
-
6341
- return choices;
6342
- }; // crawl
6343
-
6344
-
6345
- return crawl(this.$el);
6346
- },
6347
- getAjaxData: function (params) {
6348
- // vars
6349
- var ajaxData = {
6350
- action: this.get('ajaxAction'),
6351
- s: params.term || '',
6352
- paged: params.page || 1
6353
- }; // field helper
6354
-
6355
- var field = this.get('field');
6356
-
6357
- if (field) {
6358
- ajaxData.field_key = field.get('key');
6359
- } // callback
6360
-
6361
-
6362
- var callback = this.get('ajaxData');
6363
-
6364
- if (callback) {
6365
- ajaxData = callback.apply(this, [ajaxData, params]);
6366
- } // filter
6367
-
6368
-
6369
- ajaxData = acf.applyFilters('select2_ajax_data', ajaxData, this.data, this.$el, field || false, this); // return
6370
-
6371
- return acf.prepareForAjax(ajaxData);
6372
- },
6373
- getAjaxResults: function (json, params) {
6374
- // defaults
6375
- json = acf.parseArgs(json, {
6376
- results: false,
6377
- more: false
6378
- }); // callback
6379
-
6380
- var callback = this.get('ajaxResults');
6381
-
6382
- if (callback) {
6383
- json = callback.apply(this, [json, params]);
6384
- } // filter
6385
-
6386
-
6387
- json = acf.applyFilters('select2_ajax_results', json, params, this); // return
6388
-
6389
- return json;
6390
- },
6391
- processAjaxResults: function (json, params) {
6392
- // vars
6393
- var json = this.getAjaxResults(json, params); // change more to pagination
6394
-
6395
- if (json.more) {
6396
- json.pagination = {
6397
- more: true
6398
- };
6399
- } // merge together groups
6400
-
6401
-
6402
- setTimeout($.proxy(this.mergeOptions, this), 1); // return
6403
-
6404
- return json;
6405
- },
6406
- destroy: function () {
6407
- // destroy via api
6408
- if (this.$el.data('select2')) {
6409
- this.$el.select2('destroy');
6410
- } // destory via HTML (duplicating HTML does not contain data)
6411
-
6412
-
6413
- this.$el.siblings('.select2-container').remove();
6414
- }
6415
- });
6416
- /**
6417
- * Select2_4
6418
- *
6419
- * description
6420
- *
6421
- * @date 13/1/18
6422
- * @since 5.6.5
6423
- *
6424
- * @param type $var Description. Default.
6425
- * @return type Description.
6426
- */
6427
-
6428
- var Select2_4 = Select2.extend({
6429
- initialize: function () {
6430
- // vars
6431
- var $select = this.$el;
6432
- var options = {
6433
- width: '100%',
6434
- allowClear: this.get('allowNull'),
6435
- placeholder: this.get('placeholder'),
6436
- multiple: this.get('multiple'),
6437
- data: [],
6438
- escapeMarkup: function (string) {
6439
- return acf.escHtml(string);
6440
- }
6441
- }; // multiple
6442
-
6443
- if (options.multiple) {
6444
- // reorder options
6445
- this.getValue().map(function (item) {
6446
- item.$el.detach().appendTo($select);
6447
- });
6448
- } // Temporarily remove conflicting attribute.
6449
-
6450
-
6451
- var attrAjax = $select.attr('data-ajax');
6452
-
6453
- if (attrAjax !== undefined) {
6454
- $select.removeData('ajax');
6455
- $select.removeAttr('data-ajax');
6456
- } // ajax
6457
-
6458
-
6459
- if (this.get('ajax')) {
6460
- options.ajax = {
6461
- url: acf.get('ajaxurl'),
6462
- delay: 250,
6463
- dataType: 'json',
6464
- type: 'post',
6465
- cache: false,
6466
- data: $.proxy(this.getAjaxData, this),
6467
- processResults: $.proxy(this.processAjaxResults, this)
6468
- };
6469
- } // filter for 3rd party customization
6470
- //options = acf.applyFilters( 'select2_args', options, $select, this );
6471
-
6472
-
6473
- var field = this.get('field');
6474
- options = acf.applyFilters('select2_args', options, $select, this.data, field || false, this); // add select2
6475
-
6476
- $select.select2(options); // get container (Select2 v4 does not return this from constructor)
6477
-
6478
- var $container = $select.next('.select2-container'); // multiple
6479
-
6480
- if (options.multiple) {
6481
- // vars
6482
- var $ul = $container.find('ul'); // sortable
6483
-
6484
- $ul.sortable({
6485
- stop: function (e) {
6486
- // loop
6487
- $ul.find('.select2-selection__choice').each(function () {
6488
- // vars
6489
- var $option = $($(this).data('data').element); // detach and re-append to end
6490
-
6491
- $option.detach().appendTo($select);
6492
- }); // trigger change on input (JS error if trigger on select)
6493
-
6494
- $select.trigger('change');
6495
- }
6496
- }); // on select, move to end
6497
-
6498
- $select.on('select2:select', this.proxy(function (e) {
6499
- this.getOption(e.params.data.id).detach().appendTo(this.$el);
6500
- }));
6501
- } // add class
6502
-
6503
-
6504
- $container.addClass('-acf'); // Add back temporarily removed attr.
6505
-
6506
- if (attrAjax !== undefined) {
6507
- $select.attr('data-ajax', attrAjax);
6508
- } // action for 3rd party customization
6509
-
6510
-
6511
- acf.doAction('select2_init', $select, options, this.data, field || false, this);
6512
- },
6513
- mergeOptions: function () {
6514
- // vars
6515
- var $prevOptions = false;
6516
- var $prevGroup = false; // loop
6517
-
6518
- $('.select2-results__option[role="group"]').each(function () {
6519
- // vars
6520
- var $options = $(this).children('ul');
6521
- var $group = $(this).children('strong'); // compare to previous
6522
-
6523
- if ($prevGroup && $prevGroup.text() === $group.text()) {
6524
- $prevOptions.append($options.children());
6525
- $(this).remove();
6526
- return;
6527
- } // update vars
6528
-
6529
-
6530
- $prevOptions = $options;
6531
- $prevGroup = $group;
6532
- });
6533
- }
6534
- });
6535
- /**
6536
- * Select2_3
6537
- *
6538
- * description
6539
- *
6540
- * @date 13/1/18
6541
- * @since 5.6.5
6542
- *
6543
- * @param type $var Description. Default.
6544
- * @return type Description.
6545
- */
6546
-
6547
- var Select2_3 = Select2.extend({
6548
- initialize: function () {
6549
- // vars
6550
- var $select = this.$el;
6551
- var value = this.getValue();
6552
- var multiple = this.get('multiple');
6553
- var options = {
6554
- width: '100%',
6555
- allowClear: this.get('allowNull'),
6556
- placeholder: this.get('placeholder'),
6557
- separator: '||',
6558
- multiple: this.get('multiple'),
6559
- data: this.getChoices(),
6560
- escapeMarkup: function (string) {
6561
- return acf.escHtml(string);
6562
- },
6563
- dropdownCss: {
6564
- 'z-index': '999999999'
6565
- },
6566
- initSelection: function (element, callback) {
6567
- if (multiple) {
6568
- callback(value);
6569
- } else {
6570
- callback(value.shift());
6571
- }
6572
- }
6573
- }; // get hidden input
6574
-
6575
- var $input = $select.siblings('input');
6576
-
6577
- if (!$input.length) {
6578
- $input = $('<input type="hidden" />');
6579
- $select.before($input);
6580
- } // set input value
6581
-
6582
-
6583
- inputValue = value.map(function (item) {
6584
- return item.id;
6585
- }).join('||');
6586
- $input.val(inputValue); // multiple
6587
-
6588
- if (options.multiple) {
6589
- // reorder options
6590
- value.map(function (item) {
6591
- item.$el.detach().appendTo($select);
6592
- });
6593
- } // remove blank option as we have a clear all button
6594
-
6595
-
6596
- if (options.allowClear) {
6597
- options.data = options.data.filter(function (item) {
6598
- return item.id !== '';
6599
- });
6600
- } // remove conflicting atts
6601
-
6602
-
6603
- $select.removeData('ajax');
6604
- $select.removeAttr('data-ajax'); // ajax
6605
-
6606
- if (this.get('ajax')) {
6607
- options.ajax = {
6608
- url: acf.get('ajaxurl'),
6609
- quietMillis: 250,
6610
- dataType: 'json',
6611
- type: 'post',
6612
- cache: false,
6613
- data: $.proxy(this.getAjaxData, this),
6614
- results: $.proxy(this.processAjaxResults, this)
6615
- };
6616
- } // filter for 3rd party customization
6617
-
6618
-
6619
- var field = this.get('field');
6620
- options = acf.applyFilters('select2_args', options, $select, this.data, field || false, this); // add select2
6621
-
6622
- $input.select2(options); // get container
6623
-
6624
- var $container = $input.select2('container'); // helper to find this select's option
6625
-
6626
- var getOption = $.proxy(this.getOption, this); // multiple
6627
-
6628
- if (options.multiple) {
6629
- // vars
6630
- var $ul = $container.find('ul'); // sortable
6631
-
6632
- $ul.sortable({
6633
- stop: function () {
6634
- // loop
6635
- $ul.find('.select2-search-choice').each(function () {
6636
- // vars
6637
- var data = $(this).data('select2Data');
6638
- var $option = getOption(data.id); // detach and re-append to end
6639
-
6640
- $option.detach().appendTo($select);
6641
- }); // trigger change on input (JS error if trigger on select)
6642
-
6643
- $select.trigger('change');
6644
- }
6645
- });
6646
- } // on select, create option and move to end
6647
-
6648
-
6649
- $input.on('select2-selecting', function (e) {
6650
- // vars
6651
- var item = e.choice;
6652
- var $option = getOption(item.id); // create if doesn't exist
6653
-
6654
- if (!$option.length) {
6655
- $option = $('<option value="' + item.id + '">' + item.text + '</option>');
6656
- } // detach and re-append to end
6657
-
6658
-
6659
- $option.detach().appendTo($select);
6660
- }); // add class
6661
-
6662
- $container.addClass('-acf'); // action for 3rd party customization
6663
-
6664
- acf.doAction('select2_init', $select, options, this.data, field || false, this); // change
6665
-
6666
- $input.on('change', function () {
6667
- var val = $input.val();
6668
-
6669
- if (val.indexOf('||')) {
6670
- val = val.split('||');
6671
- }
6672
-
6673
- $select.val(val).trigger('change');
6674
- }); // hide select
6675
-
6676
- $select.hide();
6677
- },
6678
- mergeOptions: function () {
6679
- // vars
6680
- var $prevOptions = false;
6681
- var $prevGroup = false; // loop
6682
-
6683
- $('#select2-drop .select2-result-with-children').each(function () {
6684
- // vars
6685
- var $options = $(this).children('ul');
6686
- var $group = $(this).children('.select2-result-label'); // compare to previous
6687
-
6688
- if ($prevGroup && $prevGroup.text() === $group.text()) {
6689
- $prevGroup.append($options.children());
6690
- $(this).remove();
6691
- return;
6692
- } // update vars
6693
-
6694
-
6695
- $prevOptions = $options;
6696
- $prevGroup = $group;
6697
- });
6698
- },
6699
- getAjaxData: function (term, page) {
6700
- // create Select2 v4 params
6701
- var params = {
6702
- term: term,
6703
- page: page
6704
- }; // return
6705
-
6706
- return Select2.prototype.getAjaxData.apply(this, [params]);
6707
- }
6708
- }); // manager
6709
-
6710
- var select2Manager = new acf.Model({
6711
- priority: 5,
6712
- wait: 'prepare',
6713
- actions: {
6714
- 'duplicate': 'onDuplicate'
6715
- },
6716
- initialize: function () {
6717
- // vars
6718
- var locale = acf.get('locale');
6719
- var rtl = acf.get('rtl');
6720
- var l10n = acf.get('select2L10n');
6721
- var version = getVersion(); // bail ealry if no l10n
6722
-
6723
- if (!l10n) {
6724
- return false;
6725
- } // bail early if 'en'
6726
-
6727
-
6728
- if (locale.indexOf('en') === 0) {
6729
- return false;
6730
- } // initialize
6731
-
6732
-
6733
- if (version == 4) {
6734
- this.addTranslations4();
6735
- } else if (version == 3) {
6736
- this.addTranslations3();
6737
- }
6738
- },
6739
- addTranslations4: function () {
6740
- // vars
6741
- var l10n = acf.get('select2L10n');
6742
- var locale = acf.get('locale'); // modify local to match html[lang] attribute (used by Select2)
6743
-
6744
- locale = locale.replace('_', '-'); // select2L10n
6745
-
6746
- var select2L10n = {
6747
- errorLoading: function () {
6748
- return l10n.load_fail;
6749
- },
6750
- inputTooLong: function (args) {
6751
- var overChars = args.input.length - args.maximum;
6752
-
6753
- if (overChars > 1) {
6754
- return l10n.input_too_long_n.replace('%d', overChars);
6755
- }
6756
-
6757
- return l10n.input_too_long_1;
6758
- },
6759
- inputTooShort: function (args) {
6760
- var remainingChars = args.minimum - args.input.length;
6761
-
6762
- if (remainingChars > 1) {
6763
- return l10n.input_too_short_n.replace('%d', remainingChars);
6764
- }
6765
-
6766
- return l10n.input_too_short_1;
6767
- },
6768
- loadingMore: function () {
6769
- return l10n.load_more;
6770
- },
6771
- maximumSelected: function (args) {
6772
- var maximum = args.maximum;
6773
-
6774
- if (maximum > 1) {
6775
- return l10n.selection_too_long_n.replace('%d', maximum);
6776
- }
6777
-
6778
- return l10n.selection_too_long_1;
6779
- },
6780
- noResults: function () {
6781
- return l10n.matches_0;
6782
- },
6783
- searching: function () {
6784
- return l10n.searching;
6785
- }
6786
- }; // append
6787
-
6788
- jQuery.fn.select2.amd.define('select2/i18n/' + locale, [], function () {
6789
- return select2L10n;
6790
- });
6791
- },
6792
- addTranslations3: function () {
6793
- // vars
6794
- var l10n = acf.get('select2L10n');
6795
- var locale = acf.get('locale'); // modify local to match html[lang] attribute (used by Select2)
6796
-
6797
- locale = locale.replace('_', '-'); // select2L10n
6798
-
6799
- var select2L10n = {
6800
- formatMatches: function (matches) {
6801
- if (matches > 1) {
6802
- return l10n.matches_n.replace('%d', matches);
6803
- }
6804
-
6805
- return l10n.matches_1;
6806
- },
6807
- formatNoMatches: function () {
6808
- return l10n.matches_0;
6809
- },
6810
- formatAjaxError: function () {
6811
- return l10n.load_fail;
6812
- },
6813
- formatInputTooShort: function (input, min) {
6814
- var remainingChars = min - input.length;
6815
-
6816
- if (remainingChars > 1) {
6817
- return l10n.input_too_short_n.replace('%d', remainingChars);
6818
- }
6819
-
6820
- return l10n.input_too_short_1;
6821
- },
6822
- formatInputTooLong: function (input, max) {
6823
- var overChars = input.length - max;
6824
-
6825
- if (overChars > 1) {
6826
- return l10n.input_too_long_n.replace('%d', overChars);
6827
- }
6828
-
6829
- return l10n.input_too_long_1;
6830
- },
6831
- formatSelectionTooBig: function (maximum) {
6832
- if (maximum > 1) {
6833
- return l10n.selection_too_long_n.replace('%d', maximum);
6834
- }
6835
-
6836
- return l10n.selection_too_long_1;
6837
- },
6838
- formatLoadMore: function () {
6839
- return l10n.load_more;
6840
- },
6841
- formatSearching: function () {
6842
- return l10n.searching;
6843
- }
6844
- }; // ensure locales exists
6845
-
6846
- $.fn.select2.locales = $.fn.select2.locales || {}; // append
6847
-
6848
- $.fn.select2.locales[locale] = select2L10n;
6849
- $.extend($.fn.select2.defaults, select2L10n);
6850
- },
6851
- onDuplicate: function ($el, $el2) {
6852
- $el2.find('.select2-container').remove();
6853
- }
6854
- });
6855
- })(jQuery);
6856
-
6857
- (function ($, undefined) {
6858
- acf.tinymce = {
6859
- /*
6860
- * defaults
6861
- *
6862
- * This function will return default mce and qt settings
6863
- *
6864
- * @type function
6865
- * @date 18/8/17
6866
- * @since 5.6.0
6867
- *
6868
- * @param $post_id (int)
6869
- * @return $post_id (int)
6870
- */
6871
- defaults: function () {
6872
- // bail early if no tinyMCEPreInit
6873
- if (typeof tinyMCEPreInit === 'undefined') return false; // vars
6874
-
6875
- var defaults = {
6876
- tinymce: tinyMCEPreInit.mceInit.acf_content,
6877
- quicktags: tinyMCEPreInit.qtInit.acf_content
6878
- }; // return
6879
-
6880
- return defaults;
6881
- },
6882
-
6883
- /*
6884
- * initialize
6885
- *
6886
- * This function will initialize the tinymce and quicktags instances
6887
- *
6888
- * @type function
6889
- * @date 18/8/17
6890
- * @since 5.6.0
6891
- *
6892
- * @param $post_id (int)
6893
- * @return $post_id (int)
6894
- */
6895
- initialize: function (id, args) {
6896
- // defaults
6897
- args = acf.parseArgs(args, {
6898
- tinymce: true,
6899
- quicktags: true,
6900
- toolbar: 'full',
6901
- mode: 'visual',
6902
- // visual,text
6903
- field: false
6904
- }); // tinymce
6905
-
6906
- if (args.tinymce) {
6907
- this.initializeTinymce(id, args);
6908
- } // quicktags
6909
-
6910
-
6911
- if (args.quicktags) {
6912
- this.initializeQuicktags(id, args);
6913
- }
6914
- },
6915
-
6916
- /*
6917
- * initializeTinymce
6918
- *
6919
- * This function will initialize the tinymce instance
6920
- *
6921
- * @type function
6922
- * @date 18/8/17
6923
- * @since 5.6.0
6924
- *
6925
- * @param $post_id (int)
6926
- * @return $post_id (int)
6927
- */
6928
- initializeTinymce: function (id, args) {
6929
- // vars
6930
- var $textarea = $('#' + id);
6931
- var defaults = this.defaults();
6932
- var toolbars = acf.get('toolbars');
6933
- var field = args.field || false;
6934
- var $field = field.$el || false; // bail early
6935
-
6936
- if (typeof tinymce === 'undefined') return false;
6937
- if (!defaults) return false; // check if exists
6938
-
6939
- if (tinymce.get(id)) {
6940
- return this.enable(id);
6941
- } // settings
6942
-
6943
-
6944
- var init = $.extend({}, defaults.tinymce, args.tinymce);
6945
- init.id = id;
6946
- init.selector = '#' + id; // toolbar
6947
-
6948
- var toolbar = args.toolbar;
6949
-
6950
- if (toolbar && toolbars && toolbars[toolbar]) {
6951
- for (var i = 1; i <= 4; i++) {
6952
- init['toolbar' + i] = toolbars[toolbar][i] || '';
6953
- }
6954
- } // event
6955
-
6956
-
6957
- init.setup = function (ed) {
6958
- ed.on('change', function (e) {
6959
- ed.save(); // save to textarea
6960
-
6961
- $textarea.trigger('change');
6962
- }); // Fix bug where Gutenberg does not hear "mouseup" event and tries to select multiple blocks.
6963
-
6964
- ed.on('mouseup', function (e) {
6965
- var event = new MouseEvent('mouseup');
6966
- window.dispatchEvent(event);
6967
- }); // Temporarily comment out. May not be necessary due to wysiwyg field actions.
6968
- //ed.on('unload', function(e) {
6969
- // acf.tinymce.remove( id );
6970
- //});
6971
- }; // disable wp_autoresize_on (no solution yet for fixed toolbar)
6972
-
6973
-
6974
- init.wp_autoresize_on = false; // Enable wpautop allowing value to save without <p> tags.
6975
- // Only if the "TinyMCE Advanced" plugin hasn't already set this functionality.
6976
-
6977
- if (!init.tadv_noautop) {
6978
- init.wpautop = true;
6979
- } // hook for 3rd party customization
6980
-
6981
-
6982
- init = acf.applyFilters('wysiwyg_tinymce_settings', init, id, field); // z-index fix (caused too many conflicts)
6983
- //if( acf.isset(tinymce,'ui','FloatPanel') ) {
6984
- // tinymce.ui.FloatPanel.zIndex = 900000;
6985
- //}
6986
- // store settings
6987
-
6988
- tinyMCEPreInit.mceInit[id] = init; // visual tab is active
6989
-
6990
- if (args.mode == 'visual') {
6991
- // init
6992
- var result = tinymce.init(init); // get editor
6993
-
6994
- var ed = tinymce.get(id); // validate
6995
-
6996
- if (!ed) {
6997
- return false;
6998
- } // add reference
6999
-
7000
-
7001
- ed.acf = args.field; // action
7002
-
7003
- acf.doAction('wysiwyg_tinymce_init', ed, ed.id, init, field);
7004
- }
7005
- },
7006
-
7007
- /*
7008
- * initializeQuicktags
7009
- *
7010
- * This function will initialize the quicktags instance
7011
- *
7012
- * @type function
7013
- * @date 18/8/17
7014
- * @since 5.6.0
7015
- *
7016
- * @param $post_id (int)
7017
- * @return $post_id (int)
7018
- */
7019
- initializeQuicktags: function (id, args) {
7020
- // vars
7021
- var defaults = this.defaults(); // bail early
7022
-
7023
- if (typeof quicktags === 'undefined') return false;
7024
- if (!defaults) return false; // settings
7025
-
7026
- var init = $.extend({}, defaults.quicktags, args.quicktags);
7027
- init.id = id; // filter
7028
-
7029
- var field = args.field || false;
7030
- var $field = field.$el || false;
7031
- init = acf.applyFilters('wysiwyg_quicktags_settings', init, init.id, field); // store settings
7032
-
7033
- tinyMCEPreInit.qtInit[id] = init; // init
7034
-
7035
- var ed = quicktags(init); // validate
7036
-
7037
- if (!ed) {
7038
- return false;
7039
- } // generate HTML
7040
-
7041
-
7042
- this.buildQuicktags(ed); // action for 3rd party customization
7043
-
7044
- acf.doAction('wysiwyg_quicktags_init', ed, ed.id, init, field);
7045
- },
7046
-
7047
- /*
7048
- * buildQuicktags
7049
- *
7050
- * This function will build the quicktags HTML
7051
- *
7052
- * @type function
7053
- * @date 18/8/17
7054
- * @since 5.6.0
7055
- *
7056
- * @param $post_id (int)
7057
- * @return $post_id (int)
7058
- */
7059
- buildQuicktags: function (ed) {
7060
- var canvas,
7061
- name,
7062
- settings,
7063
- theButtons,
7064
- html,
7065
- ed,
7066
- id,
7067
- i,
7068
- use,
7069
- instanceId,
7070
- defaults = ',strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,';
7071
- canvas = ed.canvas;
7072
- name = ed.name;
7073
- settings = ed.settings;
7074
- html = '';
7075
- theButtons = {};
7076
- use = '';
7077
- instanceId = ed.id; // set buttons
7078
-
7079
- if (settings.buttons) {
7080
- use = ',' + settings.buttons + ',';
7081
- }
7082
-
7083
- for (i in edButtons) {
7084
- if (!edButtons[i]) {
7085
- continue;
7086
- }
7087
-
7088
- id = edButtons[i].id;
7089
-
7090
- if (use && defaults.indexOf(',' + id + ',') !== -1 && use.indexOf(',' + id + ',') === -1) {
7091
- continue;
7092
- }
7093
-
7094
- if (!edButtons[i].instance || edButtons[i].instance === instanceId) {
7095
- theButtons[id] = edButtons[i];
7096
-
7097
- if (edButtons[i].html) {
7098
- html += edButtons[i].html(name + '_');
7099
- }
7100
- }
7101
- }
7102
-
7103
- if (use && use.indexOf(',dfw,') !== -1) {
7104
- theButtons.dfw = new QTags.DFWButton();
7105
- html += theButtons.dfw.html(name + '_');
7106
- }
7107
-
7108
- if ('rtl' === document.getElementsByTagName('html')[0].dir) {
7109
- theButtons.textdirection = new QTags.TextDirectionButton();
7110
- html += theButtons.textdirection.html(name + '_');
7111
- }
7112
-
7113
- ed.toolbar.innerHTML = html;
7114
- ed.theButtons = theButtons;
7115
-
7116
- if (typeof jQuery !== 'undefined') {
7117
- jQuery(document).triggerHandler('quicktags-init', [ed]);
7118
- }
7119
- },
7120
- disable: function (id) {
7121
- this.destroyTinymce(id);
7122
- },
7123
- remove: function (id) {
7124
- this.destroyTinymce(id);
7125
- },
7126
- destroy: function (id) {
7127
- this.destroyTinymce(id);
7128
- },
7129
- destroyTinymce: function (id) {
7130
- // bail early
7131
- if (typeof tinymce === 'undefined') return false; // get editor
7132
-
7133
- var ed = tinymce.get(id); // bail early if no editor
7134
-
7135
- if (!ed) return false; // save
7136
-
7137
- ed.save(); // destroy editor
7138
-
7139
- ed.destroy(); // return
7140
-
7141
- return true;
7142
- },
7143
- enable: function (id) {
7144
- this.enableTinymce(id);
7145
- },
7146
- enableTinymce: function (id) {
7147
- // bail early
7148
- if (typeof switchEditors === 'undefined') return false; // bail ealry if not initialized
7149
-
7150
- if (typeof tinyMCEPreInit.mceInit[id] === 'undefined') return false; // Ensure textarea element is visible
7151
- // - Fixes bug in block editor when switching between "Block" and "Document" tabs.
7152
-
7153
- $('#' + id).show(); // toggle
7154
-
7155
- switchEditors.go(id, 'tmce'); // return
7156
-
7157
- return true;
7158
- }
7159
- };
7160
- var editorManager = new acf.Model({
7161
- // hook in before fieldsEventManager, conditions, etc
7162
- priority: 5,
7163
- actions: {
7164
- 'prepare': 'onPrepare',
7165
- 'ready': 'onReady'
7166
- },
7167
- onPrepare: function () {
7168
- // find hidden editor which may exist within a field
7169
- var $div = $('#acf-hidden-wp-editor'); // move to footer
7170
-
7171
- if ($div.exists()) {
7172
- $div.appendTo('body');
7173
- }
7174
- },
7175
- onReady: function () {
7176
- // Restore wp.editor functions used by tinymce removed in WP5.
7177
- if (acf.isset(window, 'wp', 'oldEditor')) {
7178
- wp.editor.autop = wp.oldEditor.autop;
7179
- wp.editor.removep = wp.oldEditor.removep;
7180
- } // bail early if no tinymce
7181
-
7182
-
7183
- if (!acf.isset(window, 'tinymce', 'on')) return; // restore default activeEditor
7184
-
7185
- tinymce.on('AddEditor', function (data) {
7186
- // vars
7187
- var editor = data.editor; // bail early if not 'acf'
7188
-
7189
- if (editor.id.substr(0, 3) !== 'acf') return; // override if 'content' exists
7190
-
7191
- editor = tinymce.editors.content || editor; // update vars
7192
-
7193
- tinymce.activeEditor = editor;
7194
- wpActiveEditor = editor.id;
7195
- });
7196
- }
7197
- });
7198
- })(jQuery);
7199
-
7200
- (function ($, undefined) {
7201
- /**
7202
- * Validator
7203
- *
7204
- * The model for validating forms
7205
- *
7206
- * @date 4/9/18
7207
- * @since 5.7.5
7208
- *
7209
- * @param void
7210
- * @return void
7211
- */
7212
- var Validator = acf.Model.extend({
7213
- /** @var string The model identifier. */
7214
- id: 'Validator',
7215
-
7216
- /** @var object The model data. */
7217
- data: {
7218
- /** @var array The form errors. */
7219
- errors: [],
7220
-
7221
- /** @var object The form notice. */
7222
- notice: null,
7223
-
7224
- /** @var string The form status. loading, invalid, valid */
7225
- status: ''
7226
- },
7227
-
7228
- /** @var object The model events. */
7229
- events: {
7230
- 'changed:status': 'onChangeStatus'
7231
- },
7232
-
7233
- /**
7234
- * addErrors
7235
- *
7236
- * Adds errors to the form.
7237
- *
7238
- * @date 4/9/18
7239
- * @since 5.7.5
7240
- *
7241
- * @param array errors An array of errors.
7242
- * @return void
7243
- */
7244
- addErrors: function (errors) {
7245
- errors.map(this.addError, this);
7246
- },
7247
-
7248
- /**
7249
- * addError
7250
- *
7251
- * Adds and error to the form.
7252
- *
7253
- * @date 4/9/18
7254
- * @since 5.7.5
7255
- *
7256
- * @param object error An error object containing input and message.
7257
- * @return void
7258
- */
7259
- addError: function (error) {
7260
- this.data.errors.push(error);
7261
- },
7262
-
7263
- /**
7264
- * hasErrors
7265
- *
7266
- * Returns true if the form has errors.
7267
- *
7268
- * @date 4/9/18
7269
- * @since 5.7.5
7270
- *
7271
- * @param void
7272
- * @return bool
7273
- */
7274
- hasErrors: function () {
7275
- return this.data.errors.length;
7276
- },
7277
-
7278
- /**
7279
- * clearErrors
7280
- *
7281
- * Removes any errors.
7282
- *
7283
- * @date 4/9/18
7284
- * @since 5.7.5
7285
- *
7286
- * @param void
7287
- * @return void
7288
- */
7289
- clearErrors: function () {
7290
- return this.data.errors = [];
7291
- },
7292
-
7293
- /**
7294
- * getErrors
7295
- *
7296
- * Returns the forms errors.
7297
- *
7298
- * @date 4/9/18
7299
- * @since 5.7.5
7300
- *
7301
- * @param void
7302
- * @return array
7303
- */
7304
- getErrors: function () {
7305
- return this.data.errors;
7306
- },
7307
-
7308
- /**
7309
- * getFieldErrors
7310
- *
7311
- * Returns the forms field errors.
7312
- *
7313
- * @date 4/9/18
7314
- * @since 5.7.5
7315
- *
7316
- * @param void
7317
- * @return array
7318
- */
7319
- getFieldErrors: function () {
7320
- // vars
7321
- var errors = [];
7322
- var inputs = []; // loop
7323
-
7324
- this.getErrors().map(function (error) {
7325
- // bail early if global
7326
- if (!error.input) return; // update if exists
7327
-
7328
- var i = inputs.indexOf(error.input);
7329
-
7330
- if (i > -1) {
7331
- errors[i] = error; // update
7332
- } else {
7333
- errors.push(error);
7334
- inputs.push(error.input);
7335
- }
7336
- }); // return
7337
-
7338
- return errors;
7339
- },
7340
-
7341
- /**
7342
- * getGlobalErrors
7343
- *
7344
- * Returns the forms global errors (errors without a specific input).
7345
- *
7346
- * @date 4/9/18
7347
- * @since 5.7.5
7348
- *
7349
- * @param void
7350
- * @return array
7351
- */
7352
- getGlobalErrors: function () {
7353
- // return array of errors that contain no input
7354
- return this.getErrors().filter(function (error) {
7355
- return !error.input;
7356
- });
7357
- },
7358
-
7359
- /**
7360
- * showErrors
7361
- *
7362
- * Displays all errors for this form.
7363
- *
7364
- * @date 4/9/18
7365
- * @since 5.7.5
7366
- *
7367
- * @param void
7368
- * @return void
7369
- */
7370
- showErrors: function () {
7371
- // bail early if no errors
7372
- if (!this.hasErrors()) {
7373
- return;
7374
- } // vars
7375
-
7376
-
7377
- var fieldErrors = this.getFieldErrors();
7378
- var globalErrors = this.getGlobalErrors(); // vars
7379
-
7380
- var errorCount = 0;
7381
- var $scrollTo = false; // loop
7382
-
7383
- fieldErrors.map(function (error) {
7384
- // get input
7385
- var $input = this.$('[name="' + error.input + '"]').first(); // if $_POST value was an array, this $input may not exist
7386
-
7387
- if (!$input.length) {
7388
- $input = this.$('[name^="' + error.input + '"]').first();
7389
- } // bail early if input doesn't exist
7390
-
7391
-
7392
- if (!$input.length) {
7393
- return;
7394
- } // increase
7395
-
7396
-
7397
- errorCount++; // get field
7398
-
7399
- var field = acf.getClosestField($input); // show error
7400
-
7401
- field.showError(error.message); // set $scrollTo
7402
-
7403
- if (!$scrollTo) {
7404
- $scrollTo = field.$el;
7405
- }
7406
- }, this); // errorMessage
7407
-
7408
- var errorMessage = acf.__('Validation failed');
7409
-
7410
- globalErrors.map(function (error) {
7411
- errorMessage += '. ' + error.message;
7412
- });
7413
-
7414
- if (errorCount == 1) {
7415
- errorMessage += '. ' + acf.__('1 field requires attention');
7416
- } else if (errorCount > 1) {
7417
- errorMessage += '. ' + acf.__('%d fields require attention').replace('%d', errorCount);
7418
- } // notice
7419
-
7420
-
7421
- if (this.has('notice')) {
7422
- this.get('notice').update({
7423
- type: 'error',
7424
- text: errorMessage
7425
- });
7426
- } else {
7427
- var notice = acf.newNotice({
7428
- type: 'error',
7429
- text: errorMessage,
7430
- target: this.$el
7431
- });
7432
- this.set('notice', notice);
7433
- } // if no $scrollTo, set to message
7434
-
7435
-
7436
- if (!$scrollTo) {
7437
- $scrollTo = this.get('notice').$el;
7438
- } // timeout
7439
-
7440
-
7441
- setTimeout(function () {
7442
- $("html, body").animate({
7443
- scrollTop: $scrollTo.offset().top - $(window).height() / 2
7444
- }, 500);
7445
- }, 10);
7446
- },
7447
-
7448
- /**
7449
- * onChangeStatus
7450
- *
7451
- * Update the form class when changing the 'status' data
7452
- *
7453
- * @date 4/9/18
7454
- * @since 5.7.5
7455
- *
7456
- * @param object e The event object.
7457
- * @param jQuery $el The form element.
7458
- * @param string value The new status.
7459
- * @param string prevValue The old status.
7460
- * @return void
7461
- */
7462
- onChangeStatus: function (e, $el, value, prevValue) {
7463
- this.$el.removeClass('is-' + prevValue).addClass('is-' + value);
7464
- },
7465
-
7466
- /**
7467
- * validate
7468
- *
7469
- * Vaildates the form via AJAX.
7470
- *
7471
- * @date 4/9/18
7472
- * @since 5.7.5
7473
- *
7474
- * @param object args A list of settings to customize the validation process.
7475
- * @return bool True if the form is valid.
7476
- */
7477
- validate: function (args) {
7478
- // default args
7479
- args = acf.parseArgs(args, {
7480
- // trigger event
7481
- event: false,
7482
- // reset the form after submit
7483
- reset: false,
7484
- // loading callback
7485
- loading: function () {},
7486
- // complete callback
7487
- complete: function () {},
7488
- // failure callback
7489
- failure: function () {},
7490
- // success callback
7491
- success: function ($form) {
7492
- $form.submit();
7493
- }
7494
- }); // return true if is valid - allows form submit
7495
-
7496
- if (this.get('status') == 'valid') {
7497
- return true;
7498
- } // return false if is currently validating - prevents form submit
7499
-
7500
-
7501
- if (this.get('status') == 'validating') {
7502
- return false;
7503
- } // return true if no ACF fields exist (no need to validate)
7504
-
7505
-
7506
- if (!this.$('.acf-field').length) {
7507
- return true;
7508
- } // if event is provided, create a new success callback.
7509
-
7510
-
7511
- if (args.event) {
7512
- var event = $.Event(null, args.event);
7513
-
7514
- args.success = function () {
7515
- acf.enableSubmit($(event.target)).trigger(event);
7516
- };
7517
- } // action for 3rd party
7518
-
7519
-
7520
- acf.doAction('validation_begin', this.$el); // lock form
7521
-
7522
- acf.lockForm(this.$el); // loading callback
7523
-
7524
- args.loading(this.$el, this); // update status
7525
-
7526
- this.set('status', 'validating'); // success callback
7527
-
7528
- var onSuccess = function (json) {
7529
- // validate
7530
- if (!acf.isAjaxSuccess(json)) {
7531
- return;
7532
- } // filter
7533
-
7534
-
7535
- var data = acf.applyFilters('validation_complete', json.data, this.$el, this); // add errors
7536
-
7537
- if (!data.valid) {
7538
- this.addErrors(data.errors);
7539
- }
7540
- }; // complete
7541
-
7542
-
7543
- var onComplete = function () {
7544
- // unlock form
7545
- acf.unlockForm(this.$el); // failure
7546
-
7547
- if (this.hasErrors()) {
7548
- // update status
7549
- this.set('status', 'invalid'); // action
7550
-
7551
- acf.doAction('validation_failure', this.$el, this); // display errors
7552
-
7553
- this.showErrors(); // failure callback
7554
-
7555
- args.failure(this.$el, this); // success
7556
- } else {
7557
- // update status
7558
- this.set('status', 'valid'); // remove previous error message
7559
-
7560
- if (this.has('notice')) {
7561
- this.get('notice').update({
7562
- type: 'success',
7563
- text: acf.__('Validation successful'),
7564
- timeout: 1000
7565
- });
7566
- } // action
7567
-
7568
-
7569
- acf.doAction('validation_success', this.$el, this);
7570
- acf.doAction('submit', this.$el); // success callback (submit form)
7571
-
7572
- args.success(this.$el, this); // lock form
7573
-
7574
- acf.lockForm(this.$el); // reset
7575
-
7576
- if (args.reset) {
7577
- this.reset();
7578
- }
7579
- } // complete callback
7580
-
7581
-
7582
- args.complete(this.$el, this); // clear errors
7583
-
7584
- this.clearErrors();
7585
- }; // serialize form data
7586
-
7587
-
7588
- var data = acf.serialize(this.$el);
7589
- data.action = 'acf/validate_save_post'; // ajax
7590
-
7591
- $.ajax({
7592
- url: acf.get('ajaxurl'),
7593
- data: acf.prepareForAjax(data),
7594
- type: 'post',
7595
- dataType: 'json',
7596
- context: this,
7597
- success: onSuccess,
7598
- complete: onComplete
7599
- }); // return false to fail validation and allow AJAX
7600
-
7601
- return false;
7602
- },
7603
-
7604
- /**
7605
- * setup
7606
- *
7607
- * Called during the constructor function to setup this instance
7608
- *
7609
- * @date 4/9/18
7610
- * @since 5.7.5
7611
- *
7612
- * @param jQuery $form The form element.
7613
- * @return void
7614
- */
7615
- setup: function ($form) {
7616
- // set $el
7617
- this.$el = $form;
7618
- },
7619
-
7620
- /**
7621
- * reset
7622
- *
7623
- * Rests the validation to be used again.
7624
- *
7625
- * @date 6/9/18
7626
- * @since 5.7.5
7627
- *
7628
- * @param void
7629
- * @return void
7630
- */
7631
- reset: function () {
7632
- // reset data
7633
- this.set('errors', []);
7634
- this.set('notice', null);
7635
- this.set('status', ''); // unlock form
7636
-
7637
- acf.unlockForm(this.$el);
7638
- }
7639
- });
7640
- /**
7641
- * getValidator
7642
- *
7643
- * Returns the instance for a given form element.
7644
- *
7645
- * @date 4/9/18
7646
- * @since 5.7.5
7647
- *
7648
- * @param jQuery $el The form element.
7649
- * @return object
7650
- */
7651
-
7652
- var getValidator = function ($el) {
7653
- // instantiate
7654
- var validator = $el.data('acf');
7655
-
7656
- if (!validator) {
7657
- validator = new Validator($el);
7658
- } // return
7659
-
7660
-
7661
- return validator;
7662
- };
7663
- /**
7664
- * acf.validateForm
7665
- *
7666
- * A helper function for the Validator.validate() function.
7667
- * Returns true if form is valid, or fetches a validation request and returns false.
7668
- *
7669
- * @date 4/4/18
7670
- * @since 5.6.9
7671
- *
7672
- * @param object args A list of settings to customize the validation process.
7673
- * @return bool
7674
- */
7675
-
7676
-
7677
- acf.validateForm = function (args) {
7678
- return getValidator(args.form).validate(args);
7679
- };
7680
- /**
7681
- * acf.enableSubmit
7682
- *
7683
- * Enables a submit button and returns the element.
7684
- *
7685
- * @date 30/8/18
7686
- * @since 5.7.4
7687
- *
7688
- * @param jQuery $submit The submit button.
7689
- * @return jQuery
7690
- */
7691
-
7692
-
7693
- acf.enableSubmit = function ($submit) {
7694
- return $submit.removeClass('disabled');
7695
- };
7696
- /**
7697
- * acf.disableSubmit
7698
- *
7699
- * Disables a submit button and returns the element.
7700
- *
7701
- * @date 30/8/18
7702
- * @since 5.7.4
7703
- *
7704
- * @param jQuery $submit The submit button.
7705
- * @return jQuery
7706
- */
7707
-
7708
-
7709
- acf.disableSubmit = function ($submit) {
7710
- return $submit.addClass('disabled');
7711
- };
7712
- /**
7713
- * acf.showSpinner
7714
- *
7715
- * Shows the spinner element.
7716
- *
7717
- * @date 4/9/18
7718
- * @since 5.7.5
7719
- *
7720
- * @param jQuery $spinner The spinner element.
7721
- * @return jQuery
7722
- */
7723
-
7724
-
7725
- acf.showSpinner = function ($spinner) {
7726
- $spinner.addClass('is-active'); // add class (WP > 4.2)
7727
-
7728
- $spinner.css('display', 'inline-block'); // css (WP < 4.2)
7729
-
7730
- return $spinner;
7731
- };
7732
- /**
7733
- * acf.hideSpinner
7734
- *
7735
- * Hides the spinner element.
7736
- *
7737
- * @date 4/9/18
7738
- * @since 5.7.5
7739
- *
7740
- * @param jQuery $spinner The spinner element.
7741
- * @return jQuery
7742
- */
7743
-
7744
-
7745
- acf.hideSpinner = function ($spinner) {
7746
- $spinner.removeClass('is-active'); // add class (WP > 4.2)
7747
-
7748
- $spinner.css('display', 'none'); // css (WP < 4.2)
7749
-
7750
- return $spinner;
7751
- };
7752
- /**
7753
- * acf.lockForm
7754
- *
7755
- * Locks a form by disabeling its primary inputs and showing a spinner.
7756
- *
7757
- * @date 4/9/18
7758
- * @since 5.7.5
7759
- *
7760
- * @param jQuery $form The form element.
7761
- * @return jQuery
7762
- */
7763
-
7764
-
7765
- acf.lockForm = function ($form) {
7766
- // vars
7767
- var $wrap = findSubmitWrap($form);
7768
- var $submit = $wrap.find('.button, [type="submit"]');
7769
- var $spinner = $wrap.find('.spinner, .acf-spinner'); // hide all spinners (hides the preview spinner)
7770
-
7771
- acf.hideSpinner($spinner); // lock
7772
-
7773
- acf.disableSubmit($submit);
7774
- acf.showSpinner($spinner.last());
7775
- return $form;
7776
- };
7777
- /**
7778
- * acf.unlockForm
7779
- *
7780
- * Unlocks a form by enabeling its primary inputs and hiding all spinners.
7781
- *
7782
- * @date 4/9/18
7783
- * @since 5.7.5
7784
- *
7785
- * @param jQuery $form The form element.
7786
- * @return jQuery
7787
- */
7788
-
7789
-
7790
- acf.unlockForm = function ($form) {
7791
- // vars
7792
- var $wrap = findSubmitWrap($form);
7793
- var $submit = $wrap.find('.button, [type="submit"]');
7794
- var $spinner = $wrap.find('.spinner, .acf-spinner'); // unlock
7795
-
7796
- acf.enableSubmit($submit);
7797
- acf.hideSpinner($spinner);
7798
- return $form;
7799
- };
7800
- /**
7801
- * findSubmitWrap
7802
- *
7803
- * An internal function to find the 'primary' form submit wrapping element.
7804
- *
7805
- * @date 4/9/18
7806
- * @since 5.7.5
7807
- *
7808
- * @param jQuery $form The form element.
7809
- * @return jQuery
7810
- */
7811
-
7812
-
7813
- var findSubmitWrap = function ($form) {
7814
- // default post submit div
7815
- var $wrap = $form.find('#submitdiv');
7816
-
7817
- if ($wrap.length) {
7818
- return $wrap;
7819
- } // 3rd party publish box
7820
-
7821
-
7822
- var $wrap = $form.find('#submitpost');
7823
-
7824
- if ($wrap.length) {
7825
- return $wrap;
7826
- } // term, user
7827
-
7828
-
7829
- var $wrap = $form.find('p.submit').last();
7830
-
7831
- if ($wrap.length) {
7832
- return $wrap;
7833
- } // front end form
7834
-
7835
-
7836
- var $wrap = $form.find('.acf-form-submit');
7837
-
7838
- if ($wrap.length) {
7839
- return $wrap;
7840
- } // default
7841
-
7842
-
7843
- return $form;
7844
- };
7845
- /**
7846
- * A debounced function to trigger a form submission.
7847
- *
7848
- * @date 15/07/2020
7849
- * @since 5.9.0
7850
- *
7851
- * @param type Var Description.
7852
- * @return type Description.
7853
- */
7854
-
7855
-
7856
- var submitFormDebounced = acf.debounce(function ($form) {
7857
- $form.submit();
7858
- });
7859
- /**
7860
- * acf.validation
7861
- *
7862
- * Global validation logic
7863
- *
7864
- * @date 4/4/18
7865
- * @since 5.6.9
7866
- *
7867
- * @param void
7868
- * @return void
7869
- */
7870
-
7871
- acf.validation = new acf.Model({
7872
- /** @var string The model identifier. */
7873
- id: 'validation',
7874
-
7875
- /** @var bool The active state. Set to false before 'prepare' to prevent validation. */
7876
- active: true,
7877
-
7878
- /** @var string The model initialize time. */
7879
- wait: 'prepare',
7880
-
7881
- /** @var object The model actions. */
7882
- actions: {
7883
- 'ready': 'addInputEvents',
7884
- 'append': 'addInputEvents'
7885
- },
7886
-
7887
- /** @var object The model events. */
7888
- events: {
7889
- 'click input[type="submit"]': 'onClickSubmit',
7890
- 'click button[type="submit"]': 'onClickSubmit',
7891
- //'click #editor .editor-post-publish-button': 'onClickSubmitGutenberg',
7892
- 'click #save-post': 'onClickSave',
7893
- 'submit form#post': 'onSubmitPost',
7894
- 'submit form': 'onSubmit'
7895
- },
7896
-
7897
- /**
7898
- * initialize
7899
- *
7900
- * Called when initializing the model.
7901
- *
7902
- * @date 4/9/18
7903
- * @since 5.7.5
7904
- *
7905
- * @param void
7906
- * @return void
7907
- */
7908
- initialize: function () {
7909
- // check 'validation' setting
7910
- if (!acf.get('validation')) {
7911
- this.active = false;
7912
- this.actions = {};
7913
- this.events = {};
7914
- }
7915
- },
7916
-
7917
- /**
7918
- * enable
7919
- *
7920
- * Enables validation.
7921
- *
7922
- * @date 4/9/18
7923
- * @since 5.7.5
7924
- *
7925
- * @param void
7926
- * @return void
7927
- */
7928
- enable: function () {
7929
- this.active = true;
7930
- },
7931
-
7932
- /**
7933
- * disable
7934
- *
7935
- * Disables validation.
7936
- *
7937
- * @date 4/9/18
7938
- * @since 5.7.5
7939
- *
7940
- * @param void
7941
- * @return void
7942
- */
7943
- disable: function () {
7944
- this.active = false;
7945
- },
7946
-
7947
- /**
7948
- * reset
7949
- *
7950
- * Rests the form validation to be used again
7951
- *
7952
- * @date 6/9/18
7953
- * @since 5.7.5
7954
- *
7955
- * @param jQuery $form The form element.
7956
- * @return void
7957
- */
7958
- reset: function ($form) {
7959
- getValidator($form).reset();
7960
- },
7961
-
7962
- /**
7963
- * addInputEvents
7964
- *
7965
- * Adds 'invalid' event listeners to HTML inputs.
7966
- *
7967
- * @date 4/9/18
7968
- * @since 5.7.5
7969
- *
7970
- * @param jQuery $el The element being added / readied.
7971
- * @return void
7972
- */
7973
- addInputEvents: function ($el) {
7974
- // Bug exists in Safari where custom "invalid" handeling prevents draft from saving.
7975
- if (acf.get('browser') === 'safari') return; // vars
7976
-
7977
- var $inputs = $('.acf-field [name]', $el); // check
7978
-
7979
- if ($inputs.length) {
7980
- this.on($inputs, 'invalid', 'onInvalid');
7981
- }
7982
- },
7983
-
7984
- /**
7985
- * onInvalid
7986
- *
7987
- * Callback for the 'invalid' event.
7988
- *
7989
- * @date 4/9/18
7990
- * @since 5.7.5
7991
- *
7992
- * @param object e The event object.
7993
- * @param jQuery $el The input element.
7994
- * @return void
7995
- */
7996
- onInvalid: function (e, $el) {
7997
- // prevent default
7998
- // - prevents browser error message
7999
- // - also fixes chrome bug where 'hidden-by-tab' field throws focus error
8000
- e.preventDefault(); // vars
8001
-
8002
- var $form = $el.closest('form'); // check form exists
8003
-
8004
- if ($form.length) {
8005
- // add error to validator
8006
- getValidator($form).addError({
8007
- input: $el.attr('name'),
8008
- message: acf.strEscape(e.target.validationMessage)
8009
- }); // trigger submit on $form
8010
- // - allows for "save", "preview" and "publish" to work
8011
-
8012
- submitFormDebounced($form);
8013
- }
8014
- },
8015
-
8016
- /**
8017
- * onClickSubmit
8018
- *
8019
- * Callback when clicking submit.
8020
- *
8021
- * @date 4/9/18
8022
- * @since 5.7.5
8023
- *
8024
- * @param object e The event object.
8025
- * @param jQuery $el The input element.
8026
- * @return void
8027
- */
8028
- onClickSubmit: function (e, $el) {
8029
- // store the "click event" for later use in this.onSubmit()
8030
- this.set('originalEvent', e);
8031
- },
8032
-
8033
- /**
8034
- * onClickSave
8035
- *
8036
- * Set ignore to true when saving a draft.
8037
- *
8038
- * @date 4/9/18
8039
- * @since 5.7.5
8040
- *
8041
- * @param object e The event object.
8042
- * @param jQuery $el The input element.
8043
- * @return void
8044
- */
8045
- onClickSave: function (e, $el) {
8046
- this.set('ignore', true);
8047
- },
8048
-
8049
- /**
8050
- * onClickSubmitGutenberg
8051
- *
8052
- * Custom validation event for the gutenberg editor.
8053
- *
8054
- * @date 29/10/18
8055
- * @since 5.8.0
8056
- *
8057
- * @param object e The event object.
8058
- * @param jQuery $el The input element.
8059
- * @return void
8060
- */
8061
- onClickSubmitGutenberg: function (e, $el) {
8062
- // validate
8063
- var valid = acf.validateForm({
8064
- form: $('#editor'),
8065
- event: e,
8066
- reset: true,
8067
- failure: function ($form, validator) {
8068
- var $notice = validator.get('notice').$el;
8069
- $notice.appendTo('.components-notice-list');
8070
- $notice.find('.acf-notice-dismiss').removeClass('small');
8071
- }
8072
- }); // if not valid, stop event and allow validation to continue
8073
-
8074
- if (!valid) {
8075
- e.preventDefault();
8076
- e.stopImmediatePropagation();
8077
- }
8078
- },
8079
-
8080
- /**
8081
- * onSubmitPost
8082
- *
8083
- * Callback when the 'post' form is submit.
8084
- *
8085
- * @date 5/3/19
8086
- * @since 5.7.13
8087
- *
8088
- * @param object e The event object.
8089
- * @param jQuery $el The input element.
8090
- * @return void
8091
- */
8092
- onSubmitPost: function (e, $el) {
8093
- // Check if is preview.
8094
- if ($('input#wp-preview').val() === 'dopreview') {
8095
- // Ignore validation.
8096
- this.set('ignore', true); // Unlock form to fix conflict with core "submit.edit-post" event causing all submit buttons to be disabled.
8097
-
8098
- acf.unlockForm($el);
8099
- }
8100
- },
8101
-
8102
- /**
8103
- * onSubmit
8104
- *
8105
- * Callback when the form is submit.
8106
- *
8107
- * @date 4/9/18
8108
- * @since 5.7.5
8109
- *
8110
- * @param object e The event object.
8111
- * @param jQuery $el The input element.
8112
- * @return void
8113
- */
8114
- onSubmit: function (e, $el) {
8115
- // Allow form to submit if...
8116
- if ( // Validation has been disabled.
8117
- !this.active // Or this event is to be ignored.
8118
- || this.get('ignore') // Or this event has already been prevented.
8119
- || e.isDefaultPrevented()) {
8120
- // Return early and call reset function.
8121
- return this.allowSubmit();
8122
- } // Validate form.
8123
-
8124
-
8125
- var valid = acf.validateForm({
8126
- form: $el,
8127
- event: this.get('originalEvent')
8128
- }); // If not valid, stop event to prevent form submit.
8129
-
8130
- if (!valid) {
8131
- e.preventDefault();
8132
- }
8133
- },
8134
-
8135
- /**
8136
- * allowSubmit
8137
- *
8138
- * Resets data during onSubmit when the form is allowed to submit.
8139
- *
8140
- * @date 5/3/19
8141
- * @since 5.7.13
8142
- *
8143
- * @param void
8144
- * @return void
8145
- */
8146
- allowSubmit: function () {
8147
- // Reset "ignore" state.
8148
- this.set('ignore', false); // Reset "originalEvent" object.
8149
-
8150
- this.set('originalEvent', false); // Return true
8151
-
8152
- return true;
8153
- }
8154
- });
8155
- var gutenbergValidation = new acf.Model({
8156
- wait: 'prepare',
8157
- initialize: function () {
8158
- // Bail early if not Gutenberg.
8159
- if (!acf.isGutenberg()) {
8160
- return;
8161
- } // Custommize the editor.
8162
-
8163
-
8164
- this.customizeEditor();
8165
- },
8166
- customizeEditor: function () {
8167
- // Extract vars.
8168
- var editor = wp.data.dispatch('core/editor');
8169
- var editorSelect = wp.data.select('core/editor');
8170
- var notices = wp.data.dispatch('core/notices'); // Backup original method.
8171
-
8172
- var savePost = editor.savePost; // Listen for changes to post status and perform actions:
8173
- // a) Enable validation for "publish" action.
8174
- // b) Remember last non "publish" status used for restoring after validation fail.
8175
-
8176
- var useValidation = false;
8177
- var lastPostStatus = '';
8178
- wp.data.subscribe(function () {
8179
- var postStatus = editorSelect.getEditedPostAttribute('status');
8180
- useValidation = postStatus === 'publish';
8181
- lastPostStatus = postStatus !== 'publish' ? postStatus : lastPostStatus;
8182
- }); // Create validation version.
8183
-
8184
- editor.savePost = function (options) {
8185
- options = options || {}; // Backup vars.
8186
-
8187
- var _this = this;
8188
-
8189
- var _args = arguments; // Perform validation within a Promise.
8190
-
8191
- return new Promise(function (resolve, reject) {
8192
- // Bail early if is autosave or preview.
8193
- if (options.isAutosave || options.isPreview) {
8194
- return resolve('Validation ignored (autosave).');
8195
- } // Bail early if validation is not neeed.
8196
-
8197
-
8198
- if (!useValidation) {
8199
- return resolve('Validation ignored (draft).');
8200
- } // Validate the editor form.
8201
-
8202
-
8203
- var valid = acf.validateForm({
8204
- form: $('#editor'),
8205
- reset: true,
8206
- complete: function ($form, validator) {
8207
- // Always unlock the form after AJAX.
8208
- editor.unlockPostSaving('acf');
8209
- },
8210
- failure: function ($form, validator) {
8211
- // Get validation error and append to Gutenberg notices.
8212
- var notice = validator.get('notice');
8213
- notices.createErrorNotice(notice.get('text'), {
8214
- id: 'acf-validation',
8215
- isDismissible: true
8216
- });
8217
- notice.remove(); // Restore last non "publish" status.
8218
-
8219
- if (lastPostStatus) {
8220
- editor.editPost({
8221
- status: lastPostStatus
8222
- });
8223
- } // Rejext promise and prevent savePost().
8224
-
8225
-
8226
- reject('Validation failed.');
8227
- },
8228
- success: function () {
8229
- notices.removeNotice('acf-validation'); // Resolve promise and allow savePost().
8230
-
8231
- resolve('Validation success.');
8232
- }
8233
- }); // Resolve promise and allow savePost() if no validation is needed.
8234
-
8235
- if (valid) {
8236
- resolve('Validation bypassed.'); // Otherwise, lock the form and wait for AJAX response.
8237
- } else {
8238
- editor.lockPostSaving('acf');
8239
- }
8240
- }).then(function () {
8241
- return savePost.apply(_this, _args);
8242
- });
8243
- };
8244
- }
8245
- });
8246
- })(jQuery);
8247
-
8248
- (function ($, undefined) {
8249
- /**
8250
- * refreshHelper
8251
- *
8252
- * description
8253
- *
8254
- * @date 1/7/18
8255
- * @since 5.6.9
8256
- *
8257
- * @param type $var Description. Default.
8258
- * @return type Description.
8259
- */
8260
- var refreshHelper = new acf.Model({
8261
- priority: 90,
8262
- actions: {
8263
- 'new_field': 'refresh',
8264
- 'show_field': 'refresh',
8265
- 'hide_field': 'refresh',
8266
- 'remove_field': 'refresh',
8267
- 'unmount_field': 'refresh',
8268
- 'remount_field': 'refresh'
8269
- },
8270
- refresh: function () {
8271
- acf.refresh();
8272
- }
8273
- });
8274
- /**
8275
- * mountHelper
8276
- *
8277
- * Adds compatiblity for the 'unmount' and 'remount' actions added in 5.8.0
8278
- *
8279
- * @date 7/3/19
8280
- * @since 5.7.14
8281
- *
8282
- * @param void
8283
- * @return void
8284
- */
8285
-
8286
- var mountHelper = new acf.Model({
8287
- priority: 1,
8288
- actions: {
8289
- 'sortstart': 'onSortstart',
8290
- 'sortstop': 'onSortstop'
8291
- },
8292
- onSortstart: function ($item) {
8293
- acf.doAction('unmount', $item);
8294
- },
8295
- onSortstop: function ($item) {
8296
- acf.doAction('remount', $item);
8297
- }
8298
- });
8299
- /**
8300
- * sortableHelper
8301
- *
8302
- * Adds compatibility for sorting a <tr> element
8303
- *
8304
- * @date 6/3/18
8305
- * @since 5.6.9
8306
- *
8307
- * @param void
8308
- * @return void
8309
- */
8310
-
8311
- var sortableHelper = new acf.Model({
8312
- actions: {
8313
- 'sortstart': 'onSortstart'
8314
- },
8315
- onSortstart: function ($item, $placeholder) {
8316
- // if $item is a tr, apply some css to the elements
8317
- if ($item.is('tr')) {
8318
- // replace $placeholder children with a single td
8319
- // fixes "width calculation issues" due to conditional logic hiding some children
8320
- $placeholder.html('<td style="padding:0;" colspan="' + $placeholder.children().length + '"></td>'); // add helper class to remove absolute positioning
8321
-
8322
- $item.addClass('acf-sortable-tr-helper'); // set fixed widths for children
8323
-
8324
- $item.children().each(function () {
8325
- $(this).width($(this).width());
8326
- }); // mimic height
8327
-
8328
- $placeholder.height($item.height() + 'px'); // remove class
8329
-
8330
- $item.removeClass('acf-sortable-tr-helper');
8331
- }
8332
- }
8333
- });
8334
- /**
8335
- * duplicateHelper
8336
- *
8337
- * Fixes browser bugs when duplicating an element
8338
- *
8339
- * @date 6/3/18
8340
- * @since 5.6.9
8341
- *
8342
- * @param void
8343
- * @return void
8344
- */
8345
-
8346
- var duplicateHelper = new acf.Model({
8347
- actions: {
8348
- 'after_duplicate': 'onAfterDuplicate'
8349
- },
8350
- onAfterDuplicate: function ($el, $el2) {
8351
- // get original values
8352
- var vals = [];
8353
- $el.find('select').each(function (i) {
8354
- vals.push($(this).val());
8355
- }); // set duplicate values
8356
-
8357
- $el2.find('select').each(function (i) {
8358
- $(this).val(vals[i]);
8359
- });
8360
- }
8361
- });
8362
- /**
8363
- * tableHelper
8364
- *
8365
- * description
8366
- *
8367
- * @date 6/3/18
8368
- * @since 5.6.9
8369
- *
8370
- * @param type $var Description. Default.
8371
- * @return type Description.
8372
- */
8373
-
8374
- var tableHelper = new acf.Model({
8375
- id: 'tableHelper',
8376
- priority: 20,
8377
- actions: {
8378
- 'refresh': 'renderTables'
8379
- },
8380
- renderTables: function ($el) {
8381
- // loop
8382
- var self = this;
8383
- $('.acf-table:visible').each(function () {
8384
- self.renderTable($(this));
8385
- });
8386
- },
8387
- renderTable: function ($table) {
8388
- // vars
8389
- var $ths = $table.find('> thead > tr:visible > th[data-key]');
8390
- var $tds = $table.find('> tbody > tr:visible > td[data-key]'); // bail early if no thead
8391
-
8392
- if (!$ths.length || !$tds.length) {
8393
- return false;
8394
- } // visiblity
8395
-
8396
-
8397
- $ths.each(function (i) {
8398
- // vars
8399
- var $th = $(this);
8400
- var key = $th.data('key');
8401
- var $cells = $tds.filter('[data-key="' + key + '"]');
8402
- var $hidden = $cells.filter('.acf-hidden'); // always remove empty and allow cells to be hidden
8403
-
8404
- $cells.removeClass('acf-empty'); // hide $th if all cells are hidden
8405
-
8406
- if ($cells.length === $hidden.length) {
8407
- acf.hide($th); // force all hidden cells to appear empty
8408
- } else {
8409
- acf.show($th);
8410
- $hidden.addClass('acf-empty');
8411
- }
8412
- }); // clear width
8413
-
8414
- $ths.css('width', 'auto'); // get visible
8415
-
8416
- $ths = $ths.not('.acf-hidden'); // vars
8417
-
8418
- var availableWidth = 100;
8419
- var colspan = $ths.length; // set custom widths first
8420
-
8421
- var $fixedWidths = $ths.filter('[data-width]');
8422
- $fixedWidths.each(function () {
8423
- var width = $(this).data('width');
8424
- $(this).css('width', width + '%');
8425
- availableWidth -= width;
8426
- }); // set auto widths
8427
-
8428
- var $auoWidths = $ths.not('[data-width]');
8429
-
8430
- if ($auoWidths.length) {
8431
- var width = availableWidth / $auoWidths.length;
8432
- $auoWidths.css('width', width + '%');
8433
- availableWidth = 0;
8434
- } // avoid stretching issue
8435
-
8436
-
8437
- if (availableWidth > 0) {
8438
- $ths.last().css('width', 'auto');
8439
- } // update colspan on collapsed
8440
-
8441
-
8442
- $tds.filter('.-collapsed-target').each(function () {
8443
- // vars
8444
- var $td = $(this); // check if collapsed
8445
-
8446
- if ($td.parent().hasClass('-collapsed')) {
8447
- $td.attr('colspan', $ths.length);
8448
- } else {
8449
- $td.removeAttr('colspan');
8450
- }
8451
- });
8452
- }
8453
- });
8454
- /**
8455
- * fieldsHelper
8456
- *
8457
- * description
8458
- *
8459
- * @date 6/3/18
8460
- * @since 5.6.9
8461
- *
8462
- * @param type $var Description. Default.
8463
- * @return type Description.
8464
- */
8465
-
8466
- var fieldsHelper = new acf.Model({
8467
- id: 'fieldsHelper',
8468
- priority: 30,
8469
- actions: {
8470
- 'refresh': 'renderGroups'
8471
- },
8472
- renderGroups: function () {
8473
- // loop
8474
- var self = this;
8475
- $('.acf-fields:visible').each(function () {
8476
- self.renderGroup($(this));
8477
- });
8478
- },
8479
- renderGroup: function ($el) {
8480
- // vars
8481
- var top = 0;
8482
- var height = 0;
8483
- var $row = $(); // get fields
8484
-
8485
- var $fields = $el.children('.acf-field[data-width]:visible'); // bail early if no fields
8486
-
8487
- if (!$fields.length) {
8488
- return false;
8489
- } // bail ealry if is .-left
8490
-
8491
-
8492
- if ($el.hasClass('-left')) {
8493
- $fields.removeAttr('data-width');
8494
- $fields.css('width', 'auto');
8495
- return false;
8496
- } // reset fields
8497
-
8498
-
8499
- $fields.removeClass('-r0 -c0').css({
8500
- 'min-height': 0
8501
- }); // loop
8502
-
8503
- $fields.each(function (i) {
8504
- // vars
8505
- var $field = $(this);
8506
- var position = $field.position();
8507
- var thisTop = Math.ceil(position.top);
8508
- var thisLeft = Math.ceil(position.left); // detect change in row
8509
-
8510
- if ($row.length && thisTop > top) {
8511
- // set previous heights
8512
- $row.css({
8513
- 'min-height': height + 'px'
8514
- }); // update position due to change in row above
8515
-
8516
- position = $field.position();
8517
- thisTop = Math.ceil(position.top);
8518
- thisLeft = Math.ceil(position.left); // reset vars
8519
-
8520
- top = 0;
8521
- height = 0;
8522
- $row = $();
8523
- } // rtl
8524
-
8525
-
8526
- if (acf.get('rtl')) {
8527
- thisLeft = Math.ceil($field.parent().width() - (position.left + $field.outerWidth()));
8528
- } // add classes
8529
-
8530
-
8531
- if (thisTop == 0) {
8532
- $field.addClass('-r0');
8533
- } else if (thisLeft == 0) {
8534
- $field.addClass('-c0');
8535
- } // get height after class change
8536
- // - add 1 for subpixel rendering
8537
-
8538
-
8539
- var thisHeight = Math.ceil($field.outerHeight()) + 1; // set height
8540
-
8541
- height = Math.max(height, thisHeight); // set y
8542
-
8543
- top = Math.max(top, thisTop); // append
8544
-
8545
- $row = $row.add($field);
8546
- }); // clean up
8547
-
8548
- if ($row.length) {
8549
- $row.css({
8550
- 'min-height': height + 'px'
8551
- });
8552
- }
8553
- }
8554
- });
8555
- /**
8556
- * Adds a body class when holding down the "shift" key.
8557
- *
8558
- * @date 06/05/2020
8559
- * @since 5.9.0
8560
- */
8561
-
8562
- var bodyClassShiftHelper = new acf.Model({
8563
- id: 'bodyClassShiftHelper',
8564
- events: {
8565
- 'keydown': 'onKeyDown',
8566
- 'keyup': 'onKeyUp'
8567
- },
8568
- isShiftKey: function (e) {
8569
- return e.keyCode === 16;
8570
- },
8571
- onKeyDown: function (e) {
8572
- if (this.isShiftKey(e)) {
8573
- $('body').addClass('acf-keydown-shift');
8574
- }
8575
- },
8576
- onKeyUp: function (e) {
8577
- if (this.isShiftKey(e)) {
8578
- $('body').removeClass('acf-keydown-shift');
8579
- }
8580
- }
8581
- });
8582
- })(jQuery);
8583
-
8584
- (function ($, undefined) {
8585
- /**
8586
- * acf.newCompatibility
8587
- *
8588
- * Inserts a new __proto__ object compatibility layer
8589
- *
8590
- * @date 15/2/18
8591
- * @since 5.6.9
8592
- *
8593
- * @param object instance The object to modify.
8594
- * @param object compatibilty Optional. The compatibilty layer.
8595
- * @return object compatibilty
8596
- */
8597
- acf.newCompatibility = function (instance, compatibilty) {
8598
- // defaults
8599
- compatibilty = compatibilty || {}; // inherit __proto_-
8600
-
8601
- compatibilty.__proto__ = instance.__proto__; // inject
8602
-
8603
- instance.__proto__ = compatibilty; // reference
8604
-
8605
- instance.compatibility = compatibilty; // return
8606
-
8607
- return compatibilty;
8608
- };
8609
- /**
8610
- * acf.getCompatibility
8611
- *
8612
- * Returns the compatibility layer for a given instance
8613
- *
8614
- * @date 13/3/18
8615
- * @since 5.6.9
8616
- *
8617
- * @param object instance The object to look in.
8618
- * @return object|null compatibility The compatibility object or null on failure.
8619
- */
8620
-
8621
-
8622
- acf.getCompatibility = function (instance) {
8623
- return instance.compatibility || null;
8624
- };
8625
- /**
8626
- * acf (compatibility)
8627
- *
8628
- * Compatibility layer for the acf object
8629
- *
8630
- * @date 15/2/18
8631
- * @since 5.6.9
8632
- *
8633
- * @param void
8634
- * @return void
8635
- */
8636
-
8637
-
8638
- var _acf = acf.newCompatibility(acf, {
8639
- // storage
8640
- l10n: {},
8641
- o: {},
8642
- fields: {},
8643
- // changed function names
8644
- update: acf.set,
8645
- add_action: acf.addAction,
8646
- remove_action: acf.removeAction,
8647
- do_action: acf.doAction,
8648
- add_filter: acf.addFilter,
8649
- remove_filter: acf.removeFilter,
8650
- apply_filters: acf.applyFilters,
8651
- parse_args: acf.parseArgs,
8652
- disable_el: acf.disable,
8653
- disable_form: acf.disable,
8654
- enable_el: acf.enable,
8655
- enable_form: acf.enable,
8656
- update_user_setting: acf.updateUserSetting,
8657
- prepare_for_ajax: acf.prepareForAjax,
8658
- is_ajax_success: acf.isAjaxSuccess,
8659
- remove_el: acf.remove,
8660
- remove_tr: acf.remove,
8661
- str_replace: acf.strReplace,
8662
- render_select: acf.renderSelect,
8663
- get_uniqid: acf.uniqid,
8664
- serialize_form: acf.serialize,
8665
- esc_html: acf.strEscape,
8666
- str_sanitize: acf.strSanitize
8667
- });
8668
-
8669
- _acf._e = function (k1, k2) {
8670
- // defaults
8671
- k1 = k1 || '';
8672
- k2 = k2 || ''; // compability
8673
-
8674
- var compatKey = k2 ? k1 + '.' + k2 : k1;
8675
- var compats = {
8676
- 'image.select': 'Select Image',
8677
- 'image.edit': 'Edit Image',
8678
- 'image.update': 'Update Image'
8679
- };
8680
-
8681
- if (compats[compatKey]) {
8682
- return acf.__(compats[compatKey]);
8683
- } // try k1
8684
-
8685
-
8686
- var string = this.l10n[k1] || ''; // try k2
8687
-
8688
- if (k2) {
8689
- string = string[k2] || '';
8690
- } // return
8691
-
8692
-
8693
- return string;
8694
- };
8695
-
8696
- _acf.get_selector = function (s) {
8697
- // vars
8698
- var selector = '.acf-field'; // bail early if no search
8699
-
8700
- if (!s) {
8701
- return selector;
8702
- } // compatibility with object
8703
-
8704
-
8705
- if ($.isPlainObject(s)) {
8706
- if ($.isEmptyObject(s)) {
8707
- return selector;
8708
- } else {
8709
- for (var k in s) {
8710
- s = s[k];
8711
- break;
8712
- }
8713
- }
8714
- } // append
8715
-
8716
-
8717
- selector += '-' + s; // replace underscores (split/join replaces all and is faster than regex!)
8718
-
8719
- selector = acf.strReplace('_', '-', selector); // remove potential double up
8720
-
8721
- selector = acf.strReplace('field-field-', 'field-', selector); // return
8722
-
8723
- return selector;
8724
- };
8725
-
8726
- _acf.get_fields = function (s, $el, all) {
8727
- // args
8728
- var args = {
8729
- is: s || '',
8730
- parent: $el || false,
8731
- suppressFilters: all || false
8732
- }; // change 'field_123' to '.acf-field-123'
8733
-
8734
- if (args.is) {
8735
- args.is = this.get_selector(args.is);
8736
- } // return
8737
-
8738
-
8739
- return acf.findFields(args);
8740
- };
8741
-
8742
- _acf.get_field = function (s, $el) {
8743
- // get fields
8744
- var $fields = this.get_fields.apply(this, arguments); // return
8745
-
8746
- if ($fields.length) {
8747
- return $fields.first();
8748
- } else {
8749
- return false;
8750
- }
8751
- };
8752
-
8753
- _acf.get_closest_field = function ($el, s) {
8754
- return $el.closest(this.get_selector(s));
8755
- };
8756
-
8757
- _acf.get_field_wrap = function ($el) {
8758
- return $el.closest(this.get_selector());
8759
- };
8760
-
8761
- _acf.get_field_key = function ($field) {
8762
- return $field.data('key');
8763
- };
8764
-
8765
- _acf.get_field_type = function ($field) {
8766
- return $field.data('type');
8767
- };
8768
-
8769
- _acf.get_data = function ($el, defaults) {
8770
- return acf.parseArgs($el.data(), defaults);
8771
- };
8772
-
8773
- _acf.maybe_get = function (obj, key, value) {
8774
- // default
8775
- if (value === undefined) {
8776
- value = null;
8777
- } // get keys
8778
-
8779
-
8780
- keys = String(key).split('.'); // acf.isget
8781
-
8782
- for (var i = 0; i < keys.length; i++) {
8783
- if (!obj.hasOwnProperty(keys[i])) {
8784
- return value;
8785
- }
8786
-
8787
- obj = obj[keys[i]];
8788
- }
8789
-
8790
- return obj;
8791
- };
8792
- /**
8793
- * hooks
8794
- *
8795
- * Modify add_action and add_filter functions to add compatibility with changed $field parameter
8796
- * Using the acf.add_action() or acf.add_filter() functions will interpret new field parameters as jQuery $field
8797
- *
8798
- * @date 12/5/18
8799
- * @since 5.6.9
8800
- *
8801
- * @param void
8802
- * @return void
8803
- */
8804
-
8805
-
8806
- var compatibleArgument = function (arg) {
8807
- return arg instanceof acf.Field ? arg.$el : arg;
8808
- };
8809
-
8810
- var compatibleArguments = function (args) {
8811
- return acf.arrayArgs(args).map(compatibleArgument);
8812
- };
8813
-
8814
- var compatibleCallback = function (origCallback) {
8815
- return function () {
8816
- // convert to compatible arguments
8817
- if (arguments.length) {
8818
- var args = compatibleArguments(arguments); // add default argument for 'ready', 'append' and 'load' events
8819
- } else {
8820
- var args = [$(document)];
8821
- } // return
8822
-
8823
-
8824
- return origCallback.apply(this, args);
8825
- };
8826
- };
8827
-
8828
- _acf.add_action = function (action, callback, priority, context) {
8829
- // handle multiple actions
8830
- var actions = action.split(' ');
8831
- var length = actions.length;
8832
-
8833
- if (length > 1) {
8834
- for (var i = 0; i < length; i++) {
8835
- action = actions[i];
8836
-
8837
- _acf.add_action.apply(this, arguments);
8838
- }
8839
-
8840
- return this;
8841
- } // single
8842
-
8843
-
8844
- var callback = compatibleCallback(callback);
8845
- return acf.addAction.apply(this, arguments);
8846
- };
8847
-
8848
- _acf.add_filter = function (action, callback, priority, context) {
8849
- var callback = compatibleCallback(callback);
8850
- return acf.addFilter.apply(this, arguments);
8851
- };
8852
- /*
8853
- * acf.model
8854
- *
8855
- * This model acts as a scafold for action.event driven modules
8856
- *
8857
- * @type object
8858
- * @date 8/09/2014
8859
- * @since 5.0.0
8860
- *
8861
- * @param (object)
8862
- * @return (object)
8863
- */
8864
-
8865
-
8866
- _acf.model = {
8867
- actions: {},
8868
- filters: {},
8869
- events: {},
8870
- extend: function (args) {
8871
- // extend
8872
- var model = $.extend({}, this, args); // setup actions
8873
-
8874
- $.each(model.actions, function (name, callback) {
8875
- model._add_action(name, callback);
8876
- }); // setup filters
8877
-
8878
- $.each(model.filters, function (name, callback) {
8879
- model._add_filter(name, callback);
8880
- }); // setup events
8881
-
8882
- $.each(model.events, function (name, callback) {
8883
- model._add_event(name, callback);
8884
- }); // return
8885
-
8886
- return model;
8887
- },
8888
- _add_action: function (name, callback) {
8889
- // split
8890
- var model = this,
8891
- data = name.split(' '); // add missing priority
8892
-
8893
- var name = data[0] || '',
8894
- priority = data[1] || 10; // add action
8895
-
8896
- acf.add_action(name, model[callback], priority, model);
8897
- },
8898
- _add_filter: function (name, callback) {
8899
- // split
8900
- var model = this,
8901
- data = name.split(' '); // add missing priority
8902
-
8903
- var name = data[0] || '',
8904
- priority = data[1] || 10; // add action
8905
-
8906
- acf.add_filter(name, model[callback], priority, model);
8907
- },
8908
- _add_event: function (name, callback) {
8909
- // vars
8910
- var model = this,
8911
- i = name.indexOf(' '),
8912
- event = i > 0 ? name.substr(0, i) : name,
8913
- selector = i > 0 ? name.substr(i + 1) : ''; // event
8914
-
8915
- var fn = function (e) {
8916
- // append $el to event object
8917
- e.$el = $(this); // append $field to event object (used in field group)
8918
-
8919
- if (acf.field_group) {
8920
- e.$field = e.$el.closest('.acf-field-object');
8921
- } // event
8922
-
8923
-
8924
- if (typeof model.event === 'function') {
8925
- e = model.event(e);
8926
- } // callback
8927
-
8928
-
8929
- model[callback].apply(model, arguments);
8930
- }; // add event
8931
-
8932
-
8933
- if (selector) {
8934
- $(document).on(event, selector, fn);
8935
- } else {
8936
- $(document).on(event, fn);
8937
- }
8938
- },
8939
- get: function (name, value) {
8940
- // defaults
8941
- value = value || null; // get
8942
-
8943
- if (typeof this[name] !== 'undefined') {
8944
- value = this[name];
8945
- } // return
8946
-
8947
-
8948
- return value;
8949
- },
8950
- set: function (name, value) {
8951
- // set
8952
- this[name] = value; // function for 3rd party
8953
-
8954
- if (typeof this['_set_' + name] === 'function') {
8955
- this['_set_' + name].apply(this);
8956
- } // return for chaining
8957
-
8958
-
8959
- return this;
8960
- }
8961
- };
8962
- /*
8963
- * field
8964
- *
8965
- * This model sets up many of the field's interactions
8966
- *
8967
- * @type function
8968
- * @date 21/02/2014
8969
- * @since 3.5.1
8970
- *
8971
- * @param n/a
8972
- * @return n/a
8973
- */
8974
-
8975
- _acf.field = acf.model.extend({
8976
- type: '',
8977
- o: {},
8978
- $field: null,
8979
- _add_action: function (name, callback) {
8980
- // vars
8981
- var model = this; // update name
8982
-
8983
- name = name + '_field/type=' + model.type; // add action
8984
-
8985
- acf.add_action(name, function ($field) {
8986
- // focus
8987
- model.set('$field', $field); // callback
8988
-
8989
- model[callback].apply(model, arguments);
8990
- });
8991
- },
8992
- _add_filter: function (name, callback) {
8993
- // vars
8994
- var model = this; // update name
8995
-
8996
- name = name + '_field/type=' + model.type; // add action
8997
-
8998
- acf.add_filter(name, function ($field) {
8999
- // focus
9000
- model.set('$field', $field); // callback
9001
-
9002
- model[callback].apply(model, arguments);
9003
- });
9004
- },
9005
- _add_event: function (name, callback) {
9006
- // vars
9007
- var model = this,
9008
- event = name.substr(0, name.indexOf(' ')),
9009
- selector = name.substr(name.indexOf(' ') + 1),
9010
- context = acf.get_selector(model.type); // add event
9011
-
9012
- $(document).on(event, context + ' ' + selector, function (e) {
9013
- // vars
9014
- var $el = $(this);
9015
- var $field = acf.get_closest_field($el, model.type); // bail early if no field
9016
-
9017
- if (!$field.length) return; // focus
9018
-
9019
- if (!$field.is(model.$field)) {
9020
- model.set('$field', $field);
9021
- } // append to event
9022
-
9023
-
9024
- e.$el = $el;
9025
- e.$field = $field; // callback
9026
-
9027
- model[callback].apply(model, [e]);
9028
- });
9029
- },
9030
- _set_$field: function () {
9031
- // callback
9032
- if (typeof this.focus === 'function') {
9033
- this.focus();
9034
- }
9035
- },
9036
- // depreciated
9037
- doFocus: function ($field) {
9038
- return this.set('$field', $field);
9039
- }
9040
- });
9041
- /**
9042
- * validation
9043
- *
9044
- * description
9045
- *
9046
- * @date 15/2/18
9047
- * @since 5.6.9
9048
- *
9049
- * @param type $var Description. Default.
9050
- * @return type Description.
9051
- */
9052
-
9053
- var _validation = acf.newCompatibility(acf.validation, {
9054
- remove_error: function ($field) {
9055
- acf.getField($field).removeError();
9056
- },
9057
- add_warning: function ($field, message) {
9058
- acf.getField($field).showNotice({
9059
- text: message,
9060
- type: 'warning',
9061
- timeout: 1000
9062
- });
9063
- },
9064
- fetch: acf.validateForm,
9065
- enableSubmit: acf.enableSubmit,
9066
- disableSubmit: acf.disableSubmit,
9067
- showSpinner: acf.showSpinner,
9068
- hideSpinner: acf.hideSpinner,
9069
- unlockForm: acf.unlockForm,
9070
- lockForm: acf.lockForm
9071
- });
9072
- /**
9073
- * tooltip
9074
- *
9075
- * description
9076
- *
9077
- * @date 15/2/18
9078
- * @since 5.6.9
9079
- *
9080
- * @param type $var Description. Default.
9081
- * @return type Description.
9082
- */
9083
-
9084
-
9085
- _acf.tooltip = {
9086
- tooltip: function (text, $el) {
9087
- var tooltip = acf.newTooltip({
9088
- text: text,
9089
- target: $el
9090
- }); // return
9091
-
9092
- return tooltip.$el;
9093
- },
9094
- temp: function (text, $el) {
9095
- var tooltip = acf.newTooltip({
9096
- text: text,
9097
- target: $el,
9098
- timeout: 250
9099
- });
9100
- },
9101
- confirm: function ($el, callback, text, button_y, button_n) {
9102
- var tooltip = acf.newTooltip({
9103
- confirm: true,
9104
- text: text,
9105
- target: $el,
9106
- confirm: function () {
9107
- callback(true);
9108
- },
9109
- cancel: function () {
9110
- callback(false);
9111
- }
9112
- });
9113
- },
9114
- confirm_remove: function ($el, callback) {
9115
- var tooltip = acf.newTooltip({
9116
- confirmRemove: true,
9117
- target: $el,
9118
- confirm: function () {
9119
- callback(true);
9120
- },
9121
- cancel: function () {
9122
- callback(false);
9123
- }
9124
- });
9125
- }
9126
- };
9127
- /**
9128
- * tooltip
9129
- *
9130
- * description
9131
- *
9132
- * @date 15/2/18
9133
- * @since 5.6.9
9134
- *
9135
- * @param type $var Description. Default.
9136
- * @return type Description.
9137
- */
9138
-
9139
- _acf.media = new acf.Model({
9140
- activeFrame: false,
9141
- actions: {
9142
- 'new_media_popup': 'onNewMediaPopup'
9143
- },
9144
- frame: function () {
9145
- return this.activeFrame;
9146
- },
9147
- onNewMediaPopup: function (popup) {
9148
- this.activeFrame = popup.frame;
9149
- },
9150
- popup: function (props) {
9151
- // update props
9152
- if (props.mime_types) {
9153
- props.allowedTypes = props.mime_types;
9154
- }
9155
-
9156
- if (props.id) {
9157
- props.attachment = props.id;
9158
- } // new
9159
-
9160
-
9161
- var popup = acf.newMediaPopup(props); // append
9162
-
9163
- /*
9164
- if( props.selected ) {
9165
- popup.selected = props.selected;
9166
- }
9167
- */
9168
- // return
9169
-
9170
- return popup.frame;
9171
- }
9172
- });
9173
- /**
9174
- * Select2
9175
- *
9176
- * description
9177
- *
9178
- * @date 11/6/18
9179
- * @since 5.6.9
9180
- *
9181
- * @param type $var Description. Default.
9182
- * @return type Description.
9183
- */
9184
-
9185
- _acf.select2 = {
9186
- init: function ($select, args, $field) {
9187
- // compatible args
9188
- if (args.allow_null) {
9189
- args.allowNull = args.allow_null;
9190
- }
9191
-
9192
- if (args.ajax_action) {
9193
- args.ajaxAction = args.ajax_action;
9194
- }
9195
-
9196
- if ($field) {
9197
- args.field = acf.getField($field);
9198
- } // return
9199
-
9200
-
9201
- return acf.newSelect2($select, args);
9202
- },
9203
- destroy: function ($select) {
9204
- return acf.getInstance($select).destroy();
9205
- }
9206
- };
9207
- /**
9208
- * postbox
9209
- *
9210
- * description
9211
- *
9212
- * @date 11/6/18
9213
- * @since 5.6.9
9214
- *
9215
- * @param type $var Description. Default.
9216
- * @return type Description.
9217
- */
9218
-
9219
- _acf.postbox = {
9220
- render: function (args) {
9221
- // compatible args
9222
- if (args.edit_url) {
9223
- args.editLink = args.edit_url;
9224
- }
9225
-
9226
- if (args.edit_title) {
9227
- args.editTitle = args.edit_title;
9228
- } // return
9229
-
9230
-
9231
- return acf.newPostbox(args);
9232
- }
9233
- };
9234
- /**
9235
- * acf.screen
9236
- *
9237
- * description
9238
- *
9239
- * @date 11/6/18
9240
- * @since 5.6.9
9241
- *
9242
- * @param type $var Description. Default.
9243
- * @return type Description.
9244
- */
9245
-
9246
- acf.newCompatibility(acf.screen, {
9247
- update: function () {
9248
- return this.set.apply(this, arguments);
9249
- },
9250
- fetch: acf.screen.check
9251
- });
9252
- _acf.ajax = acf.screen;
9253
  })(jQuery);
1
+ (function($, undefined){
2
+
3
+ // vars
4
+ var storage = [];
5
+
6
+ /**
7
+ * acf.Field
8
+ *
9
+ * description
10
+ *
11
+ * @date 23/3/18
12
+ * @since 5.6.9
13
+ *
14
+ * @param type $var Description. Default.
15
+ * @return type Description.
16
+ */
17
+
18
+ acf.Field = acf.Model.extend({
19
+
20
+ // field type
21
+ type: '',
22
+
23
+ // class used to avoid nested event triggers
24
+ eventScope: '.acf-field',
25
+
26
+ // initialize events on 'ready'
27
+ wait: 'ready',
28
+
29
+ /**
30
+ * setup
31
+ *
32
+ * Called during the constructor function to setup this field ready for initialization
33
+ *
34
+ * @date 8/5/18
35
+ * @since 5.6.9
36
+ *
37
+ * @param jQuery $field The field element.
38
+ * @return void
39
+ */
40
+
41
+ setup: function( $field ){
42
+
43
+ // set $el
44
+ this.$el = $field;
45
+
46
+ // inherit $field data
47
+ this.inherit( $field );
48
+
49
+ // inherit controll data
50
+ this.inherit( this.$control() );
51
+ },
52
+
53
+ /**
54
+ * val
55
+ *
56
+ * Sets or returns the field's value
57
+ *
58
+ * @date 8/5/18
59
+ * @since 5.6.9
60
+ *
61
+ * @param mixed val Optional. The value to set
62
+ * @return mixed
63
+ */
64
+
65
+ val: function( val ){
66
+
67
+ // Set.
68
+ if( val !== undefined ) {
69
+ return this.setValue( val );
70
+
71
+ // Get.
72
+ } else {
73
+ return this.prop('disabled') ? null : this.getValue();
74
+ }
75
+ },
76
+
77
+ /**
78
+ * getValue
79
+ *
80
+ * returns the field's value
81
+ *
82
+ * @date 8/5/18
83
+ * @since 5.6.9
84
+ *
85
+ * @param void
86
+ * @return mixed
87
+ */
88
+
89
+ getValue: function(){
90
+ return this.$input().val();
91
+ },
92
+
93
+ /**
94
+ * setValue
95
+ *
96
+ * sets the field's value and returns true if changed
97
+ *
98
+ * @date 8/5/18
99
+ * @since 5.6.9
100
+ *
101
+ * @param mixed val
102
+ * @return boolean. True if changed.
103
+ */
104
+
105
+ setValue: function( val ){
106
+ return acf.val( this.$input(), val );
107
+ },
108
+
109
+ /**
110
+ * __
111
+ *
112
+ * i18n helper to be removed
113
+ *
114
+ * @date 8/5/18
115
+ * @since 5.6.9
116
+ *
117
+ * @param type $var Description. Default.
118
+ * @return type Description.
119
+ */
120
+
121
+ __: function( string ){
122
+ return acf._e( this.type, string );
123
+ },
124
+
125
+ /**
126
+ * $control
127
+ *
128
+ * returns the control jQuery element used for inheriting data. Uses this.control setting.
129
+ *
130
+ * @date 8/5/18
131
+ * @since 5.6.9
132
+ *
133
+ * @param void
134
+ * @return jQuery
135
+ */
136
+
137
+ $control: function(){
138
+ return false;
139
+ },
140
+
141
+ /**
142
+ * $input
143
+ *
144
+ * returns the input jQuery element used for saving values. Uses this.input setting.
145
+ *
146
+ * @date 8/5/18
147
+ * @since 5.6.9
148
+ *
149
+ * @param void
150
+ * @return jQuery
151
+ */
152
+
153
+ $input: function(){
154
+ return this.$('[name]:first');
155
+ },
156
+
157
+ /**
158
+ * $inputWrap
159
+ *
160
+ * description
161
+ *
162
+ * @date 12/5/18
163
+ * @since 5.6.9
164
+ *
165
+ * @param type $var Description. Default.
166
+ * @return type Description.
167
+ */
168
+
169
+ $inputWrap: function(){
170
+ return this.$('.acf-input:first');
171
+ },
172
+
173
+ /**
174
+ * $inputWrap
175
+ *
176
+ * description
177
+ *
178
+ * @date 12/5/18
179
+ * @since 5.6.9
180
+ *
181
+ * @param type $var Description. Default.
182
+ * @return type Description.
183
+ */
184
+
185
+ $labelWrap: function(){
186
+ return this.$('.acf-label:first');
187
+ },
188
+
189
+ /**
190
+ * getInputName
191
+ *
192
+ * Returns the field's input name
193
+ *
194
+ * @date 8/5/18
195
+ * @since 5.6.9
196
+ *
197
+ * @param void
198
+ * @return string
199
+ */
200
+
201
+ getInputName: function(){
202
+ return this.$input().attr('name') || '';
203
+ },
204
+
205
+ /**
206
+ * parent
207
+ *
208
+ * returns the field's parent field or false on failure.
209
+ *
210
+ * @date 8/5/18
211
+ * @since 5.6.9
212
+ *
213
+ * @param void
214
+ * @return object|false
215
+ */
216
+
217
+ parent: function() {
218
+
219
+ // vars
220
+ var parents = this.parents();
221
+
222
+ // return
223
+ return parents.length ? parents[0] : false;
224
+ },
225
+
226
+ /**
227
+ * parents
228
+ *
229
+ * description
230
+ *
231
+ * @date 9/7/18
232
+ * @since 5.6.9
233
+ *
234
+ * @param type $var Description. Default.
235
+ * @return type Description.
236
+ */
237
+
238
+ parents: function(){
239
+
240
+ // vars
241
+ var $parents = this.$el.parents('.acf-field');
242
+
243
+ // convert
244
+ var parents = acf.getFields( $parents );
245
+
246
+ // return
247
+ return parents;
248
+ },
249
+
250
+ show: function( lockKey, context ){
251
+
252
+ // show field and store result
253
+ var changed = acf.show( this.$el, lockKey );
254
+
255
+ // do action if visibility has changed
256
+ if( changed ) {
257
+ this.prop('hidden', false);
258
+ acf.doAction('show_field', this, context);
259
+ }
260
+
261
+ // return
262
+ return changed;
263
+ },
264
+
265
+ hide: function( lockKey, context ){
266
+
267
+ // hide field and store result
268
+ var changed = acf.hide( this.$el, lockKey );
269
+
270
+ // do action if visibility has changed
271
+ if( changed ) {
272
+ this.prop('hidden', true);
273
+ acf.doAction('hide_field', this, context);
274
+ }
275
+
276
+ // return
277
+ return changed;
278
+ },
279
+
280
+ enable: function( lockKey, context ){
281
+
282
+ // enable field and store result
283
+ var changed = acf.enable( this.$el, lockKey );
284
+
285
+ // do action if disabled has changed
286
+ if( changed ) {
287
+ this.prop('disabled', false);
288
+ acf.doAction('enable_field', this, context);
289
+ }
290
+
291
+ // return
292
+ return changed;
293
+ },
294
+
295
+ disable: function( lockKey, context ){
296
+
297
+ // disabled field and store result
298
+ var changed = acf.disable( this.$el, lockKey );
299
+
300
+ // do action if disabled has changed
301
+ if( changed ) {
302
+ this.prop('disabled', true);
303
+ acf.doAction('disable_field', this, context);
304
+ }
305
+
306
+ // return
307
+ return changed;
308
+ },
309
+
310
+ showEnable: function( lockKey, context ){
311
+
312
+ // enable
313
+ this.enable.apply(this, arguments);
314
+
315
+ // show and return true if changed
316
+ return this.show.apply(this, arguments);
317
+ },
318
+
319
+ hideDisable: function( lockKey, context ){
320
+
321
+ // disable
322
+ this.disable.apply(this, arguments);
323
+
324
+ // hide and return true if changed
325
+ return this.hide.apply(this, arguments);
326
+ },
327
+
328
+ showNotice: function( props ){
329
+
330
+ // ensure object
331
+ if( typeof props !== 'object' ) {
332
+ props = { text: props };
333
+ }
334
+
335
+ // remove old notice
336
+ if( this.notice ) {
337
+ this.notice.remove();
338
+ }
339
+
340
+ // create new notice
341
+ props.target = this.$inputWrap();
342
+ this.notice = acf.newNotice( props );
343
+ },
344
+
345
+ removeNotice: function( timeout ){
346
+ if( this.notice ) {
347
+ this.notice.away( timeout || 0 );
348
+ this.notice = false;
349
+ }
350
+ },
351
+
352
+ showError: function( message ){
353
+
354
+ // add class
355
+ this.$el.addClass('acf-error');
356
+
357
+ // add message
358
+ if( message !== undefined ) {
359
+ this.showNotice({
360
+ text: message,
361
+ type: 'error',
362
+ dismiss: false
363
+ });
364
+ }
365
+
366
+ // action
367
+ acf.doAction('invalid_field', this);
368
+
369
+ // add event
370
+ this.$el.one('focus change', 'input, select, textarea', $.proxy( this.removeError, this ));
371
+ },
372
+
373
+ removeError: function(){
374
+
375
+ // remove class
376
+ this.$el.removeClass('acf-error');
377
+
378
+ // remove notice
379
+ this.removeNotice( 250 );
380
+
381
+ // action
382
+ acf.doAction('valid_field', this);
383
+ },
384
+
385
+ trigger: function( name, args, bubbles ){
386
+
387
+ // allow some events to bubble
388
+ if( name == 'invalidField' ) {
389
+ bubbles = true;
390
+ }
391
+
392
+ // return
393
+ return acf.Model.prototype.trigger.apply(this, [name, args, bubbles]);
394
+ },
395
+ });
396
+
397
+ /**
398
+ * newField
399
+ *
400
+ * description
401
+ *
402
+ * @date 14/12/17
403
+ * @since 5.6.5
404
+ *
405
+ * @param type $var Description. Default.
406
+ * @return type Description.
407
+ */
408
+
409
+ acf.newField = function( $field ){
410
+
411
+ // vars
412
+ var type = $field.data('type');
413
+ var mid = modelId( type );
414
+ var model = acf.models[ mid ] || acf.Field;
415
+
416
+ // instantiate
417
+ var field = new model( $field );
418
+
419
+ // actions
420
+ acf.doAction('new_field', field);
421
+
422
+ // return
423
+ return field;
424
+ };
425
+
426
+ /**
427
+ * mid
428
+ *
429
+ * Calculates the model ID for a field type
430
+ *
431
+ * @date 15/12/17
432
+ * @since 5.6.5
433
+ *
434
+ * @param string type
435
+ * @return string
436
+ */
437
+
438
+ var modelId = function( type ) {
439
+ return acf.strPascalCase( type || '' ) + 'Field';
440
+ };
441
+
442
+ /**
443
+ * registerFieldType
444
+ *
445
+ * description
446
+ *
447
+ * @date 14/12/17
448
+ * @since 5.6.5
449
+ *
450
+ * @param type $var Description. Default.
451
+ * @return type Description.
452
+ */
453
+
454
+ acf.registerFieldType = function( model ){
455
+
456
+ // vars
457
+ var proto = model.prototype;
458
+ var type = proto.type;
459
+ var mid = modelId( type );
460
+
461
+ // store model
462
+ acf.models[ mid ] = model;
463
+
464
+ // store reference
465
+ storage.push( type );
466
+ };
467
+
468
+ /**
469
+ * acf.getFieldType
470
+ *
471
+ * description
472
+ *
473
+ * @date 1/2/18
474
+ * @since 5.6.5
475
+ *
476
+ * @param type $var Description. Default.
477
+ * @return type Description.
478
+ */
479
+
480
+ acf.getFieldType = function( type ){
481
+ var mid = modelId( type );
482
+ return acf.models[ mid ] || false;
483
+ }
484
+
485
+ /**
486
+ * acf.getFieldTypes
487
+ *
488
+ * description
489
+ *
490
+ * @date 1/2/18
491
+ * @since 5.6.5
492
+ *
493
+ * @param type $var Description. Default.
494
+ * @return type Description.
495
+ */
496
+
497
+ acf.getFieldTypes = function( args ){
498
+
499
+ // defaults
500
+ args = acf.parseArgs(args, {
501
+ category: '',
502
+ // hasValue: true
503
+ });
504
+
505
+ // clonse available types
506
+ var types = [];
507
+
508
+ // loop
509
+ storage.map(function( type ){
510
+
511
+ // vars
512
+ var model = acf.getFieldType(type);
513
+ var proto = model.prototype;
514
+
515
+ // check operator
516
+ if( args.category && proto.category !== args.category ) {
517
+ return;
518
+ }
519
+
520
+ // append
521
+ types.push( model );
522
+ });
523
+
524
+ // return
525
+ return types;
526
+ };
527
+
528
  })(jQuery);
529
+ (function($, undefined){
530
+
531
+ /**
532
+ * findFields
533
+ *
534
+ * Returns a jQuery selection object of acf fields.
535
+ *
536
+ * @date 14/12/17
537
+ * @since 5.6.5
538
+ *
539
+ * @param object $args {
540
+ * Optional. Arguments to find fields.
541
+ *
542
+ * @type string key The field's key (data-attribute).
543
+ * @type string name The field's name (data-attribute).
544
+ * @type string type The field's type (data-attribute).
545
+ * @type string is jQuery selector to compare against.
546
+ * @type jQuery parent jQuery element to search within.
547
+ * @type jQuery sibling jQuery element to search alongside.
548
+ * @type limit int The number of fields to find.
549
+ * @type suppressFilters bool Whether to allow filters to add/remove results. Default behaviour will ignore clone fields.
550
+ * }
551
+ * @return jQuery
552
+ */
553
+
554
+ acf.findFields = function( args ){
555
+
556
+ // vars
557
+ var selector = '.acf-field';
558
+ var $fields = false;
559
+
560
+ // args
561
+ args = acf.parseArgs(args, {
562
+ key: '',
563
+ name: '',
564
+ type: '',
565
+ is: '',
566
+ parent: false,
567
+ sibling: false,
568
+ limit: false,
569
+ visible: false,
570
+ suppressFilters: false,
571
+ });
572
+
573
+ // filter args
574
+ if( !args.suppressFilters ) {
575
+ args = acf.applyFilters('find_fields_args', args);
576
+ }
577
+
578
+ // key
579
+ if( args.key ) {
580
+ selector += '[data-key="' + args.key + '"]';
581
+ }
582
+
583
+ // type
584
+ if( args.type ) {
585
+ selector += '[data-type="' + args.type + '"]';
586
+ }
587
+
588
+ // name
589
+ if( args.name ) {
590
+ selector += '[data-name="' + args.name + '"]';
591
+ }
592
+
593
+ // is
594
+ if( args.is ) {
595
+ selector += args.is;
596
+ }
597
+
598
+ // visibility
599
+ if( args.visible ) {
600
+ selector += ':visible';
601
+ }
602
+
603
+ // query
604
+ if( args.parent ) {
605
+ $fields = args.parent.find( selector );
606
+ } else if( args.sibling ) {
607
+ $fields = args.sibling.siblings( selector );
608
+ } else {
609
+ $fields = $( selector );
610
+ }
611
+
612
+ // filter
613
+ if( !args.suppressFilters ) {
614
+ $fields = $fields.not('.acf-clone .acf-field');
615
+ $fields = acf.applyFilters('find_fields', $fields);
616
+ }
617
+
618
+ // limit
619
+ if( args.limit ) {
620
+ $fields = $fields.slice( 0, args.limit );
621
+ }
622
+
623
+ // return
624
+ return $fields;
625
+
626
+ };
627
+
628
+ /**
629
+ * findField
630
+ *
631
+ * Finds a specific field with jQuery
632
+ *
633
+ * @date 14/12/17
634
+ * @since 5.6.5
635
+ *
636
+ * @param string key The field's key.
637
+ * @param jQuery $parent jQuery element to search within.
638
+ * @return jQuery
639
+ */
640
+
641
+ acf.findField = function( key, $parent ){
642
+ return acf.findFields({
643
+ key: key,
644
+ limit: 1,
645
+ parent: $parent,
646
+ suppressFilters: true
647
+ });
648
+ };
649
+
650
+ /**
651
+ * getField
652
+ *
653
+ * Returns a field instance
654
+ *
655
+ * @date 14/12/17
656
+ * @since 5.6.5
657
+ *
658
+ * @param jQuery|string $field jQuery element or field key.
659
+ * @return object
660
+ */
661
+
662
+ acf.getField = function( $field ){
663
+
664
+ // allow jQuery
665
+ if( $field instanceof jQuery ) {
666
+
667
+ // find fields
668
+ } else {
669
+ $field = acf.findField( $field );
670
+ }
671
+
672
+ // instantiate
673
+ var field = $field.data('acf');
674
+ if( !field ) {
675
+ field = acf.newField( $field );
676
+ }
677
+
678
+ // return
679
+ return field;
680
+ };
681
+
682
+ /**
683
+ * getFields
684
+ *
685
+ * Returns multiple field instances
686
+ *
687
+ * @date 14/12/17
688
+ * @since 5.6.5
689
+ *
690
+ * @param jQuery|object $fields jQuery elements or query args.
691
+ * @return array
692
+ */
693
+
694
+ acf.getFields = function( $fields ){
695
+
696
+ // allow jQuery
697
+ if( $fields instanceof jQuery ) {
698
+
699
+ // find fields
700
+ } else {
701
+ $fields = acf.findFields( $fields );
702
+ }
703
+
704
+ // loop
705
+ var fields = [];
706
+ $fields.each(function(){
707
+ var field = acf.getField( $(this) );
708
+ fields.push( field );
709
+ });
710
+
711
+ // return
712
+ return fields;
713
+ };
714
+
715
+ /**
716
+ * findClosestField
717
+ *
718
+ * Returns the closest jQuery field element
719
+ *
720
+ * @date 9/4/18
721
+ * @since 5.6.9
722
+ *
723
+ * @param jQuery $el
724
+ * @return jQuery
725
+ */
726
+
727
+ acf.findClosestField = function( $el ){
728
+ return $el.closest('.acf-field');
729
+ };
730
+
731
+ /**
732
+ * getClosestField
733
+ *
734
+ * Returns the closest field instance
735
+ *
736
+ * @date 22/1/18
737
+ * @since 5.6.5
738
+ *
739
+ * @param jQuery $el
740
+ * @return object
741
+ */
742
+
743
+ acf.getClosestField = function( $el ){
744
+ var $field = acf.findClosestField( $el );
745
+ return this.getField( $field );
746
+ };
747
+
748
+ /**
749
+ * addGlobalFieldAction
750
+ *
751
+ * Sets up callback logic for global field actions
752
+ *
753
+ * @date 15/6/18
754
+ * @since 5.6.9
755
+ *
756
+ * @param string action
757
+ * @return void
758
+ */
759
+
760
+ var addGlobalFieldAction = function( action ){
761
+
762
+ // vars
763
+ var globalAction = action;
764
+ var pluralAction = action + '_fields'; // ready_fields
765
+ var singleAction = action + '_field'; // ready_field
766
+
767
+ // global action
768
+ var globalCallback = function( $el /*, arg1, arg2, etc*/ ){
769
+ //console.log( action, arguments );
770
+
771
+ // get args [$el, ...]
772
+ var args = acf.arrayArgs( arguments );
773
+ var extraArgs = args.slice(1);
774
+
775
+ // find fields
776
+ var fields = acf.getFields({ parent: $el });
777
+
778
+ // check
779
+ if( fields.length ) {
780
+
781
+ // pluralAction
782
+ var pluralArgs = [ pluralAction, fields ].concat( extraArgs );
783
+ acf.doAction.apply(null, pluralArgs);
784
+ }
785
+ };
786
+
787
+ // plural action
788
+ var pluralCallback = function( fields /*, arg1, arg2, etc*/ ){
789
+ //console.log( pluralAction, arguments );
790
+
791
+ // get args [fields, ...]
792
+ var args = acf.arrayArgs( arguments );
793
+ var extraArgs = args.slice(1);
794
+
795
+ // loop
796
+ fields.map(function( field, i ){
797
+ //setTimeout(function(){
798
+ // singleAction
799
+ var singleArgs = [ singleAction, field ].concat( extraArgs );
800
+ acf.doAction.apply(null, singleArgs);
801
+ //}, i * 100);
802
+ });
803
+ };
804
+
805
+ // add actions
806
+ acf.addAction(globalAction, globalCallback);
807
+ acf.addAction(pluralAction, pluralCallback);
808
+
809
+ // also add single action
810
+ addSingleFieldAction( action );
811
+ }
812
+
813
+ /**
814
+ * addSingleFieldAction
815
+ *
816
+ * Sets up callback logic for single field actions
817
+ *
818
+ * @date 15/6/18
819
+ * @since 5.6.9
820
+ *
821
+ * @param string action
822
+ * @return void
823
+ */
824
+
825
+ var addSingleFieldAction = function( action ){
826
+
827
+ // vars
828
+ var singleAction = action + '_field'; // ready_field
829
+ var singleEvent = action + 'Field'; // readyField
830
+
831
+ // single action
832
+ var singleCallback = function( field /*, arg1, arg2, etc*/ ){
833
+ //console.log( singleAction, arguments );
834
+
835
+ // get args [field, ...]
836
+ var args = acf.arrayArgs( arguments );
837
+ var extraArgs = args.slice(1);
838
+
839
+ // action variations (ready_field/type=image)
840
+ var variations = ['type', 'name', 'key'];
841
+ variations.map(function( variation ){
842
+
843
+ // vars
844
+ var prefix = '/' + variation + '=' + field.get(variation);
845
+
846
+ // singleAction
847
+ args = [ singleAction + prefix , field ].concat( extraArgs );
848
+ acf.doAction.apply(null, args);
849
+ });
850
+
851
+ // event
852
+ if( singleFieldEvents.indexOf(action) > -1 ) {
853
+ field.trigger(singleEvent, extraArgs);
854
+ }
855
+ };
856
+
857
+ // add actions
858
+ acf.addAction(singleAction, singleCallback);
859
+ }
860
+
861
+ // vars
862
+ var globalFieldActions = [ 'prepare', 'ready', 'load', 'append', 'remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload' ];
863
+ var singleFieldActions = [ 'valid', 'invalid', 'enable', 'disable', 'new', 'duplicate' ];
864
+ var singleFieldEvents = [ 'remove', 'unmount', 'remount', 'sortstart', 'sortstop', 'show', 'hide', 'unload', 'valid', 'invalid', 'enable', 'disable', 'duplicate' ];
865
+
866
+ // add
867
+ globalFieldActions.map( addGlobalFieldAction );
868
+ singleFieldActions.map( addSingleFieldAction );
869
+
870
+ /**
871
+ * fieldsEventManager
872
+ *
873
+ * Manages field actions and events
874
+ *
875
+ * @date 15/12/17
876
+ * @since 5.6.5
877
+ *
878
+ * @param void
879
+ * @param void
880
+ */
881
+
882
+ var fieldsEventManager = new acf.Model({
883
+ id: 'fieldsEventManager',
884
+ events: {
885
+ 'click .acf-field a[href="#"]': 'onClick',
886
+ 'change .acf-field': 'onChange'
887
+ },
888
+ onClick: function( e ){
889
+
890
+ // prevent default of any link with an href of #
891
+ e.preventDefault();
892
+ },
893
+ onChange: function(){
894
+
895
+ // preview hack allows post to save with no title or content
896
+ $('#_acf_changed').val(1);
897
+ }
898
+ });
899
+
900
+ var duplicateFieldsManager = new acf.Model({
901
+ id: 'duplicateFieldsManager',
902
+ actions: {
903
+ 'duplicate': 'onDuplicate',
904
+ 'duplicate_fields': 'onDuplicateFields',
905
+ },
906
+ onDuplicate: function( $el, $el2 ){
907
+ var fields = acf.getFields({ parent: $el });
908
+ if( fields.length ) {
909
+ var $fields = acf.findFields({ parent: $el2 });
910
+ acf.doAction( 'duplicate_fields', fields, $fields );
911
+ }
912
+ },
913
+ onDuplicateFields: function( fields, duplicates ){
914
+ fields.map(function( field, i ){
915
+ acf.doAction( 'duplicate_field', field, $(duplicates[i]) );
916
+ });
917
+ }
918
+ });
919
+
920
  })(jQuery);
921
+ (function($, undefined){
922
+
923
+ var i = 0;
924
+
925
+ var Field = acf.Field.extend({
926
+
927
+ type: 'accordion',
928
+
929
+ wait: '',
930
+
931
+ $control: function(){
932
+ return this.$('.acf-fields:first');
933
+ },
934
+
935
+ initialize: function(){
936
+
937
+ // Bail early if this is a duplicate of an existing initialized accordion.
938
+ if( this.$el.hasClass('acf-accordion') ) {
939
+ return;
940
+ }
941
+
942
+ // bail early if is cell
943
+ if( this.$el.is('td') ) return;
944
+
945
+ // enpoint
946
+ if( this.get('endpoint') ) {
947
+ return this.remove();
948
+ }
949
+
950
+ // vars
951
+ var $field = this.$el;
952
+ var $label = this.$labelWrap()
953
+ var $input = this.$inputWrap();
954
+ var $wrap = this.$control();
955
+ var $instructions = $input.children('.description');
956
+
957
+ // force description into label
958
+ if( $instructions.length ) {
959
+ $label.append( $instructions );
960
+ }
961
+
962
+ // table
963
+ if( this.$el.is('tr') ) {
964
+
965
+ // vars
966
+ var $table = this.$el.closest('table');
967
+ var $newLabel = $('<div class="acf-accordion-title"/>');
968
+ var $newInput = $('<div class="acf-accordion-content"/>');
969
+ var $newTable = $('<table class="' + $table.attr('class') + '"/>');
970
+ var $newWrap = $('<tbody/>');
971
+
972
+ // dom
973
+ $newLabel.append( $label.html() );
974
+ $newTable.append( $newWrap );
975
+ $newInput.append( $newTable );
976
+ $input.append( $newLabel );
977
+ $input.append( $newInput );
978
+
979
+ // modify
980
+ $label.remove();
981
+ $wrap.remove();
982
+ $input.attr('colspan', 2);
983
+
984
+ // update vars
985
+ $label = $newLabel;
986
+ $input = $newInput;
987
+ $wrap = $newWrap;
988
+ }
989
+
990
+ // add classes
991
+ $field.addClass('acf-accordion');
992
+ $label.addClass('acf-accordion-title');
993
+ $input.addClass('acf-accordion-content');
994
+
995
+ // index
996
+ i++;
997
+
998
+ // multi-expand
999
+ if( this.get('multi_expand') ) {
1000
+ $field.attr('multi-expand', 1);
1001
+ }
1002
+
1003
+ // open
1004
+ var order = acf.getPreference('this.accordions') || [];
1005
+ if( order[i-1] !== undefined ) {
1006
+ this.set('open', order[i-1]);
1007
+ }
1008
+
1009
+ if( this.get('open') ) {
1010
+ $field.addClass('-open');
1011
+ $input.css('display', 'block'); // needed for accordion to close smoothly
1012
+ }
1013
+
1014
+ // add icon
1015
+ $label.prepend( accordionManager.iconHtml({ open: this.get('open') }) );
1016
+
1017
+ // classes
1018
+ // - remove 'inside' which is a #poststuff WP class
1019
+ var $parent = $field.parent();
1020
+ $wrap.addClass( $parent.hasClass('-left') ? '-left' : '' );
1021
+ $wrap.addClass( $parent.hasClass('-clear') ? '-clear' : '' );
1022
+
1023
+ // append
1024
+ $wrap.append( $field.nextUntil('.acf-field-accordion', '.acf-field') );
1025
+
1026
+ // clean up
1027
+ $wrap.removeAttr('data-open data-multi_expand data-endpoint');
1028
+ },
1029
+
1030
+ });
1031
+
1032
+ acf.registerFieldType( Field );
1033
+
1034
+
1035
+ /**
1036
+ * accordionManager
1037
+ *
1038
+ * Events manager for the acf accordion
1039
+ *
1040
+ * @date 14/2/18
1041
+ * @since 5.6.9
1042
+ *
1043
+ * @param void
1044
+ * @return void
1045
+ */
1046
+
1047
+ var accordionManager = new acf.Model({
1048
+
1049
+ actions: {
1050
+ 'unload': 'onUnload'
1051
+ },
1052
+
1053
+ events: {
1054
+ 'click .acf-accordion-title': 'onClick',
1055
+ 'invalidField .acf-accordion': 'onInvalidField'
1056
+ },
1057
+
1058
+ isOpen: function( $el ) {
1059
+ return $el.hasClass('-open');
1060
+ },
1061
+
1062
+ toggle: function( $el ){
1063
+ if( this.isOpen($el) ) {
1064
+ this.close( $el );
1065
+ } else {
1066
+ this.open( $el );
1067
+ }
1068
+ },
1069
+
1070
+ iconHtml: function( props ){
1071
+
1072
+ // Use SVG inside Gutenberg editor.
1073
+ if( acf.isGutenberg() ) {
1074
+ if( props.open ) {
1075
+ return '<svg class="acf-accordion-icon" width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img" aria-hidden="true" focusable="false"><g><path fill="none" d="M0,0h24v24H0V0z"></path></g><g><path d="M12,8l-6,6l1.41,1.41L12,10.83l4.59,4.58L18,14L12,8z"></path></g></svg>';
1076
+ } else {
1077
+ return '<svg class="acf-accordion-icon" width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img" aria-hidden="true" focusable="false"><g><path fill="none" d="M0,0h24v24H0V0z"></path></g><g><path d="M7.41,8.59L12,13.17l4.59-4.58L18,10l-6,6l-6-6L7.41,8.59z"></path></g></svg>';
1078
+ }
1079
+ } else {
1080
+ if( props.open ) {
1081
+ return '<i class="acf-accordion-icon dashicons dashicons-arrow-down"></i>';
1082
+ } else {
1083
+ return '<i class="acf-accordion-icon dashicons dashicons-arrow-right"></i>';
1084
+ }
1085
+ }
1086
+ },
1087
+
1088
+ open: function( $el ){
1089
+ var duration = acf.isGutenberg() ? 0 : 300;
1090
+
1091
+ // open
1092
+ $el.find('.acf-accordion-content:first').slideDown( duration ).css('display', 'block');
1093
+ $el.find('.acf-accordion-icon:first').replaceWith( this.iconHtml({ open: true }) );
1094
+ $el.addClass('-open');
1095
+
1096
+ // action
1097
+ acf.doAction('show', $el);
1098
+
1099
+ // close siblings
1100
+ if( !$el.attr('multi-expand') ) {
1101
+ $el.siblings('.acf-accordion.-open').each(function(){
1102
+ accordionManager.close( $(this) );
1103
+ });
1104
+ }
1105
+ },
1106
+
1107
+ close: function( $el ){
1108
+ var duration = acf.isGutenberg() ? 0 : 300;
1109
+
1110
+ // close
1111
+ $el.find('.acf-accordion-content:first').slideUp( duration );
1112
+ $el.find('.acf-accordion-icon:first').replaceWith( this.iconHtml({ open: false }) );
1113
+ $el.removeClass('-open');
1114
+
1115
+ // action
1116
+ acf.doAction('hide', $el);
1117
+ },
1118
+
1119
+ onClick: function( e, $el ){
1120
+
1121
+ // prevent Defailt
1122
+ e.preventDefault();
1123
+
1124
+ // open close
1125
+ this.toggle( $el.parent() );
1126
+
1127
+ },
1128
+
1129
+ onInvalidField: function( e, $el ){
1130
+
1131
+ // bail early if already focused
1132
+ if( this.busy ) {
1133
+ return;
1134
+ }
1135
+
1136
+ // disable functionality for 1sec (allow next validation to work)
1137
+ this.busy = true;
1138
+ this.setTimeout(function(){
1139
+ this.busy = false;
1140
+ }, 1000);
1141
+
1142
+ // open accordion
1143
+ this.open( $el );
1144
+ },
1145
+
1146
+ onUnload: function( e ){
1147
+
1148
+ // vars
1149
+ var order = [];
1150
+
1151
+ // loop
1152
+ $('.acf-accordion').each(function(){
1153
+ var open = $(this).hasClass('-open') ? 1 : 0;
1154
+ order.push(open);
1155
+ });
1156
+
1157
+ // set
1158
+ if( order.length ) {
1159
+ acf.setPreference('this.accordions', order);
1160
+ }
1161
+ }
1162
+ });
1163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1164
  })(jQuery);
1165
+ (function($, undefined){
1166
+
1167
+ var Field = acf.Field.extend({
1168
+
1169
+ type: 'button_group',
1170
+
1171
+ events: {
1172
+ 'click input[type="radio"]': 'onClick'
1173
+ },
1174
+
1175
+ $control: function(){
1176
+ return this.$('.acf-button-group');
1177
+ },
1178
+
1179
+ $input: function(){
1180
+ return this.$('input:checked');
1181
+ },
1182
+
1183
+ setValue: function( val ){
1184
+ this.$('input[value="' + val + '"]').prop('checked', true).trigger('change');
1185
+ },
1186
+
1187
+ onClick: function( e, $el ){
1188
+
1189
+ // vars
1190
+ var $label = $el.parent('label');
1191
+ var selected = $label.hasClass('selected');
1192
+
1193
+ // remove previous selected
1194
+ this.$('.selected').removeClass('selected');
1195
+
1196
+ // add active class
1197
+ $label.addClass('selected');
1198
+
1199
+ // allow null
1200
+ if( this.get('allow_null') && selected ) {
1201
+ $label.removeClass('selected');
1202
+ $el.prop('checked', false).trigger('change');
1203
+ }
1204
+ }
1205
+ });
1206
+
1207
+ acf.registerFieldType( Field );
1208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1209
  })(jQuery);
1210
+ (function($, undefined){
1211
+
1212
+ var Field = acf.Field.extend({
1213
+
1214
+ type: 'checkbox',
1215
+
1216
+ events: {
1217
+ 'change input': 'onChange',
1218
+ 'click .acf-add-checkbox': 'onClickAdd',
1219
+ 'click .acf-checkbox-toggle': 'onClickToggle',
1220
+ 'click .acf-checkbox-custom': 'onClickCustom'
1221
+ },
1222
+
1223
+ $control: function(){
1224
+ return this.$('.acf-checkbox-list');
1225
+ },
1226
+
1227
+ $toggle: function(){
1228
+ return this.$('.acf-checkbox-toggle');
1229
+ },
1230
+
1231
+ $input: function(){
1232
+ return this.$('input[type="hidden"]');
1233
+ },
1234
+
1235
+ $inputs: function(){
1236
+ return this.$('input[type="checkbox"]').not('.acf-checkbox-toggle');
1237
+ },
1238
+
1239
+ getValue: function(){
1240
+ var val = [];
1241
+ this.$(':checked').each(function(){
1242
+ val.push( $(this).val() );
1243
+ });
1244
+ return val.length ? val : false;
1245
+ },
1246
+
1247
+ onChange: function( e, $el ){
1248
+
1249
+ // Vars.
1250
+ var checked = $el.prop('checked');
1251
+ var $label = $el.parent('label');
1252
+ var $toggle = this.$toggle();
1253
+
1254
+ // Add or remove "selected" class.
1255
+ if( checked ) {
1256
+ $label.addClass('selected');
1257
+ } else {
1258
+ $label.removeClass('selected');
1259
+ }
1260
+
1261
+ // Update toggle state if all inputs are checked.
1262
+ if( $toggle.length ) {
1263
+ var $inputs = this.$inputs();
1264
+
1265
+ // all checked
1266
+ if( $inputs.not(':checked').length == 0 ) {
1267
+ $toggle.prop('checked', true);
1268
+ } else {
1269
+ $toggle.prop('checked', false);
1270
+ }
1271
+ }
1272
+ },
1273
+
1274
+ onClickAdd: function( e, $el ){
1275
+ var html = '<li><input class="acf-checkbox-custom" type="checkbox" checked="checked" /><input type="text" name="' + this.getInputName() + '[]" /></li>';
1276
+ $el.parent('li').before( html );
1277
+ },
1278
+
1279
+ onClickToggle: function( e, $el ){
1280
+
1281
+ // Vars.
1282
+ var checked = $el.prop('checked');
1283
+ var $inputs = this.$('input[type="checkbox"]');
1284
+ var $labels = this.$('label');
1285
+
1286
+ // Update "checked" state.
1287
+ $inputs.prop('checked', checked);
1288
+
1289
+ // Add or remove "selected" class.
1290
+ if( checked ) {
1291
+ $labels.addClass('selected');
1292
+ } else {
1293
+ $labels.removeClass('selected');
1294
+ }
1295
+ },
1296
+
1297
+ onClickCustom: function( e, $el ){
1298
+ var checked = $el.prop('checked');
1299
+ var $text = $el.next('input[type="text"]');
1300
+
1301
+ // checked
1302
+ if( checked ) {
1303
+ $text.prop('disabled', false);
1304
+
1305
+ // not checked
1306
+ } else {
1307
+ $text.prop('disabled', true);
1308
+
1309
+ // remove
1310
+ if( $text.val() == '' ) {
1311
+ $el.parent('li').remove();
1312
+ }
1313
+ }
1314
+ }
1315
+ });
1316
+
1317
+ acf.registerFieldType( Field );
1318
+
1319
  })(jQuery);
1320
+ (function($, undefined){
1321
+
1322
+ var Field = acf.Field.extend({
1323
+
1324
+ type: 'color_picker',
1325
+
1326
+ wait: 'load',
1327
+
1328
+ events: {
1329
+ 'duplicateField': 'onDuplicate'
1330
+ },
1331
+
1332
+ $control: function(){
1333
+ return this.$('.acf-color-picker');
1334
+ },
1335
+
1336
+ $input: function(){
1337
+ return this.$('input[type="hidden"]');
1338
+ },
1339
+
1340
+ $inputText: function(){
1341
+ return this.$('input[type="text"]');
1342
+ },
1343
+
1344
+ setValue: function( val ){
1345
+
1346
+ // update input (with change)
1347
+ acf.val( this.$input(), val );
1348
+
1349
+ // update iris
1350
+ this.$inputText().iris('color', val);
1351
+ },
1352
+
1353
+ initialize: function(){
1354
+
1355
+ // vars
1356
+ var $input = this.$input();
1357
+ var $inputText = this.$inputText();
1358
+
1359
+ // event
1360
+ var onChange = function( e ){
1361
+
1362
+ // timeout is required to ensure the $input val is correct
1363
+ setTimeout(function(){
1364
+ acf.val( $input, $inputText.val() );
1365
+ }, 1);
1366
+ }
1367
+
1368
+ // args
1369
+ var args = {
1370
+ defaultColor: false,
1371
+ palettes: true,
1372
+ hide: true,
1373
+ change: onChange,
1374
+ clear: onChange
1375
+ };
1376
+
1377
+ // filter
1378
+ var args = acf.applyFilters('color_picker_args', args, this);
1379
+
1380
+ // initialize
1381
+ $inputText.wpColorPicker( args );
1382
+ },
1383
+
1384
+ onDuplicate: function( e, $el, $duplicate ){
1385
+
1386
+ // The wpColorPicker library does not provide a destroy method.
1387
+ // Manually reset DOM by replacing elements back to their original state.
1388
+ $colorPicker = $duplicate.find('.wp-picker-container');
1389
+ $inputText = $duplicate.find('input[type="text"]');
1390
+ $colorPicker.replaceWith( $inputText );
1391
+ }
1392
+ });
1393
+
1394
+ acf.registerFieldType( Field );
1395
+
1396
  })(jQuery);
1397
+ (function($, undefined){
1398
+
1399
+ var Field = acf.Field.extend({
1400
+
1401
+ type: 'date_picker',
1402
+
1403
+ events: {
1404
+ 'blur input[type="text"]': 'onBlur',
1405
+ 'duplicateField': 'onDuplicate'
1406
+ },
1407
+
1408
+ $control: function(){
1409
+ return this.$('.acf-date-picker');
1410
+ },
1411
+
1412
+ $input: function(){
1413
+ return this.$('input[type="hidden"]');
1414
+ },
1415
+
1416
+ $inputText: function(){
1417
+ return this.$('input[type="text"]');
1418
+ },
1419
+
1420
+ initialize: function(){
1421
+
1422
+ // save_format: compatibility with ACF < 5.0.0
1423
+ if( this.has('save_format') ) {
1424
+ return this.initializeCompatibility();
1425
+ }
1426
+
1427
+ // vars
1428
+ var $input = this.$input();
1429
+ var $inputText = this.$inputText();
1430
+
1431
+ // args
1432
+ var args = {
1433
+ dateFormat: this.get('date_format'),
1434
+ altField: $input,
1435
+ altFormat: 'yymmdd',
1436
+ changeYear: true,
1437
+ yearRange: "-100:+100",
1438
+ changeMonth: true,
1439
+ showButtonPanel: true,
1440
+ firstDay: this.get('first_day')
1441
+ };
1442
+
1443
+ // filter
1444
+ args = acf.applyFilters('date_picker_args', args, this);
1445
+
1446
+ // add date picker
1447
+ acf.newDatePicker( $inputText, args );
1448
+
1449
+ // action
1450
+ acf.doAction('date_picker_init', $inputText, args, this);
1451
+
1452
+ },
1453
+
1454
+ initializeCompatibility: function(){
1455
+
1456
+ // vars
1457
+ var $input = this.$input();
1458
+ var $inputText = this.$inputText();
1459
+
1460
+ // get and set value from alt field
1461
+ $inputText.val( $input.val() );
1462
+
1463
+ // args
1464
+ var args = {
1465
+ dateFormat: this.get('date_format'),
1466
+ altField: $input,
1467
+ altFormat: this.get('save_format'),
1468
+ changeYear: true,
1469
+ yearRange: "-100:+100",
1470
+ changeMonth: true,
1471
+ showButtonPanel: true,
1472
+ firstDay: this.get('first_day')
1473
+ };
1474
+
1475
+ // filter for 3rd party customization
1476
+ args = acf.applyFilters('date_picker_args', args, this);
1477
+
1478
+ // backup
1479
+ var dateFormat = args.dateFormat;
1480
+
1481
+ // change args.dateFormat
1482
+ args.dateFormat = this.get('save_format');
1483
+
1484
+ // add date picker
1485
+ acf.newDatePicker( $inputText, args );
1486
+
1487
+ // now change the format back to how it should be.
1488
+ $inputText.datepicker( 'option', 'dateFormat', dateFormat );
1489
+
1490
+ // action for 3rd party customization
1491
+ acf.doAction('date_picker_init', $inputText, args, this);
1492
+ },
1493
+
1494
+ onBlur: function(){
1495
+ if( !this.$inputText().val() ) {
1496
+ acf.val( this.$input(), '' );
1497
+ }
1498
+ },
1499
+
1500
+ onDuplicate: function( e, $el, $duplicate ){
1501
+ $duplicate.find('input[type="text"]').removeClass('hasDatepicker').removeAttr('id');
1502
+ }
1503
+ });
1504
+
1505
+ acf.registerFieldType( Field );
1506
+
1507
+
1508
+ // manager
1509
+ var datePickerManager = new acf.Model({
1510
+ priority: 5,
1511
+ wait: 'ready',
1512
+ initialize: function(){
1513
+
1514
+ // vars
1515
+ var locale = acf.get('locale');
1516
+ var rtl = acf.get('rtl');
1517
+ var l10n = acf.get('datePickerL10n');
1518
+
1519
+ // bail ealry if no l10n
1520
+ if( !l10n ) {
1521
+ return false;
1522
+ }
1523
+
1524
+ // bail ealry if no datepicker library
1525
+ if( typeof $.datepicker === 'undefined' ) {
1526
+ return false;
1527
+ }
1528
+
1529
+ // rtl
1530
+ l10n.isRTL = rtl;
1531
+
1532
+ // append
1533
+ $.datepicker.regional[ locale ] = l10n;
1534
+ $.datepicker.setDefaults(l10n);
1535
+ }
1536
+ });
1537
+
1538
+ // add
1539
+ acf.newDatePicker = function( $input, args ){
1540
+
1541
+ // bail ealry if no datepicker library
1542
+ if( typeof $.datepicker === 'undefined' ) {
1543
+ return false;
1544
+ }
1545
+
1546
+ // defaults
1547
+ args = args || {};
1548
+
1549
+ // initialize
1550
+ $input.datepicker( args );
1551
+
1552
+ // wrap the datepicker (only if it hasn't already been wrapped)
1553
+ if( $('body > #ui-datepicker-div').exists() ) {
1554
+ $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
1555
+ }
1556
+ };
1557
+
1558
  })(jQuery);
1559
+ (function($, undefined){
1560
+
1561
+ var Field = acf.models.DatePickerField.extend({
1562
+
1563
+ type: 'date_time_picker',
1564
+
1565
+ $control: function(){
1566
+ return this.$('.acf-date-time-picker');
1567
+ },
1568
+
1569
+ initialize: function(){
1570
+
1571
+ // vars
1572
+ var $input = this.$input();
1573
+ var $inputText = this.$inputText();
1574
+
1575
+ // args
1576
+ var args = {
1577
+ dateFormat: this.get('date_format'),
1578
+ timeFormat: this.get('time_format'),
1579
+ altField: $input,
1580
+ altFieldTimeOnly: false,
1581
+ altFormat: 'yy-mm-dd',
1582
+ altTimeFormat: 'HH:mm:ss',
1583
+ changeYear: true,
1584
+ yearRange: "-100:+100",
1585
+ changeMonth: true,
1586
+ showButtonPanel: true,
1587
+ firstDay: this.get('first_day'),
1588
+ controlType: 'select',
1589
+ oneLine: true
1590
+ };
1591
+
1592
+ // filter
1593
+ args = acf.applyFilters('date_time_picker_args', args, this);
1594
+
1595
+ // add date time picker
1596
+ acf.newDateTimePicker( $inputText, args );
1597
+
1598
+ // action
1599
+ acf.doAction('date_time_picker_init', $inputText, args, this);
1600
+ }
1601
+ });
1602
+
1603
+ acf.registerFieldType( Field );
1604
+
1605
+
1606
+ // manager
1607
+ var dateTimePickerManager = new acf.Model({
1608
+ priority: 5,
1609
+ wait: 'ready',
1610
+ initialize: function(){
1611
+
1612
+ // vars
1613
+ var locale = acf.get('locale');
1614
+ var rtl = acf.get('rtl');
1615
+ var l10n = acf.get('dateTimePickerL10n');
1616
+
1617
+ // bail ealry if no l10n
1618
+ if( !l10n ) {
1619
+ return false;
1620
+ }
1621
+
1622
+ // bail ealry if no datepicker library
1623
+ if( typeof $.timepicker === 'undefined' ) {
1624
+ return false;
1625
+ }
1626
+
1627
+ // rtl
1628
+ l10n.isRTL = rtl;
1629
+
1630
+ // append
1631
+ $.timepicker.regional[ locale ] = l10n;
1632
+ $.timepicker.setDefaults(l10n);
1633
+ }
1634
+ });
1635
+
1636
+
1637
+ // add
1638
+ acf.newDateTimePicker = function( $input, args ){
1639
+
1640
+ // bail ealry if no datepicker library
1641
+ if( typeof $.timepicker === 'undefined' ) {
1642
+ return false;
1643
+ }
1644
+
1645
+ // defaults
1646
+ args = args || {};
1647
+
1648
+ // initialize
1649
+ $input.datetimepicker( args );
1650
+
1651
+ // wrap the datepicker (only if it hasn't already been wrapped)
1652
+ if( $('body > #ui-datepicker-div').exists() ) {
1653
+ $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
1654
+ }
1655
+ };
1656
+
1657
  })(jQuery);
1658
+ (function($, undefined){
1659
+
1660
+ var Field = acf.Field.extend({
1661
+
1662
+ type: 'google_map',
1663
+
1664
+ map: false,
1665
+
1666
+ wait: 'load',
1667
+
1668
+ events: {
1669
+ 'click a[data-name="clear"]': 'onClickClear',
1670
+ 'click a[data-name="locate"]': 'onClickLocate',
1671
+ 'click a[data-name="search"]': 'onClickSearch',
1672
+ 'keydown .search': 'onKeydownSearch',
1673
+ 'keyup .search': 'onKeyupSearch',
1674
+ 'focus .search': 'onFocusSearch',
1675
+ 'blur .search': 'onBlurSearch',
1676
+ 'showField': 'onShow',
1677
+ },
1678
+
1679
+ $control: function(){
1680
+ return this.$('.acf-google-map');
1681
+ },
1682
+
1683
+ $search: function(){
1684
+ return this.$('.search');
1685
+ },
1686
+
1687
+ $canvas: function(){
1688
+ return this.$('.canvas');
1689
+ },
1690
+
1691
+ setState: function( state ){
1692
+
1693
+ // Remove previous state classes.
1694
+ this.$control().removeClass( '-value -loading -searching' );
1695
+
1696
+ // Determine auto state based of current value.
1697
+ if( state === 'default' ) {
1698
+ state = this.val() ? 'value' : '';
1699
+ }
1700
+
1701
+ // Update state class.
1702
+ if( state ) {
1703
+ this.$control().addClass( '-' + state );
1704
+ }
1705
+ },
1706
+
1707
+ getValue: function(){
1708
+ var val = this.$input().val();
1709
+ if( val ) {
1710
+ return JSON.parse( val )
1711
+ } else {
1712
+ return false;
1713
+ }
1714
+ },
1715
+
1716
+ setValue: function( val, silent ){
1717
+
1718
+ // Convert input value.
1719
+ var valAttr = '';
1720
+ if( val ) {
1721
+ valAttr = JSON.stringify( val );
1722
+ }
1723
+
1724
+ // Update input (with change).
1725
+ acf.val( this.$input(), valAttr );
1726
+
1727
+ // Bail early if silent update.
1728
+ if( silent ) {
1729
+ return;
1730
+ }
1731
+
1732
+ // Render.
1733
+ this.renderVal( val );
1734
+
1735
+ /**
1736
+ * Fires immediately after the value has changed.
1737
+ *
1738
+ * @date 12/02/2014
1739
+ * @since 5.0.0
1740
+ *
1741
+ * @param object|string val The new value.
1742
+ * @param object map The Google Map isntance.
1743
+ * @param object field The field instance.
1744
+ */
1745
+ acf.doAction('google_map_change', val, this.map, this);
1746
+ },
1747
+
1748
+ renderVal: function( val ){
1749
+
1750
+ // Value.
1751
+ if( val ) {
1752
+ this.setState( 'value' );
1753
+ this.$search().val( val.address );
1754
+ this.setPosition( val.lat, val.lng );
1755
+
1756
+ // No value.
1757
+ } else {
1758
+ this.setState( '' );
1759
+ this.$search().val( '' );
1760
+ this.map.marker.setVisible( false );
1761
+ }
1762
+ },
1763
+
1764
+ newLatLng: function( lat, lng ){
1765
+ return new google.maps.LatLng( parseFloat(lat), parseFloat(lng) );
1766
+ },
1767
+
1768
+ setPosition: function( lat, lng ){
1769
+
1770
+ // Update marker position.
1771
+ this.map.marker.setPosition({
1772
+ lat: parseFloat(lat),
1773
+ lng: parseFloat(lng)
1774
+ });
1775
+
1776
+ // Show marker.
1777
+ this.map.marker.setVisible( true );
1778
+
1779
+ // Center map.
1780
+ this.center();
1781
+ },
1782
+
1783
+ center: function(){
1784
+
1785
+ // Find marker position.
1786
+ var position = this.map.marker.getPosition();
1787
+ if( position ) {
1788
+ var lat = position.lat();
1789
+ var lng = position.lng();
1790
+
1791
+ // Or find default settings.
1792
+ } else {
1793
+ var lat = this.get('lat');
1794
+ var lng = this.get('lng');
1795
+ }
1796
+
1797
+ // Center map.
1798
+ this.map.setCenter({
1799
+ lat: parseFloat(lat),
1800
+ lng: parseFloat(lng)
1801
+ });
1802
+ },
1803
+
1804
+ initialize: function(){
1805
+
1806
+ // Ensure Google API is loaded and then initialize map.
1807
+ withAPI( this.initializeMap.bind(this) );
1808
+ },
1809
+
1810
+ initializeMap: function(){
1811
+
1812
+ // Get value ignoring conditional logic status.
1813
+ var val = this.getValue();
1814
+
1815
+ // Construct default args.
1816
+ var args = acf.parseArgs(val, {
1817
+ zoom: this.get('zoom'),
1818
+ lat: this.get('lat'),
1819
+ lng: this.get('lng')
1820
+ });
1821
+
1822
+ // Create Map.
1823
+ var mapArgs = {
1824
+ scrollwheel: false,
1825
+ zoom: parseInt( args.zoom ),
1826
+ center: {
1827
+ lat: parseFloat( args.lat ),
1828
+ lng: parseFloat( args.lng )
1829
+ },
1830
+ mapTypeId: google.maps.MapTypeId.ROADMAP,
1831
+ marker: {
1832
+ draggable: true,
1833
+ raiseOnDrag: true
1834
+ },
1835
+ autocomplete: {}
1836
+ };
1837
+ mapArgs = acf.applyFilters('google_map_args', mapArgs, this);
1838
+ var map = new google.maps.Map( this.$canvas()[0], mapArgs );
1839
+
1840
+ // Create Marker.
1841
+ var markerArgs = acf.parseArgs(mapArgs.marker, {
1842
+ draggable: true,
1843
+ raiseOnDrag: true,
1844
+ map: map
1845
+ });
1846
+ markerArgs = acf.applyFilters('google_map_marker_args', markerArgs, this);
1847
+ var marker = new google.maps.Marker( markerArgs );
1848
+
1849
+ // Maybe Create Autocomplete.
1850
+ var autocomplete = false;
1851
+ if( acf.isset(google, 'maps', 'places', 'Autocomplete') ) {
1852
+ var autocompleteArgs = mapArgs.autocomplete || {};
1853
+ autocompleteArgs = acf.applyFilters('google_map_autocomplete_args', autocompleteArgs, this);
1854
+ autocomplete = new google.maps.places.Autocomplete( this.$search()[0], autocompleteArgs );
1855
+ autocomplete.bindTo('bounds', map);
1856
+ }
1857
+
1858
+ // Add map events.
1859
+ this.addMapEvents( this, map, marker, autocomplete );
1860
+
1861
+ // Append references.
1862
+ map.acf = this;
1863
+ map.marker = marker;
1864
+ map.autocomplete = autocomplete;
1865
+ this.map = map;
1866
+
1867
+ // Set position.
1868
+ if( val ) {
1869
+ this.setPosition( val.lat, val.lng );
1870
+ }
1871
+
1872
+ /**
1873
+ * Fires immediately after the Google Map has been initialized.
1874
+ *
1875
+ * @date 12/02/2014
1876
+ * @since 5.0.0
1877
+ *
1878
+ * @param object map The Google Map isntance.
1879
+ * @param object marker The Google Map marker isntance.
1880
+ * @param object field The field instance.
1881
+ */
1882
+ acf.doAction('google_map_init', map, marker, this);
1883
+ },
1884
+
1885
+ addMapEvents: function( field, map, marker, autocomplete ){
1886
+
1887
+ // Click map.
1888
+ google.maps.event.addListener( map, 'click', function( e ) {
1889
+ var lat = e.latLng.lat();
1890
+ var lng = e.latLng.lng();
1891
+ field.searchPosition( lat, lng );
1892
+ });
1893
+
1894
+ // Drag marker.
1895
+ google.maps.event.addListener( marker, 'dragend', function(){
1896
+ var lat = this.getPosition().lat();
1897
+ var lng = this.getPosition().lng();
1898
+ field.searchPosition( lat, lng );
1899
+ });
1900
+
1901
+ // Autocomplete search.
1902
+ if( autocomplete ) {
1903
+ google.maps.event.addListener(autocomplete, 'place_changed', function() {
1904
+ var place = this.getPlace();
1905
+ field.searchPlace( place );
1906
+ });
1907
+ }
1908
+
1909
+ // Detect zoom change.
1910
+ google.maps.event.addListener( map, 'zoom_changed', function(){
1911
+ var val = field.val();
1912
+ if( val ) {
1913
+ val.zoom = map.getZoom();
1914
+ field.setValue( val, true );
1915
+ }
1916
+ });
1917
+ },
1918
+
1919
+ searchPosition: function( lat, lng ){
1920
+ //console.log('searchPosition', lat, lng );
1921
+
1922
+ // Start Loading.
1923
+ this.setState( 'loading' );
1924
+
1925
+ // Query Geocoder.
1926
+ var latLng = { lat: lat, lng: lng };
1927
+ geocoder.geocode({ location: latLng }, function( results, status ){
1928
+ //console.log('searchPosition', arguments );
1929
+
1930
+ // End Loading.
1931
+ this.setState( '' );
1932
+
1933
+ // Status failure.
1934
+ if( status !== 'OK' ) {
1935
+ this.showNotice({
1936
+ text: acf.__('Location not found: %s').replace('%s', status),
1937
+ type: 'warning'
1938
+ });
1939
+
1940
+ // Success.
1941
+ } else {
1942
+ var val = this.parseResult( results[0] );
1943
+
1944
+ // Override lat/lng to match user defined marker location.
1945
+ // Avoids issue where marker "snaps" to nearest result.
1946
+ val.lat = lat;
1947
+ val.lng = lng;
1948
+ this.val( val );
1949
+ }
1950
+
1951
+ }.bind( this ));
1952
+ },
1953
+
1954
+ searchPlace: function( place ){
1955
+ //console.log('searchPlace', place );
1956
+
1957
+ // Bail early if no place.
1958
+ if( !place ) {
1959
+ return;
1960
+ }
1961
+
1962
+ // Selecting from the autocomplete dropdown will return a rich PlaceResult object.
1963
+ // Be sure to over-write the "formatted_address" value with the one displayed to the user for best UX.
1964
+ if( place.geometry ) {
1965
+ place.formatted_address = this.$search().val();
1966
+ var val = this.parseResult( place );
1967
+ this.val( val );
1968
+
1969
+ // Searching a custom address will return an empty PlaceResult object.
1970
+ } else if( place.name ) {
1971
+ this.searchAddress( place.name );
1972
+ }
1973
+ },
1974
+
1975
+ searchAddress: function( address ){
1976
+ //console.log('searchAddress', address );
1977
+
1978
+ // Bail early if no address.
1979
+ if( !address ) {
1980
+ return;
1981
+ }
1982
+
1983
+ // Allow "lat,lng" search.
1984
+ var latLng = address.split(',');
1985
+ if( latLng.length == 2 ) {
1986
+ var lat = parseFloat(latLng[0]);
1987
+ var lng = parseFloat(latLng[1]);
1988
+ if( lat && lng ) {
1989
+ return this.searchPosition( lat, lng );
1990
+ }
1991
+ }
1992
+
1993
+ // Start Loading.
1994
+ this.setState( 'loading' );
1995
+
1996
+ // Query Geocoder.
1997
+ geocoder.geocode({ address: address }, function( results, status ){
1998
+ //console.log('searchPosition', arguments );
1999
+
2000
+ // End Loading.
2001
+ this.setState( '' );
2002
+
2003
+ // Status failure.
2004
+ if( status !== 'OK' ) {
2005
+ this.showNotice({
2006
+ text: acf.__('Location not found: %s').replace('%s', status),
2007
+ type: 'warning'
2008
+ });
2009
+
2010
+ // Success.
2011
+ } else {
2012
+ var val = this.parseResult( results[0] );
2013
+
2014
+ // Override address data with parameter allowing custom address to be defined in search.
2015
+ val.address = address;
2016
+
2017
+ // Update value.
2018
+ this.val( val );
2019
+ }
2020
+
2021
+ }.bind( this ));
2022
+ },
2023
+
2024
+ searchLocation: function(){
2025
+ //console.log('searchLocation' );
2026
+
2027
+ // Check HTML5 geolocation.
2028
+ if( !navigator.geolocation ) {
2029
+ return alert( acf.__('Sorry, this browser does not support geolocation') );
2030
+ }
2031
+
2032
+ // Start Loading.
2033
+ this.setState( 'loading' );
2034
+
2035
+ // Query Geolocation.
2036
+ navigator.geolocation.getCurrentPosition(
2037
+
2038
+ // Success.
2039
+ function( results ){
2040
+
2041
+ // End Loading.
2042
+ this.setState( '' );
2043
+
2044
+ // Search position.
2045
+ var lat = results.coords.latitude;
2046
+ var lng = results.coords.longitude;
2047
+ this.searchPosition( lat, lng );
2048
+
2049
+ }.bind(this),
2050
+
2051
+ // Failure.
2052
+ function( error ){
2053
+ this.setState( '' );
2054
+ }.bind(this)
2055
+ );
2056
+ },
2057
+
2058
+ /**
2059
+ * parseResult
2060
+ *
2061
+ * Returns location data for the given GeocoderResult object.
2062
+ *
2063
+ * @date 15/10/19
2064
+ * @since 5.8.6
2065
+ *
2066
+ * @param object obj A GeocoderResult object.
2067
+ * @return object
2068
+ */
2069
+ parseResult: function( obj ) {
2070
+
2071
+ // Construct basic data.
2072
+ var result = {
2073
+ address: obj.formatted_address,
2074
+ lat: obj.geometry.location.lat(),
2075
+ lng: obj.geometry.location.lng(),
2076
+ };
2077
+
2078
+ // Add zoom level.
2079
+ result.zoom = this.map.getZoom();
2080
+
2081
+ // Add place ID.
2082
+ if( obj.place_id ) {
2083
+ result.place_id = obj.place_id;
2084
+ }
2085
+
2086
+ // Add place name.
2087
+ if( obj.name ) {
2088
+ result.name = obj.name;
2089
+ }
2090
+
2091
+ // Create search map for address component data.
2092
+ var map = {
2093
+ street_number: [ 'street_number' ],
2094
+ street_name: [ 'street_address', 'route' ],
2095
+ city: [ 'locality' ],
2096
+ state: [
2097
+ 'administrative_area_level_1',
2098
+ 'administrative_area_level_2',
2099
+ 'administrative_area_level_3',
2100
+ 'administrative_area_level_4',
2101
+ 'administrative_area_level_5'
2102
+ ],
2103
+ post_code: [ 'postal_code' ],
2104
+ country: [ 'country' ]
2105
+ };
2106
+
2107
+ // Loop over map.
2108
+ for( var k in map ) {
2109
+ var keywords = map[ k ];
2110
+
2111
+ // Loop over address components.
2112
+ for( var i = 0; i < obj.address_components.length; i++ ) {
2113
+ var component = obj.address_components[ i ];
2114
+ var component_type = component.types[0];
2115
+
2116
+ // Look for matching component type.
2117
+ if( keywords.indexOf(component_type) !== -1 ) {
2118
+
2119
+ // Append to result.
2120
+ result[ k ] = component.long_name;
2121
+
2122
+ // Append short version.
2123
+ if( component.long_name !== component.short_name ) {
2124
+ result[ k + '_short' ] = component.short_name;
2125
+ }
2126
+ }
2127
+ }
2128
+ }
2129
+
2130
+ /**
2131
+ * Filters the parsed result.
2132
+ *
2133
+ * @date 18/10/19
2134
+ * @since 5.8.6
2135
+ *
2136
+ * @param object result The parsed result value.
2137
+ * @param object obj The GeocoderResult object.
2138
+ */
2139
+ return acf.applyFilters('google_map_result', result, obj, this.map, this);
2140
+ },
2141
+
2142
+ onClickClear: function(){
2143
+ this.val( false );
2144
+ },
2145
+
2146
+ onClickLocate: function(){
2147
+ this.searchLocation();
2148
+ },
2149
+
2150
+ onClickSearch: function(){
2151
+ this.searchAddress( this.$search().val() );
2152
+ },
2153
+
2154
+ onFocusSearch: function( e, $el ){
2155
+ this.setState( 'searching' );
2156
+ },
2157
+
2158
+ onBlurSearch: function( e, $el ){
2159
+
2160
+ // Get saved address value.
2161
+ var val = this.val();
2162
+ var address = val ? val.address : '';
2163
+
2164
+ // Remove 'is-searching' if value has not changed.
2165
+ if( $el.val() === address ) {
2166
+ this.setState( 'default' );
2167
+ }
2168
+ },
2169
+
2170
+ onKeyupSearch: function( e, $el ){
2171
+
2172
+ // Clear empty value.
2173
+ if( !$el.val() ) {
2174
+ this.val( false );
2175
+ }
2176
+ },
2177
+
2178
+ // Prevent form from submitting.
2179
+ onKeydownSearch: function( e, $el ){
2180
+ if( e.which == 13 ) {
2181
+ e.preventDefault();
2182
+ $el.blur();
2183
+ }
2184
+ },
2185
+
2186
+ // Center map once made visible.
2187
+ onShow: function(){
2188
+ if( this.map ) {
2189
+ this.setTimeout( this.center );
2190
+ }
2191
+ },
2192
+ });
2193
+
2194
+ acf.registerFieldType( Field );
2195
+
2196
+ // Vars.
2197
+ var loading = false;
2198
+ var geocoder = false;
2199
+
2200
+ /**
2201
+ * withAPI
2202
+ *
2203
+ * Loads the Google Maps API library and troggers callback.
2204
+ *
2205
+ * @date 28/3/19
2206
+ * @since 5.7.14
2207
+ *
2208
+ * @param function callback The callback to excecute.
2209
+ * @return void
2210
+ */
2211
+
2212
+ function withAPI( callback ) {
2213
+
2214
+ // Check if geocoder exists.
2215
+ if( geocoder ) {
2216
+ return callback();
2217
+ }
2218
+
2219
+ // Check if geocoder API exists.
2220
+ if( acf.isset(window, 'google', 'maps', 'Geocoder') ) {
2221
+ geocoder = new google.maps.Geocoder();
2222
+ return callback();
2223
+ }
2224
+
2225
+ // Geocoder will need to be loaded. Hook callback to action.
2226
+ acf.addAction( 'google_map_api_loaded', callback );
2227
+
2228
+ // Bail early if already loading API.
2229
+ if( loading ) {
2230
+ return;
2231
+ }
2232
+
2233
+ // load api
2234
+ var url = acf.get('google_map_api');
2235
+ if( url ) {
2236
+
2237
+ // Set loading status.
2238
+ loading = true;
2239
+
2240
+ // Load API
2241
+ $.ajax({
2242
+ url: url,
2243
+ dataType: 'script',
2244
+ cache: true,
2245
+ success: function(){
2246
+ geocoder = new google.maps.Geocoder();
2247
+ acf.doAction('google_map_api_loaded');
2248
+ }
2249
+ });
2250
+ }
2251
+ }
2252
+
2253
+ })(jQuery);
2254
+ (function($, undefined){
2255
+
2256
+ var Field = acf.Field.extend({
2257
+
2258
+ type: 'image',
2259
+
2260
+ $control: function(){
2261
+ return this.$('.acf-image-uploader');
2262
+ },
2263
+
2264
+ $input: function(){
2265
+ return this.$('input[type="hidden"]');
2266
+ },
2267
+
2268
+ events: {
2269
+ 'click a[data-name="add"]': 'onClickAdd',
2270
+ 'click a[data-name="edit"]': 'onClickEdit',
2271
+ 'click a[data-name="remove"]': 'onClickRemove',
2272
+ 'change input[type="file"]': 'onChange'
2273
+ },
2274
+
2275
+ initialize: function(){
2276
+
2277
+ // add attribute to form
2278
+ if( this.get('uploader') === 'basic' ) {
2279
+ this.$el.closest('form').attr('enctype', 'multipart/form-data');
2280
+ }
2281
+ },
2282
+
2283
+ validateAttachment: function( attachment ){
2284
+
2285
+ // Use WP attachment attributes when available.
2286
+ if( attachment && attachment.attributes ) {
2287
+ attachment = attachment.attributes;
2288
+ }
2289
+
2290
+ // Apply defaults.
2291
+ attachment = acf.parseArgs(attachment, {
2292
+ id: 0,
2293
+ url: '',
2294
+ alt: '',
2295
+ title: '',
2296
+ caption: '',
2297
+ description: '',
2298
+ width: 0,
2299
+ height: 0
2300
+ });
2301
+
2302
+ // Override with "preview size".
2303
+ var size = acf.isget( attachment, 'sizes', this.get('preview_size') );
2304
+ if( size ) {
2305
+ attachment.url = size.url;
2306
+ attachment.width = size.width;
2307
+ attachment.height = size.height;
2308
+ }
2309
+
2310
+ // Return.
2311
+ return attachment;
2312
+ },
2313
+
2314
+ render: function( attachment ){
2315
+ attachment = this.validateAttachment( attachment );
2316
+
2317
+ // Update DOM.
2318
+ this.$('img').attr({
2319
+ src: attachment.url,
2320
+ alt: attachment.alt
2321
+ });
2322
+ if( attachment.id ) {
2323
+ this.val( attachment.id );
2324
+ this.$control().addClass('has-value');
2325
+ } else {
2326
+ this.val( '' );
2327
+ this.$control().removeClass('has-value');
2328
+ }
2329
+ },
2330
+
2331
+ // create a new repeater row and render value
2332
+ append: function( attachment, parent ){
2333
+
2334
+ // create function to find next available field within parent
2335
+ var getNext = function( field, parent ){
2336
+
2337
+ // find existing file fields within parent
2338
+ var fields = acf.getFields({
2339
+ key: field.get('key'),
2340
+ parent: parent.$el
2341
+ });
2342
+
2343
+ // find the first field with no value
2344
+ for( var i = 0; i < fields.length; i++ ) {
2345
+ if( !fields[i].val() ) {
2346
+ return fields[i];
2347
+ }
2348
+ }
2349
+
2350
+ // return
2351
+ return false;
2352
+ }
2353
+
2354
+ // find existing file fields within parent
2355
+ var field = getNext( this, parent );
2356
+
2357
+ // add new row if no available field
2358
+ if( !field ) {
2359
+ parent.$('.acf-button:last').trigger('click');
2360
+ field = getNext( this, parent );
2361
+ }
2362
+
2363
+ // render
2364
+ if( field ) {
2365
+ field.render( attachment );
2366
+ }
2367
+ },
2368
+
2369
+ selectAttachment: function(){
2370
+
2371
+ // vars
2372
+ var parent = this.parent();
2373
+ var multiple = (parent && parent.get('type') === 'repeater');
2374
+
2375
+ // new frame
2376
+ var frame = acf.newMediaPopup({
2377
+ mode: 'select',
2378
+ type: 'image',
2379
+ title: acf.__('Select Image'),
2380
+ field: this.get('key'),
2381
+ multiple: multiple,
2382
+ library: this.get('library'),
2383
+ allowedTypes: this.get('mime_types'),
2384
+ select: $.proxy(function( attachment, i ) {
2385
+ if( i > 0 ) {
2386
+ this.append( attachment, parent );
2387
+ } else {
2388
+ this.render( attachment );
2389
+ }
2390
+ }, this)
2391
+ });
2392
+ },
2393
+
2394
+ editAttachment: function(){
2395
+
2396
+ // vars
2397
+ var val = this.val();
2398
+
2399
+ // bail early if no val
2400
+ if( !val ) return;
2401
+
2402
+ // popup
2403
+ var frame = acf.newMediaPopup({
2404
+ mode: 'edit',
2405
+ title: acf.__('Edit Image'),
2406
+ button: acf.__('Update Image'),
2407
+ attachment: val,
2408
+ field: this.get('key'),
2409
+ select: $.proxy(function( attachment, i ) {
2410
+ this.render( attachment );
2411
+ }, this)
2412
+ });
2413
+ },
2414
+
2415
+ removeAttachment: function(){
2416
+ this.render( false );
2417
+ },
2418
+
2419
+ onClickAdd: function( e, $el ){
2420
+ this.selectAttachment();
2421
+ },
2422
+
2423
+ onClickEdit: function( e, $el ){
2424
+ this.editAttachment();
2425
+ },
2426
+
2427
+ onClickRemove: function( e, $el ){
2428
+ this.removeAttachment();
2429
+ },
2430
+
2431
+ onChange: function( e, $el ){
2432
+ var $hiddenInput = this.$input();
2433
+
2434
+ acf.getFileInputData($el, function( data ){
2435
+ $hiddenInput.val( $.param(data) );
2436
+ });
2437
+ }
2438
+ });
2439
+
2440
+ acf.registerFieldType( Field );
2441
 
2442
+ })(jQuery);
2443
+ (function($, undefined){
2444
+
2445
+ var Field = acf.models.ImageField.extend({
2446
+
2447
+ type: 'file',
2448
+
2449
+ $control: function(){
2450
+ return this.$('.acf-file-uploader');
2451
+ },
2452
+
2453
+ $input: function(){
2454
+ return this.$('input[type="hidden"]');
2455
+ },
2456
+
2457
+ validateAttachment: function( attachment ){
2458
+
2459
+ // defaults
2460
+ attachment = attachment || {};
2461
+
2462
+ // WP attachment
2463
+ if( attachment.id !== undefined ) {
2464
+ attachment = attachment.attributes;
2465
+ }
2466
+
2467
+ // args
2468
+ attachment = acf.parseArgs(attachment, {
2469
+ url: '',
2470
+ alt: '',
2471
+ title: '',
2472
+ filename: '',
2473
+ filesizeHumanReadable: '',
2474
+ icon: '/wp-includes/images/media/default.png'
2475
+ });
2476
+
2477
+ // return
2478
+ return attachment;
2479
+ },
2480
+
2481
+ render: function( attachment ){
2482
+
2483
+ // vars
2484
+ attachment = this.validateAttachment( attachment );
2485
+
2486
+ // update image
2487
+ this.$('img').attr({
2488
+ src: attachment.icon,
2489
+ alt: attachment.alt,
2490
+ title: attachment.title
2491
+ });
2492
+
2493
+ // update elements
2494
+ this.$('[data-name="title"]').text( attachment.title );
2495
+ this.$('[data-name="filename"]').text( attachment.filename ).attr( 'href', attachment.url );
2496
+ this.$('[data-name="filesize"]').text( attachment.filesizeHumanReadable );
2497
+
2498
+ // vars
2499
+ var val = attachment.id || '';
2500
+
2501
+ // update val
2502
+ acf.val( this.$input(), val );
2503
+
2504
+ // update class
2505
+ if( val ) {
2506
+ this.$control().addClass('has-value');
2507
+ } else {
2508
+ this.$control().removeClass('has-value');
2509
+ }
2510
+ },
2511
+
2512
+ selectAttachment: function(){
2513
+
2514
+ // vars
2515
+ var parent = this.parent();
2516
+ var multiple = (parent && parent.get('type') === 'repeater');
2517
+
2518
+ // new frame
2519
+ var frame = acf.newMediaPopup({
2520
+ mode: 'select',
2521
+ title: acf.__('Select File'),
2522
+ field: this.get('key'),
2523
+ multiple: multiple,
2524
+ library: this.get('library'),
2525
+ allowedTypes: this.get('mime_types'),
2526
+ select: $.proxy(function( attachment, i ) {
2527
+ if( i > 0 ) {
2528
+ this.append( attachment, parent );
2529
+ } else {
2530
+ this.render( attachment );
2531
+ }
2532
+ }, this)
2533
+ });
2534
+ },
2535
+
2536
+ editAttachment: function(){
2537
+
2538
+ // vars
2539
+ var val = this.val();
2540
+
2541
+ // bail early if no val
2542
+ if( !val ) {
2543
+ return false;
2544
+ }
2545
+
2546
+ // popup
2547
+ var frame = acf.newMediaPopup({
2548
+ mode: 'edit',
2549
+ title: acf.__('Edit File'),
2550
+ button: acf.__('Update File'),
2551
+ attachment: val,
2552
+ field: this.get('key'),
2553
+ select: $.proxy(function( attachment, i ) {
2554
+ this.render( attachment );
2555
+ }, this)
2556
+ });
2557
+ }
2558
+ });
2559
+
2560
+ acf.registerFieldType( Field );
2561
+
2562
+ })(jQuery);
2563
+ (function($, undefined){
2564
+
2565
+ var Field = acf.Field.extend({
2566
+
2567
+ type: 'link',
2568
+
2569
+ events: {
2570
+ 'click a[data-name="add"]': 'onClickEdit',
2571
+ 'click a[data-name="edit"]': 'onClickEdit',
2572
+ 'click a[data-name="remove"]': 'onClickRemove',
2573
+ 'change .link-node': 'onChange',
2574
+ },
2575
+
2576
+ $control: function(){
2577
+ return this.$('.acf-link');
2578
+ },
2579
+
2580
+ $node: function(){
2581
+ return this.$('.link-node');
2582
+ },
2583
+
2584
+ getValue: function(){
2585
+
2586
+ // vars
2587
+ var $node = this.$node();
2588
+
2589
+ // return false if empty
2590
+ if( !$node.attr('href') ) {
2591
+ return false;
2592
+ }
2593
+
2594
+ // return
2595
+ return {
2596
+ title: $node.html(),
2597
+ url: $node.attr('href'),
2598
+ target: $node.attr('target')
2599
+ };
2600
+ },
2601
+
2602
+ setValue: function( val ){
2603
+
2604
+ // default
2605
+ val = acf.parseArgs(val, {
2606
+ title: '',
2607
+ url: '',
2608
+ target: ''
2609
+ });
2610
+
2611
+ // vars
2612
+ var $div = this.$control();
2613
+ var $node = this.$node();
2614
+
2615
+ // remove class
2616
+ $div.removeClass('-value -external');
2617
+
2618
+ // add class
2619
+ if( val.url ) $div.addClass('-value');
2620
+ if( val.target === '_blank' ) $div.addClass('-external');
2621
+
2622
+ // update text
2623
+ this.$('.link-title').html( val.title );
2624
+ this.$('.link-url').attr('href', val.url).html( val.url );
2625
+
2626
+ // update node
2627
+ $node.html(val.title);
2628
+ $node.attr('href', val.url);
2629
+ $node.attr('target', val.target);
2630
+
2631
+ // update inputs
2632
+ this.$('.input-title').val( val.title );
2633
+ this.$('.input-target').val( val.target );
2634
+ this.$('.input-url').val( val.url ).trigger('change');
2635
+ },
2636
+
2637
+ onClickEdit: function( e, $el ){
2638
+ acf.wpLink.open( this.$node() );
2639
+ },
2640
+
2641
+ onClickRemove: function( e, $el ){
2642
+ this.setValue( false );
2643
+ },
2644
+
2645
+ onChange: function( e, $el ){
2646
+
2647
+ // get the changed value
2648
+ var val = this.getValue();
2649
+
2650
+ // update inputs
2651
+ this.setValue(val);
2652
+ }
2653
+
2654
+ });
2655
+
2656
+ acf.registerFieldType( Field );
2657
+
2658
+
2659
+ // manager
2660
+ acf.wpLink = new acf.Model({
2661
+
2662
+ getNodeValue: function(){
2663
+ var $node = this.get('node');
2664
+ return {
2665
+ title: acf.decode( $node.html() ),
2666
+ url: $node.attr('href'),
2667
+ target: $node.attr('target')
2668
+ };
2669
+ },
2670
+
2671
+ setNodeValue: function( val ){
2672
+ var $node = this.get('node');
2673
+ $node.text( val.title );
2674
+ $node.attr('href', val.url);
2675
+ $node.attr('target', val.target);
2676
+ $node.trigger('change');
2677
+ },
2678
+
2679
+ getInputValue: function(){
2680
+ return {
2681
+ title: $('#wp-link-text').val(),
2682
+ url: $('#wp-link-url').val(),
2683
+ target: $('#wp-link-target').prop('checked') ? '_blank' : ''
2684
+ };
2685
+ },
2686
+
2687
+ setInputValue: function( val ){
2688
+ $('#wp-link-text').val( val.title );
2689
+ $('#wp-link-url').val( val.url );
2690
+ $('#wp-link-target').prop('checked', val.target === '_blank' );
2691
+ },
2692
+
2693
+ open: function( $node ){
2694
+
2695
+ // add events
2696
+ this.on('wplink-open', 'onOpen');
2697
+ this.on('wplink-close', 'onClose');
2698
+
2699
+ // set node
2700
+ this.set('node', $node);
2701
+
2702
+ // create textarea
2703
+ var $textarea = $('<textarea id="acf-link-textarea" style="display:none;"></textarea>');
2704
+ $('body').append( $textarea );
2705
+
2706
+ // vars
2707
+ var val = this.getNodeValue();
2708
+
2709
+ // open popup
2710
+ wpLink.open( 'acf-link-textarea', val.url, val.title, null );
2711
+ },
2712
+
2713
+ onOpen: function(){
2714
+
2715
+ // always show title (WP will hide title if empty)
2716
+ $('#wp-link-wrap').addClass('has-text-field');
2717
+
2718
+ // set inputs
2719
+ var val = this.getNodeValue();
2720
+ this.setInputValue( val );
2721
+
2722
+ // Update button text.
2723
+ if( val.url && wpLinkL10n ) {
2724
+ $('#wp-link-submit').val( wpLinkL10n.update );
2725
+ }
2726
+ },
2727
+
2728
+ close: function(){
2729
+ wpLink.close();
2730
+ },
2731
+
2732
+ onClose: function(){
2733
+
2734
+ // Bail early if no node.
2735
+ // Needed due to WP triggering this event twice.
2736
+ if( !this.has('node') ) {
2737
+ return false;
2738
+ }
2739
+
2740
+ // Determine context.
2741
+ var $submit = $('#wp-link-submit');
2742
+ var isSubmit = ( $submit.is(':hover') || $submit.is(':focus') );
2743
+
2744
+ // Set value
2745
+ if( isSubmit ) {
2746
+ var val = this.getInputValue();
2747
+ this.setNodeValue( val );
2748
+ }
2749
+
2750
+ // Cleanup.
2751
+ this.off('wplink-open');
2752
+ this.off('wplink-close');
2753
+ $('#acf-link-textarea').remove();
2754
+ this.set('node', null);
2755
+ }
2756
+ });
2757
 
2758
+ })(jQuery);
2759
+ (function($, undefined){
2760
+
2761
+ var Field = acf.Field.extend({
2762
+
2763
+ type: 'oembed',
2764
+
2765
+ events: {
2766
+ 'click [data-name="clear-button"]': 'onClickClear',
2767
+ 'keypress .input-search': 'onKeypressSearch',
2768
+ 'keyup .input-search': 'onKeyupSearch',
2769
+ 'change .input-search': 'onChangeSearch'
2770
+ },
2771
+
2772
+ $control: function(){
2773
+ return this.$('.acf-oembed');
2774
+ },
2775
+
2776
+ $input: function(){
2777
+ return this.$('.input-value');
2778
+ },
2779
+
2780
+ $search: function(){
2781
+ return this.$('.input-search');
2782
+ },
2783
+
2784
+ getValue: function(){
2785
+ return this.$input().val();
2786
+ },
2787
+
2788
+ getSearchVal: function(){
2789
+ return this.$search().val();
2790
+ },
2791
+
2792
+ setValue: function( val ){
2793
+
2794
+ // class
2795
+ if( val ) {
2796
+ this.$control().addClass('has-value');
2797
+ } else {
2798
+ this.$control().removeClass('has-value');
2799
+ }
2800
+
2801
+ acf.val( this.$input(), val );
2802
+ },
2803
+
2804
+ showLoading: function( show ){
2805
+ acf.showLoading( this.$('.canvas') );
2806
+ },
2807
+
2808
+ hideLoading: function(){
2809
+ acf.hideLoading( this.$('.canvas') );
2810
+ },
2811
+
2812
+ maybeSearch: function(){
2813
+
2814
+ // vars
2815
+ var prevUrl = this.val();
2816
+ var url = this.getSearchVal();
2817
+
2818
+ // no value
2819
+ if( !url ) {
2820
+ return this.clear();
2821
+ }
2822
+
2823
+ // fix missing 'http://' - causes the oembed code to error and fail
2824
+ if( url.substr(0, 4) != 'http' ) {
2825
+ url = 'http://' + url;
2826
+ }
2827
+
2828
+ // bail early if no change
2829
+ if( url === prevUrl ) return;
2830
+
2831
+ // clear existing timeout
2832
+ var timeout = this.get('timeout');
2833
+ if( timeout ) {
2834
+ clearTimeout( timeout );
2835
+ }
2836
+
2837
+ // set new timeout
2838
+ var callback = $.proxy(this.search, this, url);
2839
+ this.set('timeout', setTimeout(callback, 300));
2840
+
2841
+ },
2842
+
2843
+ search: function( url ){
2844
+
2845
+ // ajax
2846
+ var ajaxData = {
2847
+ action: 'acf/fields/oembed/search',
2848
+ s: url,
2849
+ field_key: this.get('key')
2850
+ };
2851
+
2852
+ // clear existing timeout
2853
+ var xhr = this.get('xhr');
2854
+ if( xhr ) {
2855
+ xhr.abort();
2856
+ }
2857
+
2858
+ // loading
2859
+ this.showLoading();
2860
+
2861
+ // query
2862
+ var xhr = $.ajax({
2863
+ url: acf.get('ajaxurl'),
2864
+ data: acf.prepareForAjax(ajaxData),
2865
+ type: 'post',
2866
+ dataType: 'json',
2867
+ context: this,
2868
+ success: function( json ){
2869
+
2870
+ // error
2871
+ if( !json || !json.html ) {
2872
+ json = {
2873
+ url: false,
2874
+ html: ''
2875
+ }
2876
+ }
2877
+
2878
+ // update vars
2879
+ this.val( json.url );
2880
+ this.$('.canvas-media').html( json.html );
2881
+ },
2882
+ complete: function(){
2883
+ this.hideLoading();
2884
+ }
2885
+ });
2886
+
2887
+ this.set('xhr', xhr);
2888
+ },
2889
+
2890
+ clear: function(){
2891
+ this.val('');
2892
+ this.$search().val('');
2893
+ this.$('.canvas-media').html('');
2894
+ },
2895
+
2896
+ onClickClear: function( e, $el ){
2897
+ this.clear();
2898
+ },
2899
+
2900
+ onKeypressSearch: function( e, $el ){
2901
+ if( e.which == 13 ) {
2902
+ e.preventDefault();
2903
+ this.maybeSearch();
2904
+ }
2905
+ },
2906
+
2907
+ onKeyupSearch: function( e, $el ){
2908
+ if( $el.val() ) {
2909
+ this.maybeSearch();
2910
+ }
2911
+ },
2912
+
2913
+ onChangeSearch: function( e, $el ){
2914
+ this.maybeSearch();
2915
+ }
2916
+
2917
+ });
2918
+
2919
+ acf.registerFieldType( Field );
2920
 
2921
+ })(jQuery);
2922
+ (function($, undefined){
2923
+
2924
+ var Field = acf.Field.extend({
2925
+
2926
+ type: 'radio',
2927
+
2928
+ events: {
2929
+ 'click input[type="radio"]': 'onClick',
2930
+ },
2931
+
2932
+ $control: function(){
2933
+ return this.$('.acf-radio-list');
2934
+ },
2935
+
2936
+ $input: function(){
2937
+ return this.$('input:checked');
2938
+ },
2939
+
2940
+ $inputText: function(){
2941
+ return this.$('input[type="text"]');
2942
+ },
2943
+
2944
+ getValue: function(){
2945
+ var val = this.$input().val();
2946
+ if( val === 'other' && this.get('other_choice') ) {
2947
+ val = this.$inputText().val();
2948
+ }
2949
+ return val;
2950
+ },
2951
+
2952
+ onClick: function( e, $el ){
2953
+
2954
+ // vars
2955
+ var $label = $el.parent('label');
2956
+ var selected = $label.hasClass('selected');
2957
+ var val = $el.val();
2958
+
2959
+ // remove previous selected
2960
+ this.$('.selected').removeClass('selected');
2961
+
2962
+ // add active class
2963
+ $label.addClass('selected');
2964
+
2965
+ // allow null
2966
+ if( this.get('allow_null') && selected ) {
2967
+ $label.removeClass('selected');
2968
+ $el.prop('checked', false).trigger('change');
2969
+ val = false;
2970
+ }
2971
+
2972
+ // other
2973
+ if( this.get('other_choice') ) {
2974
+
2975
+ // enable
2976
+ if( val === 'other' ) {
2977
+ this.$inputText().prop('disabled', false);
2978
+
2979
+ // disable
2980
+ } else {
2981
+ this.$inputText().prop('disabled', true);
2982
+ }
2983
+ }
2984
+ }
2985
+ });
2986
+
2987
+ acf.registerFieldType( Field );
2988
 
2989
+ })(jQuery);
2990
+ (function($, undefined){
2991
+
2992
+ var Field = acf.Field.extend({
2993
+
2994
+ type: 'range',
2995
+
2996
+ events: {
2997
+ 'input input[type="range"]': 'onChange',
2998
+ 'change input': 'onChange'
2999
+ },
3000
+
3001
+ $input: function(){
3002
+ return this.$('input[type="range"]');
3003
+ },
3004
+
3005
+ $inputAlt: function(){
3006
+ return this.$('input[type="number"]');
3007
+ },
3008
+
3009
+ setValue: function( val ){
3010
+ this.busy = true;
3011
+
3012
+ // Update range input (with change).
3013
+ acf.val( this.$input(), val );
3014
+
3015
+ // Update alt input (without change).
3016
+ // Read in input value to inherit min/max validation.
3017
+ acf.val( this.$inputAlt(), this.$input().val(), true );
3018
+
3019
+ this.busy = false;
3020
+ },
3021
+
3022
+ onChange: function( e, $el ){
3023
+ if( !this.busy ) {
3024
+ this.setValue( $el.val() );
3025
+ }
3026
+ }
3027
+ });
3028
+
3029
+ acf.registerFieldType( Field );
3030
+
3031
+ })(jQuery);
3032
+ (function($, undefined){
3033
+
3034
+ var Field = acf.Field.extend({
3035
+
3036
+ type: 'relationship',
3037
+
3038
+ events: {
3039
+ 'keypress [data-filter]': 'onKeypressFilter',
3040
+ 'change [data-filter]': 'onChangeFilter',
3041
+ 'keyup [data-filter]': 'onChangeFilter',
3042
+ 'click .choices-list .acf-rel-item': 'onClickAdd',
3043
+ 'click [data-name="remove_item"]': 'onClickRemove',
3044
+ },
3045
+
3046
+ $control: function(){
3047
+ return this.$('.acf-relationship');
3048
+ },
3049
+
3050
+ $list: function( list ) {
3051
+ return this.$('.' + list + '-list');
3052
+ },
3053
+
3054
+ $listItems: function( list ) {
3055
+ return this.$list( list ).find('.acf-rel-item');
3056
+ },
3057
+
3058
+ $listItem: function( list, id ) {
3059
+ return this.$list( list ).find('.acf-rel-item[data-id="' + id + '"]');
3060
+ },
3061
+
3062
+ getValue: function(){
3063
+ var val = [];
3064
+ this.$listItems('values').each(function(){
3065
+ val.push( $(this).data('id') );
3066
+ });
3067
+ return val.length ? val : false;
3068
+ },
3069
+
3070
+ newChoice: function( props ){
3071
+ return [
3072
+ '<li>',
3073
+ '<span data-id="' + props.id + '" class="acf-rel-item">' + props.text + '</span>',
3074
+ '</li>'
3075
+ ].join('');
3076
+ },
3077
+
3078
+ newValue: function( props ){
3079
+ return [
3080
+ '<li>',
3081
+ '<input type="hidden" name="' + this.getInputName() + '[]" value="' + props.id + '" />',
3082
+ '<span data-id="' + props.id + '" class="acf-rel-item">' + props.text,
3083
+ '<a href="#" class="acf-icon -minus small dark" data-name="remove_item"></a>',
3084
+ '</span>',
3085
+ '</li>'
3086
+ ].join('');
3087
+ },
3088
+
3089
+ initialize: function(){
3090
+
3091
+ // Delay initialization until "interacted with" or "in view".
3092
+ var delayed = this.proxy(acf.once(function(){
3093
+
3094
+ // Add sortable.
3095
+ this.$list('values').sortable({
3096
+ items: 'li',
3097
+ forceHelperSize: true,
3098
+ forcePlaceholderSize: true,
3099
+ scroll: true,
3100
+ update: this.proxy(function(){
3101
+ this.$input().trigger('change');
3102
+ })
3103
+ });
3104
+
3105
+ // Avoid browser remembering old scroll position and add event.
3106
+ this.$list('choices').scrollTop(0).on('scroll', this.proxy(this.onScrollChoices));
3107
+
3108
+ // Fetch choices.
3109
+ this.fetch();
3110
+
3111
+ }));
3112
+
3113
+ // Bind "interacted with".
3114
+ this.$el.one( 'mouseover', delayed );
3115
+ this.$el.one( 'focus', 'input', delayed );
3116
+
3117
+ // Bind "in view".
3118
+ acf.onceInView( this.$el, delayed );
3119
+ },
3120
+
3121
+ onScrollChoices: function(e){
3122
+
3123
+ // bail early if no more results
3124
+ if( this.get('loading') || !this.get('more') ) {
3125
+ return;
3126
+ }
3127
+
3128
+ // Scrolled to bottom
3129
+ var $list = this.$list('choices');
3130
+ var scrollTop = Math.ceil( $list.scrollTop() );
3131
+ var scrollHeight = Math.ceil( $list[0].scrollHeight );
3132
+ var innerHeight = Math.ceil( $list.innerHeight() );
3133
+ var paged = this.get('paged') || 1;
3134
+ if( (scrollTop + innerHeight) >= scrollHeight ) {
3135
+
3136
+ // update paged
3137
+ this.set('paged', (paged+1));
3138
+
3139
+ // fetch
3140
+ this.fetch();
3141
+ }
3142
+ },
3143
+
3144
+ onKeypressFilter: function( e, $el ){
3145
+
3146
+ // don't submit form
3147
+ if( e.which == 13 ) {
3148
+ e.preventDefault();
3149
+ }
3150
+ },
3151
+
3152
+ onChangeFilter: function( e, $el ){
3153
+
3154
+ // vars
3155
+ var val = $el.val();
3156
+ var filter = $el.data('filter');
3157
+
3158
+ // Bail early if filter has not changed
3159
+ if( this.get(filter) === val ) {
3160
+ return;
3161
+ }
3162
+
3163
+ // update attr
3164
+ this.set(filter, val);
3165
+
3166
+ // reset paged
3167
+ this.set('paged', 1);
3168
+
3169
+ // fetch
3170
+ if( $el.is('select') ) {
3171
+ this.fetch();
3172
+
3173
+ // search must go through timeout
3174
+ } else {
3175
+ this.maybeFetch();
3176
+ }
3177
+ },
3178
+
3179
+ onClickAdd: function( e, $el ){
3180
+
3181
+ // vars
3182
+ var val = this.val();
3183
+ var max = parseInt( this.get('max') );
3184
+
3185
+ // can be added?
3186
+ if( $el.hasClass('disabled') ) {
3187
+ return false;
3188
+ }
3189
+
3190
+ // validate
3191
+ if( max > 0 && val && val.length >= max ) {
3192
+
3193
+ // add notice
3194
+ this.showNotice({
3195
+ text: acf.__('Maximum values reached ( {max} values )').replace('{max}', max),
3196
+ type: 'warning'
3197
+ });
3198
+ return false;
3199
+ }
3200
+
3201
+ // disable
3202
+ $el.addClass('disabled');
3203
+
3204
+ // add
3205
+ var html = this.newValue({
3206
+ id: $el.data('id'),
3207
+ text: $el.html()
3208
+ });
3209
+ this.$list('values').append( html )
3210
+
3211
+ // trigger change
3212
+ this.$input().trigger('change');
3213
+ },
3214
+
3215
+ onClickRemove: function( e, $el ){
3216
+
3217
+ // Prevent default here because generic handler wont be triggered.
3218
+ e.preventDefault();
3219
+
3220
+ // vars
3221
+ var $span = $el.parent();
3222
+ var $li = $span.parent();
3223
+ var id = $span.data('id');
3224
+
3225
+ // remove value
3226
+ $li.remove();
3227
+
3228
+ // show choice
3229
+ this.$listItem('choices', id).removeClass('disabled');
3230
+
3231
+ // trigger change
3232
+ this.$input().trigger('change');
3233
+ },
3234
+
3235
+ maybeFetch: function(){
3236
+
3237
+ // vars
3238
+ var timeout = this.get('timeout');
3239
+
3240
+ // abort timeout
3241
+ if( timeout ) {
3242
+ clearTimeout( timeout );
3243
+ }
3244
+
3245
+ // fetch
3246
+ timeout = this.setTimeout(this.fetch, 300);
3247
+ this.set('timeout', timeout);
3248
+ },
3249
+
3250
+ getAjaxData: function(){
3251
+
3252
+ // load data based on element attributes
3253
+ var ajaxData = this.$control().data();
3254
+ for( var name in ajaxData ) {
3255
+ ajaxData[ name ] = this.get( name );
3256
+ }
3257
+
3258
+ // extra
3259
+ ajaxData.action = 'acf/fields/relationship/query';
3260
+ ajaxData.field_key = this.get('key');
3261
+
3262
+ // Filter.
3263
+ ajaxData = acf.applyFilters( 'relationship_ajax_data', ajaxData, this );
3264
+
3265
+ // return
3266
+ return ajaxData;
3267
+ },
3268
+
3269
+ fetch: function(){
3270
+
3271
+ // abort XHR if this field is already loading AJAX data
3272
+ var xhr = this.get('xhr');
3273
+ if( xhr ) {
3274
+ xhr.abort();
3275
+ }
3276
+
3277
+ // add to this.o
3278
+ var ajaxData = this.getAjaxData();
3279
+
3280
+ // clear html if is new query
3281
+ var $choiceslist = this.$list( 'choices' );
3282
+ if( ajaxData.paged == 1 ) {
3283
+ $choiceslist.html('');
3284
+ }
3285
+
3286
+ // loading
3287
+ var $loading = $('<li><i class="acf-loading"></i> ' + acf.__('Loading') + '</li>');
3288
+ $choiceslist.append($loading);
3289
+ this.set('loading', true);
3290
+
3291
+ // callback
3292
+ var onComplete = function(){
3293
+ this.set('loading', false);
3294
+ $loading.remove();
3295
+ };
3296
+
3297
+ var onSuccess = function( json ){
3298
+
3299
+ // no results
3300
+ if( !json || !json.results || !json.results.length ) {
3301
+
3302
+ // prevent pagination
3303
+ this.set('more', false);
3304
+
3305
+ // add message
3306
+ if( this.get('paged') == 1 ) {
3307
+ this.$list('choices').append('<li>' + acf.__('No matches found') + '</li>');
3308
+ }
3309
+
3310
+ // return
3311
+ return;
3312
+ }
3313
+
3314
+ // set more (allows pagination scroll)
3315
+ this.set('more', json.more );
3316
+
3317
+ // get new results
3318
+ var html = this.walkChoices(json.results);
3319
+ var $html = $( html );
3320
+
3321
+ // apply .disabled to left li's
3322
+ var val = this.val();
3323
+ if( val && val.length ) {
3324
+ val.map(function( id ){
3325
+ $html.find('.acf-rel-item[data-id="' + id + '"]').addClass('disabled');
3326
+ });
3327
+ }
3328
+
3329
+ // append
3330
+ $choiceslist.append( $html );
3331
+
3332
+ // merge together groups
3333
+ var $prevLabel = false;
3334
+ var $prevList = false;
3335
+
3336
+ $choiceslist.find('.acf-rel-label').each(function(){
3337
+
3338
+ var $label = $(this);
3339
+ var $list = $label.siblings('ul');
3340
+
3341
+ if( $prevLabel && $prevLabel.text() == $label.text() ) {
3342
+ $prevList.append( $list.children() );
3343
+ $(this).parent().remove();
3344
+ return;
3345
+ }
3346
+
3347
+ // update vars
3348
+ $prevLabel = $label;
3349
+ $prevList = $list;
3350
+ });
3351
+ };
3352
+
3353
+ // get results
3354
+ var xhr = $.ajax({
3355
+ url: acf.get('ajaxurl'),
3356
+ dataType: 'json',
3357
+ type: 'post',
3358
+ data: acf.prepareForAjax(ajaxData),
3359
+ context: this,
3360
+ success: onSuccess,
3361
+ complete: onComplete
3362
+ });
3363
+
3364
+ // set
3365
+ this.set('xhr', xhr);
3366
+ },
3367
+
3368
+ walkChoices: function( data ){
3369
+
3370
+ // walker
3371
+ var walk = function( data ){
3372
+
3373
+ // vars
3374
+ var html = '';
3375
+
3376
+ // is array
3377
+ if( $.isArray(data) ) {
3378
+ data.map(function(item){
3379
+ html += walk( item );
3380
+ });
3381
+
3382
+ // is item
3383
+ } else if( $.isPlainObject(data) ) {
3384
+
3385
+ // group
3386
+ if( data.children !== undefined ) {
3387
+
3388
+ html += '<li><span class="acf-rel-label">' + acf.escHtml( data.text ) + '</span><ul class="acf-bl">';
3389
+ html += walk( data.children );
3390
+ html += '</ul></li>';
3391
+
3392
+ // single
3393
+ } else {
3394
+ html += '<li><span class="acf-rel-item" data-id="' + acf.escAttr( data.id ) + '">' + acf.escHtml( data.text ) + '</span></li>';
3395
+ }
3396
+ }
3397
+
3398
+ // return
3399
+ return html;
3400
+ };
3401
+
3402
+ return walk( data );
3403
+ }
3404
+
3405
+ });
3406
+
3407
+ acf.registerFieldType( Field );
3408
+
3409
+ })(jQuery);
3410
+ (function($, undefined){
3411
+
3412
+ var Field = acf.Field.extend({
3413
+
3414
+ type: 'select',
3415
+
3416
+ select2: false,
3417
+
3418
+ wait: 'load',
3419
+
3420
+ events: {
3421
+ 'removeField': 'onRemove',
3422
+ 'duplicateField': 'onDuplicate'
3423
+ },
3424
+
3425
+ $input: function(){
3426
+ return this.$('select');
3427
+ },
3428
+
3429
+ initialize: function(){
3430
+
3431
+ // vars
3432
+ var $select = this.$input();
3433
+
3434
+ // inherit data
3435
+ this.inherit( $select );
3436
+
3437
+ // select2
3438
+ if( this.get('ui') ) {
3439
+
3440
+ // populate ajax_data (allowing custom attribute to already exist)
3441
+ var ajaxAction = this.get('ajax_action');
3442
+ if( !ajaxAction ) {
3443
+ ajaxAction = 'acf/fields/' + this.get('type') + '/query';
3444
+ }
3445
+
3446
+ // select2
3447
+ this.select2 = acf.newSelect2($select, {
3448
+ field: this,
3449
+ ajax: this.get('ajax'),
3450
+ multiple: this.get('multiple'),
3451
+ placeholder: this.get('placeholder'),
3452
+ allowNull: this.get('allow_null'),
3453
+ ajaxAction: ajaxAction,
3454
+ });
3455
+ }
3456
+ },
3457
+
3458
+ onRemove: function(){
3459
+ if( this.select2 ) {
3460
+ this.select2.destroy();
3461
+ }
3462
+ },
3463
+
3464
+ onDuplicate: function( e, $el, $duplicate ){
3465
+ if( this.select2 ) {
3466
+ $duplicate.find('.select2-container').remove();
3467
+ $duplicate.find('select').removeClass('select2-hidden-accessible');
3468
+ }
3469
+ }
3470
+ });
3471
+
3472
+ acf.registerFieldType( Field );
3473
+
3474
+ })(jQuery);
3475
+ (function($, undefined){
3476
+
3477
+ // vars
3478
+ var CONTEXT = 'tab';
3479
+
3480
+ var Field = acf.Field.extend({
3481
+
3482
+ type: 'tab',
3483
+
3484
+ wait: '',
3485
+
3486
+ tabs: false,
3487
+
3488
+ tab: false,
3489
+
3490
+ events: {
3491
+ 'duplicateField': 'onDuplicate'
3492
+ },
3493
+
3494
+ findFields: function(){
3495
+ return this.$el.nextUntil('.acf-field-tab', '.acf-field');
3496
+ },
3497
+
3498
+ getFields: function(){
3499
+ return acf.getFields( this.findFields() );
3500
+ },
3501
+
3502
+ findTabs: function(){
3503
+ return this.$el.prevAll('.acf-tab-wrap:first');
3504
+ },
3505
+
3506
+ findTab: function(){
3507
+ return this.$('.acf-tab-button');
3508
+ },
3509
+
3510
+ initialize: function(){
3511
+
3512
+ // bail early if is td
3513
+ if( this.$el.is('td') ) {
3514
+ this.events = {};
3515
+ return false;
3516
+ }
3517
+
3518
+ // vars
3519
+ var $tabs = this.findTabs();
3520
+ var $tab = this.findTab();
3521
+ var settings = acf.parseArgs($tab.data(), {
3522
+ endpoint: false,
3523
+ placement: '',
3524
+ before: this.$el
3525
+ });
3526
+
3527
+ // create wrap
3528
+ if( !$tabs.length || settings.endpoint ) {
3529
+ this.tabs = new Tabs( settings );
3530
+ } else {
3531
+ this.tabs = $tabs.data('acf');
3532
+ }
3533
+
3534
+ // add tab
3535
+ this.tab = this.tabs.addTab($tab, this);
3536
+ },
3537
+
3538
+ isActive: function(){
3539
+ return this.tab.isActive();
3540
+ },
3541
+
3542
+ showFields: function(){
3543
+
3544
+ // show fields
3545
+ this.getFields().map(function( field ){
3546
+ field.show( this.cid, CONTEXT );
3547
+ field.hiddenByTab = false;
3548
+ }, this);
3549
+
3550
+ },
3551
+
3552
+ hideFields: function(){
3553
+
3554
+ // hide fields
3555
+ this.getFields().map(function( field ){
3556
+ field.hide( this.cid, CONTEXT );
3557
+ field.hiddenByTab = this.tab;
3558
+ }, this);
3559
+
3560
+ },
3561
+
3562
+ show: function( lockKey ){
3563
+
3564
+ // show field and store result
3565
+ var visible = acf.Field.prototype.show.apply(this, arguments);
3566
+
3567
+ // check if now visible
3568
+ if( visible ) {
3569
+
3570
+ // show tab
3571
+ this.tab.show();
3572
+
3573
+ // check active tabs
3574
+ this.tabs.refresh();
3575
+ }
3576
+
3577
+ // return
3578
+ return visible;
3579
+ },
3580
+
3581
+ hide: function( lockKey ){
3582
+
3583
+ // hide field and store result
3584
+ var hidden = acf.Field.prototype.hide.apply(this, arguments);
3585
+
3586
+ // check if now hidden
3587
+ if( hidden ) {
3588
+
3589
+ // hide tab
3590
+ this.tab.hide();
3591
+
3592
+ // reset tabs if this was active
3593
+ if( this.isActive() ) {
3594
+ this.tabs.reset();
3595
+ }
3596
+ }
3597
+
3598
+ // return
3599
+ return hidden;
3600
+ },
3601
+
3602
+ enable: function( lockKey ){
3603
+
3604
+ // enable fields
3605
+ this.getFields().map(function( field ){
3606
+ field.enable( CONTEXT );
3607
+ });
3608
+ },
3609
+
3610
+ disable: function( lockKey ){
3611
+
3612
+ // disable fields
3613
+ this.getFields().map(function( field ){
3614
+ field.disable( CONTEXT );
3615
+ });
3616
+ },
3617
+
3618
+ onDuplicate: function( e, $el, $duplicate ){
3619
+ if( this.isActive() ) {
3620
+ $duplicate.prevAll('.acf-tab-wrap:first').remove();
3621
+ }
3622
+ }
3623
+ });
3624
+
3625
+ acf.registerFieldType( Field );
3626
+
3627
+
3628
+ /**
3629
+ * tabs
3630
+ *
3631
+ * description
3632
+ *
3633
+ * @date 8/2/18
3634
+ * @since 5.6.5
3635
+ *
3636
+ * @param type $var Description. Default.
3637
+ * @return type Description.
3638
+ */
3639
+
3640
+ var i = 0;
3641
+ var Tabs = acf.Model.extend({
3642
+
3643
+ tabs: [],
3644
+
3645
+ active: false,
3646
+
3647
+ actions: {
3648
+ 'refresh': 'onRefresh'
3649
+ },
3650
+
3651
+ data: {
3652
+ before: false,
3653
+ placement: 'top',
3654
+ index: 0,
3655
+ initialized: false,
3656
+ },
3657
+
3658
+ setup: function( settings ){
3659
+
3660
+ // data
3661
+ $.extend(this.data, settings);
3662
+
3663
+ // define this prop to avoid scope issues
3664
+ this.tabs = [];
3665
+ this.active = false;
3666
+
3667
+ // vars
3668
+ var placement = this.get('placement');
3669
+ var $before = this.get('before');
3670
+ var $parent = $before.parent();
3671
+
3672
+ // add sidebar for left placement
3673
+ if( placement == 'left' && $parent.hasClass('acf-fields') ) {
3674
+ $parent.addClass('-sidebar');
3675
+ }
3676
+
3677
+ // create wrap
3678
+ if( $before.is('tr') ) {
3679
+ this.$el = $('<tr class="acf-tab-wrap"><td colspan="2"><ul class="acf-hl acf-tab-group"></ul></td></tr>');
3680
+ } else {
3681
+ this.$el = $('<div class="acf-tab-wrap -' + placement + '"><ul class="acf-hl acf-tab-group"></ul></div>');
3682
+ }
3683
+
3684
+ // append
3685
+ $before.before( this.$el );
3686
+
3687
+ // set index
3688
+ this.set('index', i, true);
3689
+ i++;
3690
+ },
3691
+
3692
+ initializeTabs: function(){
3693
+
3694
+ // find first visible tab
3695
+ var tab = this.getVisible().shift();
3696
+
3697
+ // remember previous tab state
3698
+ var order = acf.getPreference('this.tabs') || [];
3699
+ var groupIndex = this.get('index');
3700
+ var tabIndex = order[ groupIndex ];
3701
+
3702
+ if( this.tabs[ tabIndex ] && this.tabs[ tabIndex ].isVisible() ) {
3703
+ tab = this.tabs[ tabIndex ];
3704
+ }
3705
+
3706
+ // select
3707
+ if( tab ) {
3708
+ this.selectTab( tab );
3709
+ } else {
3710
+ this.closeTabs();
3711
+ }
3712
+
3713
+ // set local variable used by tabsManager
3714
+ this.set('initialized', true);
3715
+ },
3716
+
3717
+ getVisible: function(){
3718
+ return this.tabs.filter(function( tab ){
3719
+ return tab.isVisible();
3720
+ });
3721
+ },
3722
+
3723
+ getActive: function(){
3724
+ return this.active;
3725
+ },
3726
+
3727
+ setActive: function( tab ){
3728
+ return this.active = tab;
3729
+ },
3730
+
3731
+ hasActive: function(){
3732
+ return (this.active !== false);
3733
+ },
3734
+
3735
+ isActive: function( tab ){
3736
+ var active = this.getActive();
3737
+ return (active && active.cid === tab.cid);
3738
+ },
3739
+
3740
+ closeActive: function(){
3741
+ if( this.hasActive() ) {
3742
+ this.closeTab( this.getActive() );
3743
+ }
3744
+ },
3745
+
3746
+ openTab: function( tab ){
3747
+
3748
+ // close existing tab
3749
+ this.closeActive();
3750
+
3751
+ // open
3752
+ tab.open();
3753
+
3754
+ // set active
3755
+ this.setActive( tab );
3756
+ },
3757
+
3758
+ closeTab: function( tab ){
3759
+
3760
+ // close
3761
+ tab.close();
3762
+
3763
+ // set active
3764
+ this.setActive( false );
3765
+ },
3766
+
3767
+ closeTabs: function(){
3768
+ this.tabs.map( this.closeTab, this );
3769
+ },
3770
+
3771
+ selectTab: function( tab ){
3772
+
3773
+ // close other tabs
3774
+ this.tabs.map(function( t ){
3775
+ if( tab.cid !== t.cid ) {
3776
+ this.closeTab( t );
3777
+ }
3778
+ }, this);
3779
+
3780
+ // open
3781
+ this.openTab( tab );
3782
+
3783
+ },
3784
+
3785
+ addTab: function( $a, field ){
3786
+
3787
+ // create <li>
3788
+ var $li = $('<li>' + $a.outerHTML() + '</li>');
3789
+
3790
+ // append
3791
+ this.$('ul').append( $li );
3792
+
3793
+ // initialize
3794
+ var tab = new Tab({
3795
+ $el: $li,
3796
+ field: field,
3797
+ group: this,
3798
+ });
3799
+
3800
+ // store
3801
+ this.tabs.push( tab );
3802
+
3803
+ // return
3804
+ return tab;
3805
+ },
3806
+
3807
+ reset: function(){
3808
+
3809
+ // close existing tab
3810
+ this.closeActive();
3811
+
3812
+ // find and active a tab
3813
+ return this.refresh();
3814
+ },
3815
+
3816
+ refresh: function(){
3817
+
3818
+ // bail early if active already exists
3819
+ if( this.hasActive() ) {
3820
+ return false;
3821
+ }
3822
+
3823
+ // find next active tab
3824
+ var tab = this.getVisible().shift();
3825
+
3826
+ // open tab
3827
+ if( tab ) {
3828
+ this.openTab( tab );
3829
+ }
3830
+
3831
+ // return
3832
+ return tab;
3833
+ },
3834
+
3835
+ onRefresh: function(){
3836
+
3837
+ // only for left placements
3838
+ if( this.get('placement') !== 'left' ) {
3839
+ return;
3840
+ }
3841
+
3842
+ // vars
3843
+ var $parent = this.$el.parent();
3844
+ var $list = this.$el.children('ul');
3845
+ var attribute = $parent.is('td') ? 'height' : 'min-height';
3846
+
3847
+ // find height (minus 1 for border-bottom)
3848
+ var height = $list.position().top + $list.outerHeight(true) - 1;
3849
+
3850
+ // add css
3851
+ $parent.css(attribute, height);
3852
+ }
3853
+ });
3854
+
3855
+ var Tab = acf.Model.extend({
3856
+
3857
+ group: false,
3858
+
3859
+ field: false,
3860
+
3861
+ events: {
3862
+ 'click a': 'onClick'
3863
+ },
3864
+
3865
+ index: function(){
3866
+ return this.$el.index();
3867
+ },
3868
+
3869
+ isVisible: function(){
3870
+ return acf.isVisible( this.$el );
3871
+ },
3872
+
3873
+ isActive: function(){
3874
+ return this.$el.hasClass('active');
3875
+ },
3876
+
3877
+ open: function(){
3878
+
3879
+ // add class
3880
+ this.$el.addClass('active');
3881
+
3882
+ // show field
3883
+ this.field.showFields();
3884
+ },
3885
+
3886
+ close: function(){
3887
+
3888
+ // remove class
3889
+ this.$el.removeClass('active');
3890
+
3891
+ // hide field
3892
+ this.field.hideFields();
3893
+ },
3894
+
3895
+ onClick: function( e, $el ){
3896
+
3897
+ // prevent default
3898
+ e.preventDefault();
3899
+
3900
+ // toggle
3901
+ this.toggle();
3902
+ },
3903
+
3904
+ toggle: function(){
3905
+
3906
+ // bail early if already active
3907
+ if( this.isActive() ) {
3908
+ return;
3909
+ }
3910
+
3911
+ // toggle this tab
3912
+ this.group.openTab( this );
3913
+ }
3914
+ });
3915
+
3916
+ var tabsManager = new acf.Model({
3917
+
3918
+ priority: 50,
3919
+
3920
+ actions: {
3921
+ 'prepare': 'render',
3922
+ 'append': 'render',
3923
+ 'unload': 'onUnload',
3924
+ 'invalid_field': 'onInvalidField'
3925
+ },
3926
+
3927
+ findTabs: function(){
3928
+ return $('.acf-tab-wrap');
3929
+ },
3930
+
3931
+ getTabs: function(){
3932
+ return acf.getInstances( this.findTabs() );
3933
+ },
3934
+
3935
+ render: function( $el ){
3936
+ this.getTabs().map(function( tabs ){
3937
+ if( !tabs.get('initialized') ) {
3938
+ tabs.initializeTabs();
3939
+ }
3940
+ });
3941
+ },
3942
+
3943
+ onInvalidField: function( field ){
3944
+
3945
+ // bail early if busy
3946
+ if( this.busy ) {
3947
+ return;
3948
+ }
3949
+
3950
+ // ignore if not hidden by tab
3951
+ if( !field.hiddenByTab ) {
3952
+ return;
3953
+ }
3954
+
3955
+ // toggle tab
3956
+ field.hiddenByTab.toggle();
3957
+
3958
+ // ignore other invalid fields
3959
+ this.busy = true;
3960
+ this.setTimeout(function(){
3961
+ this.busy = false;
3962
+ }, 100);
3963
+ },
3964
+
3965
+ onUnload: function(){
3966
+
3967
+ // vars
3968
+ var order = [];
3969
+
3970
+ // loop
3971
+ this.getTabs().map(function( group ){
3972
+ var active = group.hasActive() ? group.getActive().index() : 0;
3973
+ order.push(active);
3974
+ });
3975
+
3976
+ // bail if no tabs
3977
+ if( !order.length ) {
3978
+ return;
3979
+ }
3980
+
3981
+ // update
3982
+ acf.setPreference('this.tabs', order);
3983
+ }
3984
+ });
3985
+
3986
+ })(jQuery);
3987
+ (function($, undefined){
3988
+
3989
+ var Field = acf.models.SelectField.extend({
3990
+ type: 'post_object',
3991
+ });
3992
+
3993
+ acf.registerFieldType( Field );
3994
+
3995
+ })(jQuery);
3996
+ (function($, undefined){
3997
+
3998
+ var Field = acf.models.SelectField.extend({
3999
+ type: 'page_link',
4000
+ });
4001
+
4002
+ acf.registerFieldType( Field );
4003
+
4004
+ })(jQuery);
4005
+ (function($, undefined){
4006
+
4007
+ var Field = acf.models.SelectField.extend({
4008
+ type: 'user',
4009
+ });
4010
+
4011
+ acf.registerFieldType( Field );
4012
+
4013
+ })(jQuery);
4014
+ (function($, undefined){
4015
+
4016
+ var Field = acf.Field.extend({
4017
+
4018
+ type: 'taxonomy',
4019
+
4020
+ data: {
4021
+ 'ftype': 'select'
4022
+ },
4023
+
4024
+ select2: false,
4025
+
4026
+ wait: 'load',
4027
+
4028
+ events: {
4029
+ 'click a[data-name="add"]': 'onClickAdd',
4030
+ 'click input[type="radio"]': 'onClickRadio',
4031
+ 'removeField': 'onRemove'
4032
+ },
4033
+
4034
+ $control: function(){
4035
+ return this.$('.acf-taxonomy-field');
4036
+ },
4037
+
4038
+ $input: function(){
4039
+ return this.getRelatedPrototype().$input.apply(this, arguments);
4040
+ },
4041
+
4042
+ getRelatedType: function(){
4043
+
4044
+ // vars
4045
+ var fieldType = this.get('ftype');
4046
+
4047
+ // normalize
4048
+ if( fieldType == 'multi_select' ) {
4049
+ fieldType = 'select';
4050
+ }
4051
+
4052
+ // return
4053
+ return fieldType;
4054
+
4055
+ },
4056
+
4057
+ getRelatedPrototype: function(){
4058
+ return acf.getFieldType( this.getRelatedType() ).prototype;
4059
+ },
4060
+
4061
+ getValue: function(){
4062
+ return this.getRelatedPrototype().getValue.apply(this, arguments);
4063
+ },
4064
+
4065
+ setValue: function(){
4066
+ return this.getRelatedPrototype().setValue.apply(this, arguments);
4067
+ },
4068
+
4069
+ initialize: function(){
4070
+ this.getRelatedPrototype().initialize.apply(this, arguments);
4071
+ },
4072
+
4073
+ onRemove: function(){
4074
+ var proto = this.getRelatedPrototype();
4075
+ if( proto.onRemove ) {
4076
+ proto.onRemove.apply(this, arguments);
4077
+ }
4078
+ },
4079
+
4080
+ onClickAdd: function( e, $el ){
4081
+
4082
+ // vars
4083
+ var field = this;
4084
+ var popup = false;
4085
+ var $form = false;
4086
+ var $name = false;
4087
+ var $parent = false;
4088
+ var $button = false;
4089
+ var $message = false;
4090
+ var notice = false;
4091
+
4092
+ // step 1.
4093
+ var step1 = function(){
4094
+
4095
+ // popup
4096
+ popup = acf.newPopup({
4097
+ title: $el.attr('title'),
4098
+ loading: true,
4099
+ width: '300px'
4100
+ });
4101
+
4102
+ // ajax
4103
+ var ajaxData = {
4104
+ action: 'acf/fields/taxonomy/add_term',
4105
+ field_key: field.get('key')
4106
+ };
4107
+
4108
+ // get HTML
4109
+ $.ajax({
4110
+ url: acf.get('ajaxurl'),
4111
+ data: acf.prepareForAjax(ajaxData),
4112
+ type: 'post',
4113
+ dataType: 'html',
4114
+ success: step2
4115
+ });
4116
+ };
4117
+
4118
+ // step 2.
4119
+ var step2 = function( html ){
4120
+
4121
+ // update popup
4122
+ popup.loading(false);
4123
+ popup.content(html);
4124
+
4125
+ // vars
4126
+ $form = popup.$('form');
4127
+ $name = popup.$('input[name="term_name"]');
4128
+ $parent = popup.$('select[name="term_parent"]');
4129
+ $button = popup.$('.acf-submit-button');
4130
+
4131
+ // focus
4132
+ $name.trigger('focus');
4133
+
4134
+ // submit form
4135
+ popup.on('submit', 'form', step3);
4136
+ };
4137
+
4138
+ // step 3.
4139
+ var step3 = function( e, $el ){
4140
+
4141
+ // prevent
4142
+ e.preventDefault();
4143
+ e.stopImmediatePropagation();
4144
+
4145
+ // basic validation
4146
+ if( $name.val() === '' ) {
4147
+ $name.trigger('focus');
4148
+ return false;
4149
+ }
4150
+
4151
+ // disable
4152
+ acf.startButtonLoading( $button );
4153
+
4154
+ // ajax
4155
+ var ajaxData = {
4156
+ action: 'acf/fields/taxonomy/add_term',
4157
+ field_key: field.get('key'),
4158
+ term_name: $name.val(),
4159
+ term_parent: $parent.length ? $parent.val() : 0
4160
+ };
4161
+
4162
+ $.ajax({
4163
+ url: acf.get('ajaxurl'),
4164
+ data: acf.prepareForAjax(ajaxData),
4165
+ type: 'post',
4166
+ dataType: 'json',
4167
+ success: step4
4168
+ });
4169
+ };
4170
+
4171
+ // step 4.
4172
+ var step4 = function( json ){
4173
+
4174
+ // enable
4175
+ acf.stopButtonLoading( $button );
4176
+
4177
+ // remove prev notice
4178
+ if( notice ) {
4179
+ notice.remove();
4180
+ }
4181
+
4182
+ // success
4183
+ if( acf.isAjaxSuccess(json) ) {
4184
+
4185
+ // clear name
4186
+ $name.val('');
4187
+
4188
+ // update term lists
4189
+ step5( json.data );
4190
+
4191
+ // notice
4192
+ notice = acf.newNotice({
4193
+ type: 'success',
4194
+ text: acf.getAjaxMessage(json),
4195
+ target: $form,
4196
+ timeout: 2000,
4197
+ dismiss: false
4198
+ });
4199
+
4200
+ } else {
4201
+
4202
+ // notice
4203
+ notice = acf.newNotice({
4204
+ type: 'error',
4205
+ text: acf.getAjaxError(json),
4206
+ target: $form,
4207
+ timeout: 2000,
4208
+ dismiss: false
4209
+ });
4210
+ }
4211
+
4212
+ // focus
4213
+ $name.trigger('focus');
4214
+ };
4215
+
4216
+ // step 5.
4217
+ var step5 = function( term ){
4218
+
4219
+ // update parent dropdown
4220
+ var $option = $('<option value="' + term.term_id + '">' + term.term_label + '</option>');
4221
+ if( term.term_parent ) {
4222
+ $parent.children('option[value="' + term.term_parent + '"]').after( $option );
4223
+ } else {
4224
+ $parent.append( $option );
4225
+ }
4226
+
4227
+ // add this new term to all taxonomy field
4228
+ var fields = acf.getFields({
4229
+ type: 'taxonomy'
4230
+ });
4231
+
4232
+ fields.map(function( otherField ){
4233
+ if( otherField.get('taxonomy') == field.get('taxonomy') ) {
4234
+ otherField.appendTerm( term );
4235
+ }
4236
+ });
4237
+
4238
+ // select
4239
+ field.selectTerm( term.term_id );
4240
+ };
4241
+
4242
+ // run
4243
+ step1();
4244
+ },
4245
+
4246
+ appendTerm: function( term ){
4247
+
4248
+ if( this.getRelatedType() == 'select' ) {
4249
+ this.appendTermSelect( term );
4250
+ } else {
4251
+ this.appendTermCheckbox( term );
4252
+ }
4253
+ },
4254
+
4255
+ appendTermSelect: function( term ){
4256
+
4257
+ this.select2.addOption({
4258
+ id: term.term_id,
4259
+ text: term.term_label
4260
+ });
4261
+
4262
+ },
4263
+
4264
+ appendTermCheckbox: function( term ){
4265
+
4266
+ // vars
4267
+ var name = this.$('[name]:first').attr('name');
4268
+ var $ul = this.$('ul:first');
4269
+
4270
+ // allow multiple selection
4271
+ if( this.getRelatedType() == 'checkbox' ) {
4272
+ name += '[]';
4273
+ }
4274
+
4275
+ // create new li
4276
+ var $li = $([
4277
+ '<li data-id="' + term.term_id + '">',
4278
+ '<label>',
4279
+ '<input type="' + this.get('ftype') + '" value="' + term.term_id + '" name="' + name + '" /> ',
4280
+ '<span>' + term.term_name + '</span>',
4281
+ '</label>',
4282
+ '</li>'
4283
+ ].join(''));
4284
+
4285
+ // find parent
4286
+ if( term.term_parent ) {
4287
+
4288
+ // vars
4289
+ var $parent = $ul.find('li[data-id="' + term.term_parent + '"]');
4290
+
4291
+ // update vars
4292
+ $ul = $parent.children('ul');
4293
+
4294
+ // create ul
4295
+ if( !$ul.exists() ) {
4296
+ $ul = $('<ul class="children acf-bl"></ul>');
4297
+ $parent.append( $ul );
4298
+ }
4299
+ }
4300
+
4301
+ // append
4302
+ $ul.append( $li );
4303
+ },
4304
+
4305
+ selectTerm: function( id ){
4306
+ if( this.getRelatedType() == 'select' ) {
4307
+ this.select2.selectOption( id );
4308
+ } else {
4309
+ var $input = this.$('input[value="' + id + '"]');
4310
+ $input.prop('checked', true).trigger('change');
4311
+ }
4312
+ },
4313
+
4314
+ onClickRadio: function( e, $el ){
4315
+
4316
+ // vars
4317
+ var $label = $el.parent('label');
4318
+ var selected = $label.hasClass('selected');
4319
+
4320
+ // remove previous selected
4321
+ this.$('.selected').removeClass('selected');
4322
+
4323
+ // add active class
4324
+ $label.addClass('selected');
4325
+
4326
+ // allow null
4327
+ if( this.get('allow_null') && selected ) {
4328
+ $label.removeClass('selected');
4329
+ $el.prop('checked', false).trigger('change');
4330
+ }
4331
+ }
4332
+ });
4333
+
4334
+ acf.registerFieldType( Field );
4335
+
4336
+ })(jQuery);
4337
+ (function($, undefined){
4338
+
4339
+ var Field = acf.models.DatePickerField.extend({
4340
+
4341
+ type: 'time_picker',
4342
+
4343
+ $control: function(){
4344
+ return this.$('.acf-time-picker');
4345
+ },
4346
+
4347
+ initialize: function(){
4348
+
4349
+ // vars
4350
+ var $input = this.$input();
4351
+ var $inputText = this.$inputText();
4352
+
4353
+ // args
4354
+ var args = {
4355
+ timeFormat: this.get('time_format'),
4356
+ altField: $input,
4357
+ altFieldTimeOnly: false,
4358
+ altTimeFormat: 'HH:mm:ss',
4359
+ showButtonPanel: true,
4360
+ controlType: 'select',
4361
+ oneLine: true,
4362
+ closeText: acf.get('dateTimePickerL10n').selectText,
4363
+ timeOnly: true,
4364
+ };
4365
+
4366
+ // add custom 'Close = Select' functionality
4367
+ args.onClose = function( value, dp_instance, t_instance ){
4368
+
4369
+ // vars
4370
+ var $close = dp_instance.dpDiv.find('.ui-datepicker-close');
4371
+
4372
+ // if clicking close button
4373
+ if( !value && $close.is(':hover') ) {
4374
+ t_instance._updateDateTime();
4375
+ }
4376
+ };
4377
+
4378
+
4379
+ // filter
4380
+ args = acf.applyFilters('time_picker_args', args, this);
4381
+
4382
+ // add date time picker
4383
+ acf.newTimePicker( $inputText, args );
4384
+
4385
+ // action
4386
+ acf.doAction('time_picker_init', $inputText, args, this);
4387
+ }
4388
+ });
4389
+
4390
+ acf.registerFieldType( Field );
4391
+
4392
+
4393
+ // add
4394
+ acf.newTimePicker = function( $input, args ){
4395
+
4396
+ // bail ealry if no datepicker library
4397
+ if( typeof $.timepicker === 'undefined' ) {
4398
+ return false;
4399
+ }
4400
+
4401
+ // defaults
4402
+ args = args || {};
4403
+
4404
+ // initialize
4405
+ $input.timepicker( args );
4406
+
4407
+ // wrap the datepicker (only if it hasn't already been wrapped)
4408
+ if( $('body > #ui-datepicker-div').exists() ) {
4409
+ $('body > #ui-datepicker-div').wrap('<div class="acf-ui-datepicker" />');
4410
+ }
4411
+ };
4412
+
4413
+ })(jQuery);
4414
+ (function($, undefined){
4415
+
4416
+ var Field = acf.Field.extend({
4417
+
4418
+ type: 'true_false',
4419
+
4420
+ events: {
4421
+ 'change .acf-switch-input': 'onChange',
4422
+ 'focus .acf-switch-input': 'onFocus',
4423
+ 'blur .acf-switch-input': 'onBlur',
4424
+ 'keypress .acf-switch-input': 'onKeypress'
4425
+ },
4426
+
4427
+ $input: function(){
4428
+ return this.$('input[type="checkbox"]');
4429
+ },
4430
+
4431
+ $switch: function(){
4432
+ return this.$('.acf-switch');
4433
+ },
4434
+
4435
+ getValue: function(){
4436
+ return this.$input().prop('checked') ? 1 : 0;
4437
+ },
4438
+
4439
+ initialize: function(){
4440
+ this.render();
4441
+ },
4442
+
4443
+ render: function(){
4444
+
4445
+ // vars
4446
+ var $switch = this.$switch();
4447
+
4448
+ // bail ealry if no $switch
4449
+ if( !$switch.length ) return;
4450
+
4451
+ // vars
4452
+ var $on = $switch.children('.acf-switch-on');
4453
+ var $off = $switch.children('.acf-switch-off');
4454
+ var width = Math.max( $on.width(), $off.width() );
4455
+
4456
+ // bail ealry if no width
4457
+ if( !width ) return;
4458
+
4459
+ // set widths
4460
+ $on.css( 'min-width', width );
4461
+ $off.css( 'min-width', width );
4462
+
4463
+ },
4464
+
4465
+ switchOn: function() {
4466
+ this.$input().prop('checked', true);
4467
+ this.$switch().addClass('-on');
4468
+ },
4469
+
4470
+ switchOff: function() {
4471
+ this.$input().prop('checked', false);
4472
+ this.$switch().removeClass('-on');
4473
+ },
4474
+
4475
+ onChange: function( e, $el ){
4476
+ if( $el.prop('checked') ) {
4477
+ this.switchOn();
4478
+ } else {
4479
+ this.switchOff();
4480
+ }
4481
+ },
4482
+
4483
+ onFocus: function( e, $el ){
4484
+ this.$switch().addClass('-focus');
4485
+ },
4486
+
4487
+ onBlur: function( e, $el ){
4488
+ this.$switch().removeClass('-focus');
4489
+ },
4490
+
4491
+ onKeypress: function( e, $el ){
4492
+
4493
+ // left
4494
+ if( e.keyCode === 37 ) {
4495
+ return this.switchOff();
4496
+ }
4497
+
4498
+ // right
4499
+ if( e.keyCode === 39 ) {
4500
+ return this.switchOn();
4501
+ }
4502
+
4503
+ }
4504
+ });
4505
+
4506
+ acf.registerFieldType( Field );
4507
+
4508
+ })(jQuery);
4509
+ (function($, undefined){
4510
+
4511
+ var Field = acf.Field.extend({
4512
+
4513
+ type: 'url',
4514
+
4515
+ events: {
4516
+ 'keyup input[type="url"]': 'onkeyup'
4517
+ },
4518
+
4519
+ $control: function(){
4520
+ return this.$('.acf-input-wrap');
4521
+ },
4522
+
4523
+ $input: function(){
4524
+ return this.$('input[type="url"]');
4525
+ },
4526
+
4527
+ initialize: function(){
4528
+ this.render();
4529
+ },
4530
+
4531
+ isValid: function(){
4532
+
4533
+ // vars
4534
+ var val = this.val();
4535
+
4536
+ // bail early if no val
4537
+ if( !val ) {
4538
+ return false;
4539
+ }
4540
+
4541
+ // url
4542
+ if( val.indexOf('://') !== -1 ) {
4543
+ return true;
4544
+ }
4545
+
4546
+ // protocol relative url
4547
+ if( val.indexOf('//') === 0 ) {
4548
+ return true;
4549
+ }
4550
+
4551
+ // return
4552
+ return false;
4553
+ },
4554
+
4555
+ render: function(){
4556
+
4557
+ // add class
4558
+ if( this.isValid() ) {
4559
+ this.$control().addClass('-valid');
4560
+ } else {
4561
+ this.$control().removeClass('-valid');
4562
+ }
4563
+ },
4564
+
4565
+ onkeyup: function( e, $el ){
4566
+ this.render();
4567
+ }
4568
+ });
4569
+
4570
+ acf.registerFieldType( Field );
4571
+
4572
+ })(jQuery);
4573
+ (function($, undefined){
4574
+
4575
+ var Field = acf.Field.extend({
4576
+
4577
+ type: 'wysiwyg',
4578
+
4579
+ wait: 'load',
4580
+
4581
+ events: {
4582
+ 'mousedown .acf-editor-wrap.delay': 'onMousedown',
4583
+ 'unmountField': 'disableEditor',
4584
+ 'remountField': 'enableEditor',
4585
+ 'removeField': 'disableEditor'
4586
+ },
4587
+
4588
+ $control: function(){
4589
+ return this.$('.acf-editor-wrap');
4590
+ },
4591
+
4592
+ $input: function(){
4593
+ return this.$('textarea');
4594
+ },
4595
+
4596
+ getMode: function(){
4597
+ return this.$control().hasClass('tmce-active') ? 'visual' : 'text';
4598
+ },
4599
+
4600
+ initialize: function(){
4601
+
4602
+ // initializeEditor if no delay
4603
+ if( !this.$control().hasClass('delay') ) {
4604
+ this.initializeEditor();
4605
+ }
4606
+ },
4607
+
4608
+ initializeEditor: function(){
4609
+
4610
+ // vars
4611
+ var $wrap = this.$control();
4612
+ var $textarea = this.$input();
4613
+ var args = {
4614
+ tinymce: true,
4615
+ quicktags: true,
4616
+ toolbar: this.get('toolbar'),
4617
+ mode: this.getMode(),
4618
+ field: this
4619
+ };
4620
+
4621
+ // generate new id
4622
+ var oldId = $textarea.attr('id');
4623
+ var newId = acf.uniqueId('acf-editor-');
4624
+
4625
+ // Backup textarea data.
4626
+ var inputData = $textarea.data();
4627
+ var inputVal = $textarea.val();
4628
+
4629
+ // rename
4630
+ acf.rename({
4631
+ target: $wrap,
4632
+ search: oldId,
4633
+ replace: newId,
4634
+ destructive: true
4635
+ });
4636
+
4637
+ // update id
4638
+ this.set('id', newId, true);
4639
+
4640
+ // apply data to new textarea (acf.rename creates a new textarea element due to destructive mode)
4641
+ // fixes bug where conditional logic "disabled" is lost during "screen_check"
4642
+ this.$input().data( inputData ).val( inputVal );
4643
+
4644
+ // initialize
4645
+ acf.tinymce.initialize( newId, args );
4646
+ },
4647
+
4648
+ onMousedown: function( e ){
4649
+
4650
+ // prevent default
4651
+ e.preventDefault();
4652
+
4653
+ // remove delay class
4654
+ var $wrap = this.$control();
4655
+ $wrap.removeClass('delay');
4656
+ $wrap.find('.acf-editor-toolbar').remove();
4657
+
4658
+ // initialize
4659
+ this.initializeEditor();
4660
+ },
4661
+
4662
+ enableEditor: function(){
4663
+ if( this.getMode() == 'visual' ) {
4664
+ acf.tinymce.enable( this.get('id') );
4665
+ }
4666
+ },
4667
+
4668
+ disableEditor: function(){
4669
+ acf.tinymce.destroy( this.get('id') );
4670
+ }
4671
+ });
4672
+
4673
+ acf.registerFieldType( Field );
4674
+
4675
+ })(jQuery);
4676
+ (function($, undefined){
4677
+
4678
+ // vars
4679
+ var storage = [];
4680
+
4681
+ /**
4682
+ * acf.Condition
4683
+ *
4684
+ * description
4685
+ *
4686
+ * @date 23/3/18
4687
+ * @since 5.6.9
4688
+ *
4689
+ * @param type $var Description. Default.
4690
+ * @return type Description.
4691
+ */
4692
+
4693
+ acf.Condition = acf.Model.extend({
4694
+
4695
+ type: '', // used for model name
4696
+ operator: '==', // rule operator
4697
+ label: '', // label shown when editing fields
4698
+ choiceType: 'input', // input, select
4699
+ fieldTypes: [], // auto connect this conditions with these field types
4700
+
4701
+ data: {
4702
+ conditions: false, // the parent instance
4703
+ field: false, // the field which we query against
4704
+ rule: {} // the rule [field, operator, value]
4705
+ },
4706
+
4707
+ events: {
4708
+ 'change': 'change',
4709
+ 'keyup': 'change',
4710
+ 'enableField': 'change',
4711
+ 'disableField': 'change'
4712
+ },
4713
+
4714
+ setup: function( props ){
4715
+ $.extend(this.data, props);
4716
+ },
4717
+
4718
+ getEventTarget: function( $el, event ){
4719
+ return $el || this.get('field').$el;
4720
+ },
4721
+
4722
+ change: function( e, $el ){
4723
+ this.get('conditions').change( e );
4724
+ },
4725
+
4726
+ match: function( rule, field ){
4727
+ return false;
4728
+ },
4729
+
4730
+ calculate: function(){
4731
+ return this.match( this.get('rule'), this.get('field') );
4732
+ },
4733
+
4734
+ choices: function( field ){
4735
+ return '<input type="text" />';
4736
+ }
4737
+ });
4738
+
4739
+ /**
4740
+ * acf.newCondition
4741
+ *
4742
+ * description
4743
+ *
4744
+ * @date 1/2/18
4745
+ * @since 5.6.5
4746
+ *
4747
+ * @param type $var Description. Default.
4748
+ * @return type Description.
4749
+ */
4750
+
4751
+ acf.newCondition = function( rule, conditions ){
4752
+
4753
+ // currently setting up conditions for fieldX, this field is the 'target'
4754
+ var target = conditions.get('field');
4755
+
4756
+ // use the 'target' to find the 'trigger' field.
4757
+ // - this field is used to setup the conditional logic events
4758
+ var field = target.getField( rule.field );
4759
+
4760
+ // bail ealry if no target or no field (possible if field doesn't exist due to HTML error)
4761
+ if( !target || !field ) {
4762
+ return false;
4763
+ }
4764
+
4765
+ // vars
4766
+ var args = {
4767
+ rule: rule,
4768
+ target: target,
4769
+ conditions: conditions,
4770
+ field: field
4771
+ };
4772
+
4773
+ // vars
4774
+ var fieldType = field.get('type');
4775
+ var operator = rule.operator;
4776
+
4777
+ // get avaibale conditions
4778
+ var conditionTypes = acf.getConditionTypes({
4779
+ fieldType: fieldType,
4780
+ operator: operator,
4781
+ });
4782
+
4783
+ // instantiate
4784
+ var model = conditionTypes[0] || acf.Condition;
4785
+
4786
+ // instantiate
4787
+ var condition = new model( args );
4788
+
4789
+ // return
4790
+ return condition;
4791
+ };
4792
+
4793
+ /**
4794
+ * mid
4795
+ *
4796
+ * Calculates the model ID for a field type
4797
+ *
4798
+ * @date 15/12/17
4799
+ * @since 5.6.5
4800
+ *
4801
+ * @param string type
4802
+ * @return string
4803
+ */
4804
+
4805
+ var modelId = function( type ) {
4806
+ return acf.strPascalCase( type || '' ) + 'Condition';
4807
+ };
4808
+
4809
+ /**
4810
+ * acf.registerConditionType
4811
+ *
4812
+ * description
4813
+ *
4814
+ * @date 1/2/18
4815
+ * @since 5.6.5
4816
+ *
4817
+ * @param type $var Description. Default.
4818
+ * @return type Description.
4819
+ */
4820
+
4821
+ acf.registerConditionType = function( model ){
4822
+
4823
+ // vars
4824
+ var proto = model.prototype;
4825
+ var type = proto.type;
4826
+ var mid = modelId( type );
4827
+
4828
+ // store model
4829
+ acf.models[ mid ] = model;
4830
+
4831
+ // store reference
4832
+ storage.push( type );
4833
+ };
4834
+
4835
+ /**
4836
+ * acf.getConditionType
4837
+ *
4838
+ * description
4839
+ *
4840
+ * @date 1/2/18
4841
+ * @since 5.6.5
4842
+ *
4843
+ * @param type $var Description. Default.
4844
+ * @return type Description.
4845
+ */
4846
+
4847
+ acf.getConditionType = function( type ){
4848
+ var mid = modelId( type );
4849
+ return acf.models[ mid ] || false;
4850
+ }
4851
+
4852
+ /**
4853
+ * acf.registerConditionForFieldType
4854
+ *
4855
+ * description
4856
+ *
4857
+ * @date 1/2/18
4858
+ * @since 5.6.5
4859
+ *
4860
+ * @param type $var Description. Default.
4861
+ * @return type Description.
4862
+ */
4863
+
4864
+ acf.registerConditionForFieldType = function( conditionType, fieldType ){
4865
+
4866
+ // get model
4867
+ var model = acf.getConditionType( conditionType );
4868
+
4869
+ // append
4870
+ if( model ) {
4871
+ model.prototype.fieldTypes.push( fieldType );
4872
+ }
4873
+ };
4874
+
4875
+ /**
4876
+ * acf.getConditionTypes
4877
+ *
4878
+ * description
4879
+ *
4880
+ * @date 1/2/18
4881
+ * @since 5.6.5
4882
+ *
4883
+ * @param type $var Description. Default.
4884
+ * @return type Description.
4885
+ */
4886
+
4887
+ acf.getConditionTypes = function( args ){
4888
+
4889
+ // defaults
4890
+ args = acf.parseArgs(args, {
4891
+ fieldType: '',
4892
+ operator: ''
4893
+ });
4894
+
4895
+ // clonse available types
4896
+ var types = [];
4897
+
4898
+ // loop
4899
+ storage.map(function( type ){
4900
+
4901
+ // vars
4902
+ var model = acf.getConditionType(type);
4903
+ var ProtoFieldTypes = model.prototype.fieldTypes;
4904
+ var ProtoOperator = model.prototype.operator;
4905
+
4906
+ // check fieldType
4907
+ if( args.fieldType && ProtoFieldTypes.indexOf( args.fieldType ) === -1 ) {
4908
+ return;
4909
+ }
4910
+
4911
+ // check operator
4912
+ if( args.operator && ProtoOperator !== args.operator ) {
4913
+ return;
4914
+ }
4915
+
4916
+ // append
4917
+ types.push( model );
4918
+ });
4919
+
4920
+ // return
4921
+ return types;
4922
+ };
4923
+
4924
+ })(jQuery);
4925
+ (function($, undefined){
4926
+
4927
+ // vars
4928
+ var CONTEXT = 'conditional_logic';
4929
+
4930
+ /**
4931
+ * conditionsManager
4932
+ *
4933
+ * description
4934
+ *
4935
+ * @date 1/2/18
4936
+ * @since 5.6.5
4937
+ *
4938
+ * @param type $var Description. Default.
4939
+ * @return type Description.
4940
+ */
4941
+
4942
+ var conditionsManager = new acf.Model({
4943
+
4944
+ id: 'conditionsManager',
4945
+
4946
+ priority: 20, // run actions later
4947
+
4948
+ actions: {
4949
+ 'new_field': 'onNewField',
4950
+ },
4951
+
4952
+ onNewField: function( field ){
4953
+ if( field.has('conditions') ) {
4954
+ field.getConditions().render();
4955
+ }
4956
+ },
4957
+ });
4958
+
4959
+ /**
4960
+ * acf.Field.prototype.getField
4961
+ *
4962
+ * Finds a field that is related to another field
4963
+ *
4964
+ * @date 1/2/18
4965
+ * @since 5.6.5
4966
+ *
4967
+ * @param type $var Description. Default.
4968
+ * @return type Description.
4969
+ */
4970
+
4971
+ var getSiblingField = function( field, key ){
4972
+
4973
+ // find sibling (very fast)
4974
+ var fields = acf.getFields({
4975
+ key: key,
4976
+ sibling: field.$el,
4977
+ suppressFilters: true,
4978
+ });
4979
+
4980
+ // find sibling-children (fast)
4981
+ // needed for group fields, accordions, etc
4982
+ if( !fields.length ) {
4983
+ fields = acf.getFields({
4984
+ key: key,
4985
+ parent: field.$el.parent(),
4986
+ suppressFilters: true,
4987
+ });
4988
+ }
4989
+
4990
+ // return
4991
+ if( fields.length ) {
4992
+ return fields[0];
4993
+ }
4994
+ return false;
4995
+ };
4996
+
4997
+ acf.Field.prototype.getField = function( key ){
4998
+
4999
+ // get sibling field
5000
+ var field = getSiblingField( this, key );
5001
+
5002
+ // return early
5003
+ if( field ) {
5004
+ return field;
5005
+ }
5006
+
5007
+ // move up through each parent and try again
5008
+ var parents = this.parents();
5009
+ for( var i = 0; i < parents.length; i++ ) {
5010
+
5011
+ // get sibling field
5012
+ field = getSiblingField( parents[i], key );
5013
+
5014
+ // return early
5015
+ if( field ) {
5016
+ return field;
5017
+ }
5018
+ }
5019
+
5020
+ // return
5021
+ return false;
5022
+ };
5023
+
5024
+
5025
+ /**
5026
+ * acf.Field.prototype.getConditions
5027
+ *
5028
+ * Returns the field's conditions instance
5029
+ *
5030
+ * @date 1/2/18
5031
+ * @since 5.6.5
5032
+ *
5033
+ * @param type $var Description. Default.
5034
+ * @return type Description.
5035
+ */
5036
+
5037
+ acf.Field.prototype.getConditions = function(){
5038
+
5039
+ // instantiate
5040
+ if( !this.conditions ) {
5041
+ this.conditions = new Conditions( this );
5042
+ }
5043
+
5044
+ // return
5045
+ return this.conditions;
5046
+ };
5047
+
5048
+
5049
+ /**
5050
+ * Conditions
5051
+ *
5052
+ * description
5053
+ *
5054
+ * @date 1/2/18
5055
+ * @since 5.6.5
5056
+ *
5057
+ * @param type $var Description. Default.
5058
+ * @return type Description.
5059
+ */
5060
+ var timeout = false;
5061
+ var Conditions = acf.Model.extend({
5062
+
5063
+ id: 'Conditions',
5064
+
5065
+ data: {
5066
+ field: false, // The field with "data-conditions" (target).
5067
+ timeStamp: false, // Reference used during "change" event.
5068
+ groups: [], // The groups of condition instances.
5069
+ },
5070
+
5071
+ setup: function( field ){
5072
+
5073
+ // data
5074
+ this.data.field = field;
5075
+
5076
+ // vars
5077
+ var conditions = field.get('conditions');
5078
+
5079
+ // detect groups
5080
+ if( conditions instanceof Array ) {
5081
+
5082
+ // detect groups
5083
+ if( conditions[0] instanceof Array ) {
5084
+
5085
+ // loop
5086
+ conditions.map(function(rules, i){
5087
+ this.addRules( rules, i );
5088
+ }, this);
5089
+
5090
+ // detect rules
5091
+ } else {
5092
+ this.addRules( conditions );
5093
+ }
5094
+
5095
+ // detect rule
5096
+ } else {
5097
+ this.addRule( conditions );
5098
+ }
5099
+ },
5100
+
5101
+ change: function( e ){
5102
+
5103
+ // this function may be triggered multiple times per event due to multiple condition classes
5104
+ // compare timestamp to allow only 1 trigger per event
5105
+ if( this.get('timeStamp') === e.timeStamp ) {
5106
+ return false;
5107
+ } else {
5108
+ this.set('timeStamp', e.timeStamp, true);
5109
+ }
5110
+
5111
+ // render condition and store result
5112
+ var changed = this.render();
5113
+ },
5114
+
5115
+ render: function(){
5116
+ return this.calculate() ? this.show() : this.hide();
5117
+ },
5118
+
5119
+ show: function(){
5120
+ return this.get('field').showEnable(this.cid, CONTEXT);
5121
+ },
5122
+
5123
+ hide: function(){
5124
+ return this.get('field').hideDisable(this.cid, CONTEXT);
5125
+ },
5126
+
5127
+ calculate: function(){
5128
+
5129
+ // vars
5130
+ var pass = false;
5131
+
5132
+ // loop
5133
+ this.getGroups().map(function( group ){
5134
+
5135
+ // igrnore this group if another group passed
5136
+ if( pass ) return;
5137
+
5138
+ // find passed
5139
+ var passed = group.filter(function(condition){
5140
+ return condition.calculate();
5141
+ });
5142
+
5143
+ // if all conditions passed, update the global var
5144
+ if( passed.length == group.length ) {
5145
+ pass = true;
5146
+ }
5147
+ });
5148
+
5149
+ return pass;
5150
+ },
5151
+
5152
+ hasGroups: function(){
5153
+ return this.data.groups != null;
5154
+ },
5155
+
5156
+ getGroups: function(){
5157
+ return this.data.groups;
5158
+ },
5159
+
5160
+ addGroup: function(){
5161
+ var group = [];
5162
+ this.data.groups.push( group );
5163
+ return group;
5164
+ },
5165
+
5166
+ hasGroup: function( i ){
5167
+ return this.data.groups[i] != null;
5168
+ },
5169
+
5170
+ getGroup: function( i ){
5171
+ return this.data.groups[i];
5172
+ },
5173
+
5174
+ removeGroup: function( i ){
5175
+ this.data.groups[i].delete;
5176
+ return this;
5177
+ },
5178
+
5179
+ addRules: function( rules, group ){
5180
+ rules.map(function( rule ){
5181
+ this.addRule( rule, group );
5182
+ }, this);
5183
+ },
5184
+
5185
+ addRule: function( rule, group ){
5186
+
5187
+ // defaults
5188
+ group = group || 0;
5189
+
5190
+ // vars
5191
+ var groupArray;
5192
+
5193
+ // get group
5194
+ if( this.hasGroup(group) ) {
5195
+ groupArray = this.getGroup(group);
5196
+ } else {
5197
+ groupArray = this.addGroup();
5198
+ }
5199
+
5200
+ // instantiate
5201
+ var condition = acf.newCondition( rule, this );
5202
+
5203
+ // bail ealry if condition failed (field did not exist)
5204
+ if( !condition ) {
5205
+ return false;
5206
+ }
5207
+
5208
+ // add rule
5209
+ groupArray.push(condition);
5210
+ },
5211
+
5212
+ hasRule: function(){
5213
+
5214
+ },
5215
+
5216
+ getRule: function( rule, group ){
5217
+
5218
+ // defaults
5219
+ rule = rule || 0;
5220
+ group = group || 0;
5221
+
5222
+ return this.data.groups[ group ][ rule ];
5223
+ },
5224
+
5225
+ removeRule: function(){
5226
+
5227
+ }
5228
+ });
5229
+
5230
+ })(jQuery);
5231
+ (function($, undefined){
5232
+
5233
+ var __ = acf.__;
5234
+
5235
+ var parseString = function( val ){
5236
+ return val ? '' + val : '';
5237
+ };
5238
+
5239
+ var isEqualTo = function( v1, v2 ){
5240
+ return ( parseString(v1).toLowerCase() === parseString(v2).toLowerCase() );
5241
+ };
5242
+
5243
+ var isEqualToNumber = function( v1, v2 ){
5244
+ return ( parseFloat(v1) === parseFloat(v2) );
5245
+ };
5246
+
5247
+ var isGreaterThan = function( v1, v2 ){
5248
+ return ( parseFloat(v1) > parseFloat(v2) );
5249
+ };
5250
+
5251
+ var isLessThan = function( v1, v2 ){
5252
+ return ( parseFloat(v1) < parseFloat(v2) );
5253
+ };
5254
+
5255
+ var inArray = function( v1, array ){
5256
+
5257
+ // cast all values as string
5258
+ array = array.map(function(v2){
5259
+ return parseString(v2);
5260
+ });
5261
+
5262
+ return (array.indexOf( v1 ) > -1);
5263
+ }
5264
+
5265
+ var containsString = function( haystack, needle ){
5266
+ return ( parseString(haystack).indexOf( parseString(needle) ) > -1 );
5267
+ };
5268
+
5269
+ var matchesPattern = function( v1, pattern ){
5270
+ var regexp = new RegExp(parseString(pattern), 'gi');
5271
+ return parseString(v1).match( regexp );
5272
+ };
5273
+
5274
+ /**
5275
+ * hasValue
5276
+ *
5277
+ * description
5278
+ *
5279
+ * @date 1/2/18
5280
+ * @since 5.6.5
5281
+ *
5282
+ * @param void
5283
+ * @return void
5284
+ */
5285
+
5286
+ var HasValue = acf.Condition.extend({
5287
+ type: 'hasValue',
5288
+ operator: '!=empty',
5289
+ label: __('Has any value'),
5290
+ fieldTypes: [ 'text', 'textarea', 'number', 'range', 'email', 'url', 'password', 'image', 'file', 'wysiwyg', 'oembed', 'select', 'checkbox', 'radio', 'button_group', 'link', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user', 'google_map', 'date_picker', 'date_time_picker', 'time_picker', 'color_picker' ],
5291
+ match: function( rule, field ){
5292
+ return (field.val() ? true : false);
5293
+ },
5294
+ choices: function( fieldObject ){
5295
+ return '<input type="text" disabled="" />';
5296
+ }
5297
+ });
5298
+
5299
+ acf.registerConditionType( HasValue );
5300
+
5301
+ /**
5302
+ * hasValue
5303
+ *
5304
+ * description
5305
+ *
5306
+ * @date 1/2/18
5307
+ * @since 5.6.5
5308
+ *
5309
+ * @param void
5310
+ * @return void
5311
+ */
5312
+
5313
+ var HasNoValue = HasValue.extend({
5314
+ type: 'hasNoValue',
5315
+ operator: '==empty',
5316
+ label: __('Has no value'),
5317
+ match: function( rule, field ){
5318
+ return !HasValue.prototype.match.apply(this, arguments);
5319
+ }
5320
+ });
5321
+
5322
+ acf.registerConditionType( HasNoValue );
5323
+
5324
+
5325
+
5326
+ /**
5327
+ * EqualTo
5328
+ *
5329
+ * description
5330
+ *
5331
+ * @date 1/2/18
5332
+ * @since 5.6.5
5333
+ *
5334
+ * @param void
5335
+ * @return void
5336
+ */
5337
+
5338
+ var EqualTo = acf.Condition.extend({
5339
+ type: 'equalTo',
5340
+ operator: '==',
5341
+ label: __('Value is equal to'),
5342
+ fieldTypes: [ 'text', 'textarea', 'number', 'range', 'email', 'url', 'password' ],
5343
+ match: function( rule, field ){
5344
+ if( acf.isNumeric(rule.value) ) {
5345
+ return isEqualToNumber( rule.value, field.val() );
5346
+ } else {
5347
+ return isEqualTo( rule.value, field.val() );
5348
+ }
5349
+ },
5350
+ choices: function( fieldObject ){
5351
+ return '<input type="text" />';
5352
+ }
5353
+ });
5354
+
5355
+ acf.registerConditionType( EqualTo );
5356
+
5357
+ /**
5358
+ * NotEqualTo
5359
+ *
5360
+ * description
5361
+ *
5362
+ * @date 1/2/18
5363
+ * @since 5.6.5
5364
+ *
5365
+ * @param void
5366
+ * @return void
5367
+ */
5368
+
5369
+ var NotEqualTo = EqualTo.extend({
5370
+ type: 'notEqualTo',
5371
+ operator: '!=',
5372
+ label: __('Value is not equal to'),
5373
+ match: function( rule, field ){
5374
+ return !EqualTo.prototype.match.apply(this, arguments);
5375
+ }
5376
+ });
5377
+
5378
+ acf.registerConditionType( NotEqualTo );
5379
+
5380
+ /**
5381
+ * PatternMatch
5382
+ *
5383
+ * description
5384
+ *
5385
+ * @date 1/2/18
5386
+ * @since 5.6.5
5387
+ *
5388
+ * @param void
5389
+ * @return void
5390
+ */
5391
+
5392
+ var PatternMatch = acf.Condition.extend({
5393
+ type: 'patternMatch',
5394
+ operator: '==pattern',
5395
+ label: __('Value matches pattern'),
5396
+ fieldTypes: [ 'text', 'textarea', 'email', 'url', 'password', 'wysiwyg' ],
5397
+ match: function( rule, field ){
5398
+ return matchesPattern( field.val(), rule.value );
5399
+ },
5400
+ choices: function( fieldObject ){
5401
+ return '<input type="text" placeholder="[a-z0-9]" />';
5402
+ }
5403
+ });
5404
+
5405
+ acf.registerConditionType( PatternMatch );
5406
+
5407
+ /**
5408
+ * Contains
5409
+ *
5410
+ * description
5411
+ *
5412
+ * @date 1/2/18
5413
+ * @since 5.6.5
5414
+ *
5415
+ * @param void
5416
+ * @return void
5417
+ */
5418
+
5419
+ var Contains = acf.Condition.extend({
5420
+ type: 'contains',
5421
+ operator: '==contains',
5422
+ label: __('Value contains'),
5423
+ fieldTypes: [ 'text', 'textarea', 'number', 'email', 'url', 'password', 'wysiwyg', 'oembed', 'select' ],
5424
+ match: function( rule, field ){
5425
+ return containsString( field.val(), rule.value );
5426
+ },
5427
+ choices: function( fieldObject ){
5428
+ return '<input type="text" />';
5429
+ }
5430
+ });
5431
+
5432
+ acf.registerConditionType( Contains );
5433
+
5434
+ /**
5435
+ * TrueFalseEqualTo
5436
+ *
5437
+ * description
5438
+ *
5439
+ * @date 1/2/18
5440
+ * @since 5.6.5
5441
+ *
5442
+ * @param void
5443
+ * @return void
5444
+ */
5445
+
5446
+ var TrueFalseEqualTo = EqualTo.extend({
5447
+ type: 'trueFalseEqualTo',
5448
+ choiceType: 'select',
5449
+ fieldTypes: [ 'true_false' ],
5450
+ choices: function( field ){
5451
+ return [
5452
+ {
5453
+ id: 1,
5454
+ text: __('Checked')
5455
+ }
5456
+ ];
5457
+ },
5458
+ });
5459
+
5460
+ acf.registerConditionType( TrueFalseEqualTo );
5461
+
5462
+ /**
5463
+ * TrueFalseNotEqualTo
5464
+ *
5465
+ * description
5466
+ *
5467
+ * @date 1/2/18
5468
+ * @since 5.6.5
5469
+ *
5470
+ * @param void
5471
+ * @return void
5472
+ */
5473
+
5474
+ var TrueFalseNotEqualTo = NotEqualTo.extend({
5475
+ type: 'trueFalseNotEqualTo',
5476
+ choiceType: 'select',
5477
+ fieldTypes: [ 'true_false' ],
5478
+ choices: function( field ){
5479
+ return [
5480
+ {
5481
+ id: 1,
5482
+ text: __('Checked')
5483
+ }
5484
+ ];
5485
+ },
5486
+ });
5487
+
5488
+ acf.registerConditionType( TrueFalseNotEqualTo );
5489
+
5490
+ /**
5491
+ * SelectEqualTo
5492
+ *
5493
+ * description
5494
+ *
5495
+ * @date 1/2/18
5496
+ * @since 5.6.5
5497
+ *
5498
+ * @param void
5499
+ * @return void
5500
+ */
5501
+
5502
+ var SelectEqualTo = acf.Condition.extend({
5503
+ type: 'selectEqualTo',
5504
+ operator: '==',
5505
+ label: __('Value is equal to'),
5506
+ fieldTypes: [ 'select', 'checkbox', 'radio', 'button_group' ],
5507
+ match: function( rule, field ){
5508
+ var val = field.val();
5509
+ if( val instanceof Array ) {
5510
+ return inArray( rule.value, val );
5511
+ } else {
5512
+ return isEqualTo( rule.value, val );
5513
+ }
5514
+ },
5515
+ choices: function( fieldObject ){
5516
+
5517
+ // vars
5518
+ var choices = [];
5519
+ var lines = fieldObject.$setting('choices textarea').val().split("\n");
5520
+
5521
+ // allow null
5522
+ if( fieldObject.$input('allow_null').prop('checked') ) {
5523
+ choices.push({
5524
+ id: '',
5525
+ text: __('Null')
5526
+ });
5527
+ }
5528
+
5529
+ // loop
5530
+ lines.map(function( line ){
5531
+
5532
+ // split
5533
+ line = line.split(':');
5534
+
5535
+ // default label to value
5536
+ line[1] = line[1] || line[0];
5537
+
5538
+ // append
5539
+ choices.push({
5540
+ id: line[0].trim(),
5541
+ text: line[1].trim()
5542
+ });
5543
+ });
5544
+
5545
+ // return
5546
+ return choices;
5547
+ },
5548
+ });
5549
+
5550
+ acf.registerConditionType( SelectEqualTo );
5551
+
5552
+ /**
5553
+ * SelectNotEqualTo
5554
+ *
5555
+ * description
5556
+ *
5557
+ * @date 1/2/18
5558
+ * @since 5.6.5
5559
+ *
5560
+ * @param void
5561
+ * @return void
5562
+ */
5563
+
5564
+ var SelectNotEqualTo = SelectEqualTo.extend({
5565
+ type: 'selectNotEqualTo',
5566
+ operator: '!=',
5567
+ label: __('Value is not equal to'),
5568
+ match: function( rule, field ){
5569
+ return !SelectEqualTo.prototype.match.apply(this, arguments);
5570
+ }
5571
+ });
5572
+
5573
+ acf.registerConditionType( SelectNotEqualTo );
5574
+
5575
+ /**
5576
+ * GreaterThan
5577
+ *
5578
+ * description
5579
+ *
5580
+ * @date 1/2/18
5581
+ * @since 5.6.5
5582
+ *
5583
+ * @param void
5584
+ * @return void
5585
+ */
5586
+
5587
+ var GreaterThan = acf.Condition.extend({
5588
+ type: 'greaterThan',
5589
+ operator: '>',
5590
+ label: __('Value is greater than'),
5591
+ fieldTypes: [ 'number', 'range' ],
5592
+ match: function( rule, field ){
5593
+ var val = field.val();
5594
+ if( val instanceof Array ) {
5595
+ val = val.length;
5596
+ }
5597
+ return isGreaterThan( val, rule.value );
5598
+ },
5599
+ choices: function( fieldObject ){
5600
+ return '<input type="number" />';
5601
+ }
5602
+ });
5603
+
5604
+ acf.registerConditionType( GreaterThan );
5605
+
5606
+
5607
+ /**
5608
+ * LessThan
5609
+ *
5610
+ * description
5611
+ *
5612
+ * @date 1/2/18
5613
+ * @since 5.6.5
5614
+ *
5615
+ * @param void
5616
+ * @return void
5617
+ */
5618
+
5619
+ var LessThan = GreaterThan.extend({
5620
+ type: 'lessThan',
5621
+ operator: '<',
5622
+ label: __('Value is less than'),
5623
+ match: function( rule, field ){
5624
+ var val = field.val();
5625
+ if( val instanceof Array ) {
5626
+ val = val.length;
5627
+ }
5628
+ return isLessThan( val, rule.value );
5629
+ },
5630
+ choices: function( fieldObject ){
5631
+ return '<input type="number" />';
5632
+ }
5633
+ });
5634
+
5635
+ acf.registerConditionType( LessThan );
5636
+
5637
+ /**
5638
+ * SelectedGreaterThan
5639
+ *
5640
+ * description
5641
+ *
5642
+ * @date 1/2/18
5643
+ * @since 5.6.5
5644
+ *
5645
+ * @param void
5646
+ * @return void
5647
+ */
5648
+
5649
+ var SelectionGreaterThan = GreaterThan.extend({
5650
+ type: 'selectionGreaterThan',
5651
+ label: __('Selection is greater than'),
5652
+ fieldTypes: [ 'checkbox', 'select', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user' ],
5653
+ });
5654
+
5655
+ acf.registerConditionType( SelectionGreaterThan );
5656
+
5657
+ /**
5658
+ * SelectedGreaterThan
5659
+ *
5660
+ * description
5661
+ *
5662
+ * @date 1/2/18
5663
+ * @since 5.6.5
5664
+ *
5665
+ * @param void
5666
+ * @return void
5667
+ */
5668
+
5669
+ var SelectionLessThan = LessThan.extend({
5670
+ type: 'selectionLessThan',
5671
+ label: __('Selection is less than'),
5672
+ fieldTypes: [ 'checkbox', 'select', 'post_object', 'page_link', 'relationship', 'taxonomy', 'user' ],
5673
+ });
5674
+
5675
+ acf.registerConditionType( SelectionLessThan );
5676
+
5677
+ })(jQuery);
5678
+ (function($, undefined){
5679
+
5680
+ acf.unload = new acf.Model({
5681
+
5682
+ wait: 'load',
5683
+ active: true,
5684
+ changed: false,
5685
+
5686
+ actions: {
5687
+ 'validation_failure': 'startListening',
5688
+ 'validation_success': 'stopListening'
5689
+ },
5690
+
5691
+ events: {
5692
+ 'change form .acf-field': 'startListening',
5693
+ 'submit form': 'stopListening'
5694
+ },
5695
+
5696
+ enable: function(){
5697
+ this.active = true;
5698
+ },
5699
+
5700
+ disable: function(){
5701
+ this.active = false;
5702
+ },
5703
+
5704
+ reset: function(){
5705
+ this.stopListening();
5706
+ },
5707
+
5708
+ startListening: function(){
5709
+
5710
+ // bail ealry if already changed, not active
5711
+ if( this.changed || !this.active ) {
5712
+ return;
5713
+ }
5714
+
5715
+ // update
5716
+ this.changed = true;
5717
+
5718
+ // add event
5719
+ $(window).on('beforeunload', this.onUnload);
5720
+
5721
+ },
5722
+
5723
+ stopListening: function(){
5724
+
5725
+ // update
5726
+ this.changed = false;
5727
+
5728
+ // remove event
5729
+ $(window).off('beforeunload', this.onUnload);
5730
+
5731
+ },
5732
+
5733
+ onUnload: function(){
5734
+ return acf.__('The changes you made will be lost if you navigate away from this page');
5735
+ }
5736
+
5737
+ });
5738
+
5739
+ })(jQuery);
5740
+ (function($, undefined){
5741
+
5742
+ /**
5743
+ * postboxManager
5744
+ *
5745
+ * Manages postboxes on the screen.
5746
+ *
5747
+ * @date 25/5/19
5748
+ * @since 5.8.1
5749
+ *
5750
+ * @param void
5751
+ * @return void
5752
+ */
5753
+ var postboxManager = new acf.Model({
5754
+ wait: 'prepare',
5755
+ priority: 1,
5756
+ initialize: function(){
5757
+ (acf.get('postboxes') || []).map( acf.newPostbox );
5758
+ },
5759
+ });
5760
+
5761
+ /**
5762
+ * acf.getPostbox
5763
+ *
5764
+ * Returns a postbox instance.
5765
+ *
5766
+ * @date 23/9/18
5767
+ * @since 5.7.7
5768
+ *
5769
+ * @param mixed $el Either a jQuery element or the postbox id.
5770
+ * @return object
5771
+ */
5772
+ acf.getPostbox = function( $el ){
5773
+
5774
+ // allow string parameter
5775
+ if( typeof arguments[0] == 'string' ) {
5776
+ $el = $('#' + arguments[0]);
5777
+ }
5778
+
5779
+ // return instance
5780
+ return acf.getInstance( $el );
5781
+ };
5782
+
5783
+ /**
5784
+ * acf.getPostboxes
5785
+ *
5786
+ * Returns an array of postbox instances.
5787
+ *
5788
+ * @date 23/9/18
5789
+ * @since 5.7.7
5790
+ *
5791
+ * @param void
5792
+ * @return array
5793
+ */
5794
+ acf.getPostboxes = function(){
5795
+ return acf.getInstances( $('.acf-postbox') );
5796
+ };
5797
+
5798
+ /**
5799
+ * acf.newPostbox
5800
+ *
5801
+ * Returns a new postbox instance for the given props.
5802
+ *
5803
+ * @date 20/9/18
5804
+ * @since 5.7.6
5805
+ *
5806
+ * @param object props The postbox properties.
5807
+ * @return object
5808
+ */
5809
+ acf.newPostbox = function( props ){
5810
+ return new acf.models.Postbox( props );
5811
+ };
5812
+
5813
+ /**
5814
+ * acf.models.Postbox
5815
+ *
5816
+ * The postbox model.
5817
+ *
5818
+ * @date 20/9/18
5819
+ * @since 5.7.6
5820
+ *
5821
+ * @param void
5822
+ * @return void
5823
+ */
5824
+ acf.models.Postbox = acf.Model.extend({
5825
+
5826
+ data: {
5827
+ id: '',
5828
+ key: '',
5829
+ style: 'default',
5830
+ label: 'top',
5831
+ edit: ''
5832
+ },
5833
+
5834
+ setup: function( props ){
5835
+
5836
+ // compatibilty
5837
+ if( props.editLink ) {
5838
+ props.edit = props.editLink;
5839
+ }
5840
+
5841
+ // extend data
5842
+ $.extend(this.data, props);
5843
+
5844
+ // set $el
5845
+ this.$el = this.$postbox();
5846
+ },
5847
+
5848
+ $postbox: function(){
5849
+ return $('#' + this.get('id'));
5850
+ },
5851
+
5852
+ $hide: function(){
5853
+ return $('#' + this.get('id') + '-hide');
5854
+ },
5855
+
5856
+ $hideLabel: function(){
5857
+ return this.$hide().parent();
5858
+ },
5859
+
5860
+ $hndle: function(){
5861
+ return this.$('> .hndle');
5862
+ },
5863
+
5864
+ $handleActions: function(){
5865
+ return this.$('> .postbox-header .handle-actions');
5866
+ },
5867
+
5868
+ $inside: function(){
5869
+ return this.$('> .inside');
5870
+ },
5871
+
5872
+ isVisible: function(){
5873
+ return this.$el.hasClass('acf-hidden');
5874
+ },
5875
+
5876
+ initialize: function(){
5877
+
5878
+ // Add default class.
5879
+ this.$el.addClass('acf-postbox');
5880
+
5881
+ // Remove 'hide-if-js class.
5882
+ // This class is added by WP to postboxes that are hidden via the "Screen Options" tab.
5883
+ this.$el.removeClass('hide-if-js');
5884
+
5885
+ // Add field group style class (ignore in block editor).
5886
+ if( acf.get('editor') !== 'block' ) {
5887
+ var style = this.get('style');
5888
+ if( style !== 'default' ) {
5889
+ this.$el.addClass( style );
5890
+ }
5891
+ }
5892
+
5893
+ // Add .inside class.
5894
+ this.$inside().addClass('acf-fields').addClass('-' + this.get('label'));
5895
+
5896
+ // Append edit link.
5897
+ var edit = this.get('edit');
5898
+ if( edit ) {
5899
+ var html = '<a href="' + edit + '" class="dashicons dashicons-admin-generic acf-hndle-cog acf-js-tooltip" title="' + acf.__('Edit field group') + '"></a>';
5900
+ var $handleActions = this.$handleActions();
5901
+ if( $handleActions.length ) {
5902
+ $handleActions.prepend( html );
5903
+ } else {
5904
+ this.$hndle().append( html );
5905
+ }
5906
+ }
5907
+
5908
+ // Show postbox.
5909
+ this.show();
5910
+ },
5911
+
5912
+ show: function(){
5913
+
5914
+ // Show label.
5915
+ this.$hideLabel().show();
5916
+
5917
+ // toggle on checkbox
5918
+ this.$hide().prop('checked', true);
5919
+
5920
+ // Show postbox
5921
+ this.$el.show().removeClass('acf-hidden');
5922
+
5923
+ // Do action.
5924
+ acf.doAction('show_postbox', this);
5925
+ },
5926
+
5927
+ enable: function(){
5928
+ acf.enable( this.$el, 'postbox' );
5929
+ },
5930
+
5931
+ showEnable: function(){
5932
+ this.enable();
5933
+ this.show();
5934
+ },
5935
+
5936
+ hide: function(){
5937
+
5938
+ // Hide label.
5939
+ this.$hideLabel().hide();
5940
+
5941
+ // Hide postbox
5942
+ this.$el.hide().addClass('acf-hidden');
5943
+
5944
+ // Do action.
5945
+ acf.doAction('hide_postbox', this);
5946
+ },
5947
+
5948
+ disable: function(){
5949
+ acf.disable( this.$el, 'postbox' );
5950
+ },
5951
+
5952
+ hideDisable: function(){
5953
+ this.disable();
5954
+ this.hide();
5955
+ },
5956
+
5957
+ html: function( html ){
5958
+
5959
+ // Update HTML.
5960
+ this.$inside().html( html );
5961
+
5962
+ // Do action.
5963
+ acf.doAction('append', this.$el);
5964
+ }
5965
+ });
5966
+
5967
+ })(jQuery);
5968
+ (function($, undefined){
5969
+
5970
+ /**
5971
+ * acf.newMediaPopup
5972
+ *
5973
+ * description
5974
+ *
5975
+ * @date 10/1/18
5976
+ * @since 5.6.5
5977
+ *
5978
+ * @param type $var Description. Default.
5979
+ * @return type Description.
5980
+ */
5981
+
5982
+ acf.newMediaPopup = function( args ){
5983
+
5984
+ // args
5985
+ var popup = null;
5986
+ var args = acf.parseArgs(args, {
5987
+ mode: 'select', // 'select', 'edit'
5988
+ title: '', // 'Upload Image'
5989
+ button: '', // 'Select Image'
5990
+ type: '', // 'image', ''
5991
+ field: false, // field instance
5992
+ allowedTypes: '', // '.jpg, .png, etc'
5993
+ library: 'all', // 'all', 'uploadedTo'
5994
+ multiple: false, // false, true, 'add'
5995
+ attachment: 0, // the attachment to edit
5996
+ autoOpen: true, // open the popup automatically
5997
+ open: function(){}, // callback after close
5998
+ select: function(){}, // callback after select
5999
+ close: function(){} // callback after close
6000
+ });
6001
+
6002
+ // initialize
6003
+ if( args.mode == 'edit' ) {
6004
+ popup = new acf.models.EditMediaPopup( args );
6005
+ } else {
6006
+ popup = new acf.models.SelectMediaPopup( args );
6007
+ }
6008
+
6009
+ // open popup (allow frame customization before opening)
6010
+ if( args.autoOpen ) {
6011
+ setTimeout(function(){
6012
+ popup.open();
6013
+ }, 1);
6014
+ }
6015
+
6016
+ // action
6017
+ acf.doAction('new_media_popup', popup);
6018
+
6019
+ // return
6020
+ return popup;
6021
+ };
6022
+
6023
+
6024
+ /**
6025
+ * getPostID
6026
+ *
6027
+ * description
6028
+ *
6029
+ * @date 10/1/18
6030
+ * @since 5.6.5
6031
+ *
6032
+ * @param type $var Description. Default.
6033
+ * @return type Description.
6034
+ */
6035
+
6036
+ var getPostID = function() {
6037
+ var postID = acf.get('post_id');
6038
+ return acf.isNumeric(postID) ? postID : 0;
6039
+ }
6040
+
6041
+
6042
+ /**
6043
+ * acf.getMimeTypes
6044
+ *
6045
+ * description
6046
+ *
6047
+ * @date 11/1/18
6048
+ * @since 5.6.5
6049
+ *
6050
+ * @param type $var Description. Default.
6051
+ * @return type Description.
6052
+ */
6053
+
6054
+ acf.getMimeTypes = function(){
6055
+ return this.get('mimeTypes');
6056
+ };
6057
+
6058
+ acf.getMimeType = function( name ){
6059
+
6060
+ // vars
6061
+ var allTypes = acf.getMimeTypes();
6062
+
6063
+ // search
6064
+ if( allTypes[name] !== undefined ) {
6065
+ return allTypes[name];
6066
+ }
6067
+
6068
+ // some types contain a mixed key such as "jpg|jpeg|jpe"
6069
+ for( var key in allTypes ) {
6070
+ if( key.indexOf(name) !== -1 ) {
6071
+ return allTypes[key];
6072
+ }
6073
+ }
6074
+
6075
+ // return
6076
+ return false;
6077
+ };
6078
+
6079
+
6080
+ /**
6081
+ * MediaPopup
6082
+ *
6083
+ * description
6084
+ *
6085
+ * @date 10/1/18
6086
+ * @since 5.6.5
6087
+ *
6088
+ * @param type $var Description. Default.
6089
+ * @return type Description.
6090
+ */
6091
+
6092
+ var MediaPopup = acf.Model.extend({
6093
+
6094
+ id: 'MediaPopup',
6095
+ data: {},
6096
+ defaults: {},
6097
+ frame: false,
6098
+
6099
+ setup: function( props ){
6100
+ $.extend(this.data, props);
6101
+ },
6102
+
6103
+ initialize: function(){
6104
+
6105
+ // vars
6106
+ var options = this.getFrameOptions();
6107
+
6108
+ // add states
6109
+ this.addFrameStates( options );
6110
+
6111
+ // create frame
6112
+ var frame = wp.media( options );
6113
+
6114
+ // add args reference
6115
+ frame.acf = this;
6116
+
6117
+ // add events
6118
+ this.addFrameEvents( frame, options );
6119
+
6120
+ // strore frame
6121
+ this.frame = frame;
6122
+ },
6123
+
6124
+ open: function(){
6125
+ this.frame.open();
6126
+ },
6127
+
6128
+ close: function(){
6129
+ this.frame.close();
6130
+ },
6131
+
6132
+ remove: function(){
6133
+ this.frame.detach();
6134
+ this.frame.remove();
6135
+ },
6136
+
6137
+ getFrameOptions: function(){
6138
+
6139
+ // vars
6140
+ var options = {
6141
+ title: this.get('title'),
6142
+ multiple: this.get('multiple'),
6143
+ library: {},
6144
+ states: []
6145
+ };
6146
+
6147
+ // type
6148
+ if( this.get('type') ) {
6149
+ options.library.type = this.get('type');
6150
+ }
6151
+
6152
+ // type
6153
+ if( this.get('library') === 'uploadedTo' ) {
6154
+ options.library.uploadedTo = getPostID();
6155
+ }
6156
+
6157
+ // attachment
6158
+ if( this.get('attachment') ) {
6159
+ options.library.post__in = [ this.get('attachment') ];
6160
+ }
6161
+
6162
+ // button
6163
+ if( this.get('button') ) {
6164
+ options.button = {
6165
+ text: this.get('button')
6166
+ };
6167
+ }
6168
+
6169
+ // return
6170
+ return options;
6171
+ },
6172
+
6173
+ addFrameStates: function( options ){
6174
+
6175
+ // create query
6176
+ var Query = wp.media.query( options.library );
6177
+
6178
+ // add _acfuploader
6179
+ // this is super wack!
6180
+ // if you add _acfuploader to the options.library args, new uploads will not be added to the library view.
6181
+ // this has been traced back to the wp.media.model.Query initialize function (which can't be overriden)
6182
+ // Adding any custom args will cause the Attahcments to not observe the uploader queue
6183
+ // To bypass this security issue, we add in the args AFTER the Query has been initialized
6184
+ // options.library._acfuploader = settings.field;
6185
+ if( this.get('field') && acf.isset(Query, 'mirroring', 'args') ) {
6186
+ Query.mirroring.args._acfuploader = this.get('field');
6187
+ }
6188
+
6189
+ // add states
6190
+ options.states.push(
6191
+
6192
+ // main state
6193
+ new wp.media.controller.Library({
6194
+ library: Query,
6195
+ multiple: this.get('multiple'),
6196
+ title: this.get('title'),
6197
+ priority: 20,
6198
+ filterable: 'all',
6199
+ editable: true,
6200
+ allowLocalEdits: true
6201
+ })
6202
+
6203
+ );
6204
+
6205
+ // edit image functionality (added in WP 3.9)
6206
+ if( acf.isset(wp, 'media', 'controller', 'EditImage') ) {
6207
+ options.states.push( new wp.media.controller.EditImage() );
6208
+ }
6209
+ },
6210
+
6211
+ addFrameEvents: function( frame, options ){
6212
+
6213
+ // log all events
6214
+ //frame.on('all', function( e ) {
6215
+ // console.log( 'frame all: %o', e );
6216
+ //});
6217
+
6218
+ // add class
6219
+ frame.on('open',function() {
6220
+ this.$el.closest('.media-modal').addClass('acf-media-modal -' + this.acf.get('mode') );
6221
+ }, frame);
6222
+
6223
+ // edit image view
6224
+ // source: media-views.js:2410 editImageContent()
6225
+ frame.on('content:render:edit-image', function(){
6226
+
6227
+ var image = this.state().get('image');
6228
+ var view = new wp.media.view.EditImage({ model: image, controller: this }).render();
6229
+ this.content.set( view );
6230
+
6231
+ // after creating the wrapper view, load the actual editor via an ajax call
6232
+ view.loadEditor();
6233
+
6234
+ }, frame);
6235
+
6236
+ // update toolbar button
6237
+ //frame.on( 'toolbar:create:select', function( toolbar ) {
6238
+ // toolbar.view = new wp.media.view.Toolbar.Select({
6239
+ // text: frame.options._button,
6240
+ // controller: this
6241
+ // });
6242
+ //}, frame );
6243
+
6244
+ // on select
6245
+ frame.on('select', function() {
6246
+
6247
+ // vars
6248
+ var selection = frame.state().get('selection');
6249
+
6250
+ // if selecting images
6251
+ if( selection ) {
6252
+
6253
+ // loop
6254
+ selection.each(function( attachment, i ){
6255
+ frame.acf.get('select').apply( frame.acf, [attachment, i] );
6256
+ });
6257
+ }
6258
+ });
6259
+
6260
+ // on close
6261
+ frame.on('close',function(){
6262
+
6263
+ // callback and remove
6264
+ setTimeout(function(){
6265
+ frame.acf.get('close').apply( frame.acf );
6266
+ frame.acf.remove();
6267
+ }, 1);
6268
+ });
6269
+ }
6270
+ });
6271
+
6272
+
6273
+ /**
6274
+ * acf.models.SelectMediaPopup
6275
+ *
6276
+ * description
6277
+ *
6278
+ * @date 10/1/18
6279
+ * @since 5.6.5
6280
+ *
6281
+ * @param type $var Description. Default.
6282
+ * @return type Description.
6283
+ */
6284
+
6285
+ acf.models.SelectMediaPopup = MediaPopup.extend({
6286
+ id: 'SelectMediaPopup',
6287
+ setup: function( props ){
6288
+
6289
+ // default button
6290
+ if( !props.button ) {
6291
+ props.button = acf._x('Select', 'verb');
6292
+ }
6293
+
6294
+ // parent
6295
+ MediaPopup.prototype.setup.apply(this, arguments);
6296
+ },
6297
+
6298
+ addFrameEvents: function( frame, options ){
6299
+
6300
+ // plupload
6301
+ // adds _acfuploader param to validate uploads
6302
+ if( acf.isset(_wpPluploadSettings, 'defaults', 'multipart_params') ) {
6303
+
6304
+ // add _acfuploader so that Uploader will inherit
6305
+ _wpPluploadSettings.defaults.multipart_params._acfuploader = this.get('field');
6306
+
6307
+ // remove acf_field so future Uploaders won't inherit
6308
+ frame.on('open', function(){
6309
+ delete _wpPluploadSettings.defaults.multipart_params._acfuploader;
6310
+ });
6311
+ }
6312
+
6313
+ // browse
6314
+ frame.on('content:activate:browse', function(){
6315
+
6316
+ // vars
6317
+ var toolbar = false;
6318
+
6319
+ // populate above vars making sure to allow for failure
6320
+ // perhaps toolbar does not exist because the frame open is Upload Files
6321
+ try {
6322
+ toolbar = frame.content.get().toolbar;
6323
+ } catch(e) {
6324
+ console.log(e);
6325
+ return;
6326
+ }
6327
+
6328
+ // callback
6329
+ frame.acf.customizeFilters.apply(frame.acf, [toolbar]);
6330
+ });
6331
+
6332
+ // parent
6333
+ MediaPopup.prototype.addFrameEvents.apply(this, arguments);
6334
+
6335
+ },
6336
+
6337
+ customizeFilters: function( toolbar ){
6338
+
6339
+ // vars
6340
+ var filters = toolbar.get('filters');
6341
+
6342
+ // image
6343
+ if( this.get('type') == 'image' ) {
6344
+
6345
+ // update all
6346
+ filters.filters.all.text = acf.__('All images');
6347
+
6348
+ // remove some filters
6349
+ delete filters.filters.audio;
6350
+ delete filters.filters.video;
6351
+ delete filters.filters.image;
6352
+
6353
+ // update all filters to show images
6354
+ $.each(filters.filters, function( i, filter ){
6355
+ filter.props.type = filter.props.type || 'image';
6356
+ });
6357
+ }
6358
+
6359
+ // specific types
6360
+ if( this.get('allowedTypes') ) {
6361
+
6362
+ // convert ".jpg, .png" into ["jpg", "png"]
6363
+ var allowedTypes = this.get('allowedTypes').split(' ').join('').split('.').join('').split(',');
6364
+
6365
+ // loop
6366
+ allowedTypes.map(function( name ){
6367
+
6368
+ // get type
6369
+ var mimeType = acf.getMimeType( name );
6370
+
6371
+ // bail early if no type
6372
+ if( !mimeType ) return;
6373
+
6374
+ // create new filter
6375
+ var newFilter = {
6376
+ text: mimeType,
6377
+ props: {
6378
+ status: null,
6379
+ type: mimeType,
6380
+ uploadedTo: null,
6381
+ orderby: 'date',
6382
+ order: 'DESC'
6383
+ },
6384
+ priority: 20
6385
+ };
6386
+
6387
+ // append
6388
+ filters.filters[ mimeType ] = newFilter;
6389
+
6390
+ });
6391
+ }
6392
+
6393
+
6394
+
6395
+ // uploaded to post
6396
+ if( this.get('library') === 'uploadedTo' ) {
6397
+
6398
+ // vars
6399
+ var uploadedTo = this.frame.options.library.uploadedTo;
6400
+
6401
+ // remove some filters
6402
+ delete filters.filters.unattached;
6403
+ delete filters.filters.uploaded;
6404
+
6405
+ // add uploadedTo to filters
6406
+ $.each(filters.filters, function( i, filter ){
6407
+ filter.text += ' (' + acf.__('Uploaded to this post') + ')';
6408
+ filter.props.uploadedTo = uploadedTo;
6409
+ });
6410
+ }
6411
+
6412
+ // add _acfuploader to filters
6413
+ var field = this.get('field');
6414
+ $.each(filters.filters, function( k, filter ){
6415
+ filter.props._acfuploader = field;
6416
+ });
6417
+
6418
+ // add _acfuplaoder to search
6419
+ var search = toolbar.get('search');
6420
+ search.model.attributes._acfuploader = field;
6421
+
6422
+ // render (custom function added to prototype)
6423
+ if( filters.renderFilters ) {
6424
+ filters.renderFilters();
6425
+ }
6426
+ }
6427
+ });
6428
+
6429
+
6430
+ /**
6431
+ * acf.models.EditMediaPopup
6432
+ *
6433
+ * description
6434
+ *
6435
+ * @date 10/1/18
6436
+ * @since 5.6.5
6437
+ *
6438
+ * @param type $var Description. Default.
6439
+ * @return type Description.
6440
+ */
6441
+
6442
+ acf.models.EditMediaPopup = MediaPopup.extend({
6443
+ id: 'SelectMediaPopup',
6444
+ setup: function( props ){
6445
+
6446
+ // default button
6447
+ if( !props.button ) {
6448
+ props.button = acf._x('Update', 'verb');
6449
+ }
6450
+
6451
+ // parent
6452
+ MediaPopup.prototype.setup.apply(this, arguments);
6453
+ },
6454
+
6455
+ addFrameEvents: function( frame, options ){
6456
+
6457
+ // add class
6458
+ frame.on('open',function() {
6459
+
6460
+ // add class
6461
+ this.$el.closest('.media-modal').addClass('acf-expanded');
6462
+
6463
+ // set to browse
6464
+ if( this.content.mode() != 'browse' ) {
6465
+ this.content.mode('browse');
6466
+ }
6467
+
6468
+ // set selection
6469
+ var state = this.state();
6470
+ var selection = state.get('selection');
6471
+ var attachment = wp.media.attachment( frame.acf.get('attachment') );
6472
+ selection.add( attachment );
6473
+
6474
+ }, frame);
6475
+
6476
+ // parent
6477
+ MediaPopup.prototype.addFrameEvents.apply(this, arguments);
6478
+
6479
+ }
6480
+ });
6481
+
6482
+
6483
+ /**
6484
+ * customizePrototypes
6485
+ *
6486
+ * description
6487
+ *
6488
+ * @date 11/1/18
6489
+ * @since 5.6.5
6490
+ *
6491
+ * @param type $var Description. Default.
6492
+ * @return type Description.
6493
+ */
6494
+
6495
+ var customizePrototypes = new acf.Model({
6496
+ id: 'customizePrototypes',
6497
+ wait: 'ready',
6498
+
6499
+ initialize: function(){
6500
+
6501
+ // bail early if no media views
6502
+ if( !acf.isset(window, 'wp', 'media', 'view') ) {
6503
+ return;
6504
+ }
6505
+
6506
+ // fix bug where CPT without "editor" does not set post.id setting which then prevents uploadedTo from working
6507
+ var postID = getPostID();
6508
+ if( postID && acf.isset(wp, 'media', 'view', 'settings', 'post') ) {
6509
+ wp.media.view.settings.post.id = postID;
6510
+ }
6511
+
6512
+ // customize
6513
+ this.customizeAttachmentsButton();
6514
+ this.customizeAttachmentsRouter();
6515
+ this.customizeAttachmentFilters();
6516
+ this.customizeAttachmentCompat();
6517
+ this.customizeAttachmentLibrary();
6518
+ },
6519
+
6520
+ customizeAttachmentsButton: function(){
6521
+
6522
+ // validate
6523
+ if( !acf.isset(wp, 'media', 'view', 'Button') ) {
6524
+ return;
6525
+ }
6526
+
6527
+ // Extend
6528
+ var Button = wp.media.view.Button;
6529
+ wp.media.view.Button = Button.extend({
6530
+
6531
+ // Fix bug where "Select" button appears blank after editing an image.
6532
+ // Do this by simplifying Button initialize function and avoid deleting this.options.
6533
+ initialize: function() {
6534
+ var options = _.defaults( this.options, this.defaults );
6535
+ this.model = new Backbone.Model( options );
6536
+ this.listenTo( this.model, 'change', this.render );
6537
+ }
6538
+ });
6539
+
6540
+ },
6541
+
6542
+ customizeAttachmentsRouter: function(){
6543
+
6544
+ // validate
6545
+ if( !acf.isset(wp, 'media', 'view', 'Router') ) {
6546
+ return;
6547
+ }
6548
+
6549
+ // vars
6550
+ var Parent = wp.media.view.Router;
6551
+
6552
+ // extend
6553
+ wp.media.view.Router = Parent.extend({
6554
+
6555
+ addExpand: function(){
6556
+
6557
+ // vars
6558
+ var $a = $([
6559
+ '<a href="#" class="acf-expand-details">',
6560
+ '<span class="is-closed"><i class="acf-icon -left -small"></i>' + acf.__('Expand Details') + '</span>',
6561
+ '<span class="is-open"><i class="acf-icon -right -small"></i>' + acf.__('Collapse Details') + '</span>',
6562
+ '</a>'
6563
+ ].join(''));
6564
+
6565
+ // add events
6566
+ $a.on('click', function( e ){
6567
+ e.preventDefault();
6568
+ var $div = $(this).closest('.media-modal');
6569
+ if( $div.hasClass('acf-expanded') ) {
6570
+ $div.removeClass('acf-expanded');
6571
+ } else {
6572
+ $div.addClass('acf-expanded');
6573
+ }
6574
+ });
6575
+
6576
+ // append
6577
+ this.$el.append( $a );
6578
+ },
6579
+
6580
+ initialize: function(){
6581
+
6582
+ // initialize
6583
+ Parent.prototype.initialize.apply( this, arguments );
6584
+
6585
+ // add buttons
6586
+ this.addExpand();
6587
+
6588
+ // return
6589
+ return this;
6590
+ }
6591
+ });
6592
+ },
6593
+
6594
+ customizeAttachmentFilters: function(){
6595
+
6596
+ // validate
6597
+ if( !acf.isset(wp, 'media', 'view', 'AttachmentFilters', 'All') ) {
6598
+ return;
6599
+ }
6600
+
6601
+ // vars
6602
+ var Parent = wp.media.view.AttachmentFilters.All;
6603
+
6604
+ // renderFilters
6605
+ // copied from media-views.js:6939
6606
+ Parent.prototype.renderFilters = function(){
6607
+
6608
+ // Build `<option>` elements.
6609
+ this.$el.html( _.chain( this.filters ).map( function( filter, value ) {
6610
+ return {
6611
+ el: $( '<option></option>' ).val( value ).html( filter.text )[0],
6612
+ priority: filter.priority || 50
6613
+ };
6614
+ }, this ).sortBy('priority').pluck('el').value() );
6615
+
6616
+ };
6617
+ },
6618
+
6619
+ customizeAttachmentCompat: function(){
6620
+
6621
+ // validate
6622
+ if( !acf.isset(wp, 'media', 'view', 'AttachmentCompat') ) {
6623
+ return;
6624
+ }
6625
+
6626
+ // vars
6627
+ var AttachmentCompat = wp.media.view.AttachmentCompat;
6628
+ var timeout = false;
6629
+
6630
+ // extend
6631
+ wp.media.view.AttachmentCompat = AttachmentCompat.extend({
6632
+
6633
+ render: function() {
6634
+
6635
+ // WP bug
6636
+ // When multiple media frames exist on the same page (WP content, WYSIWYG, image, file ),
6637
+ // WP creates multiple instances of this AttachmentCompat view.
6638
+ // Each instance will attempt to render when a new modal is created.
6639
+ // Use a property to avoid this and only render once per instance.
6640
+ if( this.rendered ) {
6641
+ return this;
6642
+ }
6643
+
6644
+ // render HTML
6645
+ AttachmentCompat.prototype.render.apply( this, arguments );
6646
+
6647
+ // when uploading, render is called twice.
6648
+ // ignore first render by checking for #acf-form-data element
6649
+ if( !this.$('#acf-form-data').length ) {
6650
+ return this;
6651
+ }
6652
+
6653
+ // clear timeout
6654
+ clearTimeout( timeout );
6655
+
6656
+ // setTimeout
6657
+ timeout = setTimeout($.proxy(function(){
6658
+ this.rendered = true;
6659
+ acf.doAction('append', this.$el);
6660
+ }, this), 50);
6661
+
6662
+ // return
6663
+ return this;
6664
+ },
6665
+
6666
+ save: function( event ) {
6667
+ var data = {};
6668
+
6669
+ if ( event ) {
6670
+ event.preventDefault();
6671
+ }
6672
+
6673
+ //_.each( this.$el.serializeArray(), function( pair ) {
6674
+ // data[ pair.name ] = pair.value;
6675
+ //});
6676
+
6677
+ // Serialize data more thoroughly to allow chckbox inputs to save.
6678
+ data = acf.serializeForAjax(this.$el);
6679
+
6680
+ this.controller.trigger( 'attachment:compat:waiting', ['waiting'] );
6681
+ this.model.saveCompat( data ).always( _.bind( this.postSave, this ) );
6682
+ }
6683
+ });
6684
+
6685
+ },
6686
+
6687
+ customizeAttachmentLibrary: function(){
6688
+
6689
+ // validate
6690
+ if( !acf.isset(wp, 'media', 'view', 'Attachment', 'Library') ) {
6691
+ return;
6692
+ }
6693
+
6694
+ // vars
6695
+ var AttachmentLibrary = wp.media.view.Attachment.Library;
6696
+
6697
+ // extend
6698
+ wp.media.view.Attachment.Library = AttachmentLibrary.extend({
6699
+
6700
+ render: function() {
6701
+
6702
+ // vars
6703
+ var popup = acf.isget(this, 'controller', 'acf');
6704
+ var attributes = acf.isget(this, 'model', 'attributes');
6705
+
6706
+ // check vars exist to avoid errors
6707
+ if( popup && attributes ) {
6708
+
6709
+ // show errors
6710
+ if( attributes.acf_errors ) {
6711
+ this.$el.addClass('acf-disabled');
6712
+ }
6713
+
6714
+ // disable selected
6715
+ var selected = popup.get('selected');
6716
+ if( selected && selected.indexOf(attributes.id) > -1 ) {
6717
+ this.$el.addClass('acf-selected');
6718
+ }
6719
+ }
6720
+
6721
+ // render
6722
+ return AttachmentLibrary.prototype.render.apply( this, arguments );
6723
+
6724
+ },
6725
+
6726
+
6727
+ /*
6728
+ * toggleSelection
6729
+ *
6730
+ * This function is called before an attachment is selected
6731
+ * A good place to check for errors and prevent the 'select' function from being fired
6732
+ *
6733
+ * @type function
6734
+ * @date 29/09/2016
6735
+ * @since 5.4.0
6736
+ *
6737
+ * @param options (object)
6738
+ * @return n/a
6739
+ */
6740
+
6741
+ toggleSelection: function( options ) {
6742
+
6743
+ // vars
6744
+ // source: wp-includes/js/media-views.js:2880
6745
+ var collection = this.collection,
6746
+ selection = this.options.selection,
6747
+ model = this.model,
6748
+ single = selection.single();
6749
+
6750
+
6751
+ // vars
6752
+ var frame = this.controller;
6753
+ var errors = acf.isget(this, 'model', 'attributes', 'acf_errors');
6754
+ var $sidebar = frame.$el.find('.media-frame-content .media-sidebar');
6755
+
6756
+ // remove previous error
6757
+ $sidebar.children('.acf-selection-error').remove();
6758
+
6759
+ // show attachment details
6760
+ $sidebar.children().removeClass('acf-hidden');
6761
+
6762
+ // add message
6763
+ if( frame && errors ) {
6764
+
6765
+ // vars
6766
+ var filename = acf.isget(this, 'model', 'attributes', 'filename');
6767
+
6768
+ // hide attachment details
6769
+ // Gallery field continues to show previously selected attachment...
6770
+ $sidebar.children().addClass('acf-hidden');
6771
+
6772
+ // append message
6773
+ $sidebar.prepend([
6774
+ '<div class="acf-selection-error">',
6775
+ '<span class="selection-error-label">' + acf.__('Restricted') +'</span>',
6776
+ '<span class="selection-error-filename">' + filename + '</span>',
6777
+ '<span class="selection-error-message">' + errors + '</span>',
6778
+ '</div>'
6779
+ ].join(''));
6780
+
6781
+ // reset selection (unselects all attachments)
6782
+ selection.reset();
6783
+
6784
+ // set single (attachment displayed in sidebar)
6785
+ selection.single( model );
6786
+
6787
+ // return and prevent 'select' form being fired
6788
+ return;
6789
+
6790
+ }
6791
+
6792
+ // return
6793
+ return AttachmentLibrary.prototype.toggleSelection.apply( this, arguments );
6794
+ }
6795
+ });
6796
+ }
6797
+ });
6798
 
6799
+ })(jQuery);
6800
+ (function($, undefined){
6801
+
6802
+ acf.screen = new acf.Model({
6803
+
6804
+ active: true,
6805
+
6806
+ xhr: false,
6807
+
6808
+ timeout: false,
6809
+
6810
+ wait: 'load',
6811
+
6812
+ events: {
6813
+ 'change #page_template': 'onChange',
6814
+ 'change #parent_id': 'onChange',
6815
+ 'change #post-formats-select': 'onChange',
6816
+ 'change .categorychecklist': 'onChange',
6817
+ 'change .tagsdiv': 'onChange',
6818
+ 'change .acf-taxonomy-field[data-save="1"]': 'onChange',
6819
+ 'change #product-type': 'onChange'
6820
+ },
6821
+
6822
+ isPost: function(){
6823
+ return acf.get('screen') === 'post';
6824
+ },
6825
+
6826
+ isUser: function(){
6827
+ return acf.get('screen') === 'user';
6828
+ },
6829
+
6830
+ isTaxonomy: function(){
6831
+ return acf.get('screen') === 'taxonomy';
6832
+ },
6833
+
6834
+ isAttachment: function(){
6835
+ return acf.get('screen') === 'attachment';
6836
+ },
6837
+
6838
+ isNavMenu: function(){
6839
+ return acf.get('screen') === 'nav_menu';
6840
+ },
6841
+
6842
+ isWidget: function(){
6843
+ return acf.get('screen') === 'widget';
6844
+ },
6845
+
6846
+ isComment: function(){
6847
+ return acf.get('screen') === 'comment';
6848
+ },
6849
+
6850
+ getPageTemplate: function(){
6851
+ var $el = $('#page_template');
6852
+ return $el.length ? $el.val() : null;
6853
+ },
6854
+
6855
+ getPageParent: function( e, $el ){
6856
+ var $el = $('#parent_id');
6857
+ return $el.length ? $el.val() : null;
6858
+ },
6859
+
6860
+ getPageType: function( e, $el ){
6861
+ return this.getPageParent() ? 'child' : 'parent';
6862
+ },
6863
+
6864
+ getPostType: function(){
6865
+ return $('#post_type').val();
6866
+ },
6867
+
6868
+ getPostFormat: function( e, $el ){
6869
+ var $el = $('#post-formats-select input:checked');
6870
+ if( $el.length ) {
6871
+ var val = $el.val();
6872
+ return (val == '0') ? 'standard' : val;
6873
+ }
6874
+ return null;
6875
+ },
6876
+
6877
+ getPostCoreTerms: function(){
6878
+
6879
+ // vars
6880
+ var terms = {};
6881
+
6882
+ // serialize WP taxonomy postboxes
6883
+ var data = acf.serialize( $('.categorydiv, .tagsdiv') );
6884
+
6885
+ // use tax_input (tag, custom-taxonomy) when possible.
6886
+ // this data is already formatted in taxonomy => [terms].
6887
+ if( data.tax_input ) {
6888
+ terms = data.tax_input;
6889
+ }
6890
+
6891
+ // append "category" which uses a different name
6892
+ if( data.post_category ) {
6893
+ terms.category = data.post_category;
6894
+ }
6895
+
6896
+ // convert any string values (tags) into array format
6897
+ for( var tax in terms ) {
6898
+ if( !acf.isArray(terms[tax]) ) {
6899
+ terms[tax] = terms[tax].split(/,[\s]?/);
6900
+ }
6901
+ }
6902
+
6903
+ // return
6904
+ return terms;
6905
+ },
6906
+
6907
+ getPostTerms: function(){
6908
+
6909
+ // Get core terms.
6910
+ var terms = this.getPostCoreTerms();
6911
+
6912
+ // loop over taxonomy fields and add their values
6913
+ acf.getFields({type: 'taxonomy'}).map(function( field ){
6914
+
6915
+ // ignore fields that don't save
6916
+ if( !field.get('save') ) {
6917
+ return;
6918
+ }
6919
+
6920
+ // vars
6921
+ var val = field.val();
6922
+ var tax = field.get('taxonomy');
6923
+
6924
+ // check val
6925
+ if( val ) {
6926
+
6927
+ // ensure terms exists
6928
+ terms[ tax ] = terms[ tax ] || [];
6929
+
6930
+ // ensure val is an array
6931
+ val = acf.isArray(val) ? val : [val];
6932
+
6933
+ // append
6934
+ terms[ tax ] = terms[ tax ].concat( val );
6935
+ }
6936
+ });
6937
+
6938
+ // add WC product type
6939
+ if( (productType = this.getProductType()) !== null ) {
6940
+ terms.product_type = [productType];
6941
+ }
6942
+
6943
+ // remove duplicate values
6944
+ for( var tax in terms ) {
6945
+ terms[tax] = acf.uniqueArray(terms[tax]);
6946
+ }
6947
+
6948
+ // return
6949
+ return terms;
6950
+ },
6951
+
6952
+ getProductType: function(){
6953
+ var $el = $('#product-type');
6954
+ return $el.length ? $el.val() : null;
6955
+ },
6956
+
6957
+ check: function(){
6958
+
6959
+ // bail early if not for post
6960
+ if( acf.get('screen') !== 'post' ) {
6961
+ return;
6962
+ }
6963
+
6964
+ // abort XHR if is already loading AJAX data
6965
+ if( this.xhr ) {
6966
+ this.xhr.abort();
6967
+ }
6968
+
6969
+ // vars
6970
+ var ajaxData = acf.parseArgs(this.data, {
6971
+ action: 'acf/ajax/check_screen',
6972
+ screen: acf.get('screen'),
6973
+ exists: []
6974
+ });
6975
+
6976
+ // post id
6977
+ if( this.isPost() ) {
6978
+ ajaxData.post_id = acf.get('post_id');
6979
+ }
6980
+
6981
+ // post type
6982
+ if( (postType = this.getPostType()) !== null ) {
6983
+ ajaxData.post_type = postType;
6984
+ }
6985
+
6986
+ // page template
6987
+ if( (pageTemplate = this.getPageTemplate()) !== null ) {
6988
+ ajaxData.page_template = pageTemplate;
6989
+ }
6990
+
6991
+ // page parent
6992
+ if( (pageParent = this.getPageParent()) !== null ) {
6993
+ ajaxData.page_parent = pageParent;
6994
+ }
6995
+
6996
+ // page type
6997
+ if( (pageType = this.getPageType()) !== null ) {
6998
+ ajaxData.page_type = pageType;
6999
+ }
7000
+
7001
+ // post format
7002
+ if( (postFormat = this.getPostFormat()) !== null ) {
7003
+ ajaxData.post_format = postFormat;
7004
+ }
7005
+
7006
+ // post terms
7007
+ if( (postTerms = this.getPostTerms()) !== null ) {
7008
+ ajaxData.post_terms = postTerms;
7009
+ }
7010
+
7011
+ // add array of existing postboxes to increase performance and reduce JSON HTML
7012
+ acf.getPostboxes().map(function( postbox ){
7013
+ ajaxData.exists.push( postbox.get('key') );
7014
+ });
7015
+
7016
+ // filter
7017
+ ajaxData = acf.applyFilters('check_screen_args', ajaxData);
7018
+
7019
+ // success
7020
+ var onSuccess = function( json ){
7021
+
7022
+ // Render post screen.
7023
+ if( acf.get('screen') == 'post' ) {
7024
+ this.renderPostScreen( json );
7025
+
7026
+ // Render user screen.
7027
+ } else if( acf.get('screen') == 'user' ) {
7028
+ this.renderUserScreen( json );
7029
+ }
7030
+
7031
+ // action
7032
+ acf.doAction('check_screen_complete', json, ajaxData);
7033
+ };
7034
+
7035
+ // ajax
7036
+ this.xhr = $.ajax({
7037
+ url: acf.get('ajaxurl'),
7038
+ data: acf.prepareForAjax( ajaxData ),
7039
+ type: 'post',
7040
+ dataType: 'json',
7041
+ context: this,
7042
+ success: onSuccess
7043
+ });
7044
+ },
7045
+
7046
+ onChange: function( e, $el ){
7047
+ this.setTimeout(this.check, 1);
7048
+ },
7049
+
7050
+ renderPostScreen: function( data ){
7051
+
7052
+ // Helper function to copy events
7053
+ var copyEvents = function( $from, $to ){
7054
+ var events = $._data($from[0]).events;
7055
+ for( var type in events ) {
7056
+ for( var i = 0; i < events[type].length; i++ ) {
7057
+ $to.on( type, events[type][i].handler );
7058
+ }
7059
+ }
7060
+ }
7061
+
7062
+ // Helper function to sort metabox.
7063
+ var sortMetabox = function( id, ids ){
7064
+
7065
+ // Find position of id within ids.
7066
+ var index = ids.indexOf( id );
7067
+
7068
+ // Bail early if index not found.
7069
+ if( index == -1 ) {
7070
+ return false;
7071
+ }
7072
+
7073
+ // Loop over metaboxes behind (in reverse order).
7074
+ for( var i = index-1; i >= 0; i-- ) {
7075
+ if( $('#'+ids[i]).length ) {
7076
+ return $('#'+ids[i]).after( $('#'+id) );
7077
+ }
7078
+ }
7079
+
7080
+ // Loop over metaboxes infront.
7081
+ for( var i = index+1; i < ids.length; i++ ) {
7082
+ if( $('#'+ids[i]).length ) {
7083
+ return $('#'+ids[i]).before( $('#'+id) );
7084
+ }
7085
+ }
7086
+
7087
+ // Return false if not sorted.
7088
+ return false;
7089
+ };
7090
+
7091
+ // Keep track of visible and hidden postboxes.
7092
+ data.visible = [];
7093
+ data.hidden = [];
7094
+
7095
+ // Show these postboxes.
7096
+ data.results = data.results.map(function( result, i ){
7097
+
7098
+ // vars
7099
+ var postbox = acf.getPostbox( result.id );
7100
+
7101
+ // Prevent "acf_after_title" position in Block Editor.
7102
+ if( acf.isGutenberg() && result.position == "acf_after_title" ) {
7103
+ result.position = 'normal';
7104
+ }
7105
+
7106
+ // Create postbox if doesn't exist.
7107
+ if( !postbox ) {
7108
+ var wpMinorVersion = parseFloat( acf.get('wp_version') );
7109
+ if( wpMinorVersion >= 5.5 ) {
7110
+ var postboxHeader = [
7111
+ '<div class="postbox-header">',
7112
+ '<h2 class="hndle ui-sortable-handle">',
7113
+ '<span>' + acf.escHtml( result.title ) + '</span>',
7114
+ '</h2>',
7115
+ '<div class="handle-actions hide-if-no-js">',
7116
+ '<button type="button" class="handlediv" aria-expanded="true">',
7117
+ '<span class="screen-reader-text">Toggle panel: ' + acf.escHtml( result.title ) + '</span>',
7118
+ '<span class="toggle-indicator" aria-hidden="true"></span>',
7119
+ '</button>',
7120
+ '</div>',
7121
+ '</div>'
7122
+ ].join('');
7123
+ } else {
7124
+ var postboxHeader = [
7125
+ '<button type="button" class="handlediv" aria-expanded="true">',
7126
+ '<span class="screen-reader-text">Toggle panel: ' + acf.escHtml( result.title ) + '</span>',
7127
+ '<span class="toggle-indicator" aria-hidden="true"></span>',
7128
+ '</button>',
7129
+ '<h2 class="hndle ui-sortable-handle">',
7130
+ '<span>' + acf.escHtml( result.title ) + '</span>',
7131
+ '</h2>',
7132
+ ].join('');
7133
+ }
7134
+
7135
+ // Create it.
7136
+ var $postbox = $([
7137
+ '<div id="' + result.id + '" class="postbox">',
7138
+ postboxHeader,
7139
+ '<div class="inside">',
7140
+ result.html,
7141
+ '</div>',
7142
+ '</div>'
7143
+ ].join(''));
7144
+
7145
+ // Create new hide toggle.
7146
+ if( $('#adv-settings').length ) {
7147
+ var $prefs = $('#adv-settings .metabox-prefs');
7148
+ var $label = $([
7149
+ '<label for="' + result.id + '-hide">',
7150
+ '<input class="hide-postbox-tog" name="' + result.id + '-hide" type="checkbox" id="' + result.id + '-hide" value="' + result.id + '" checked="checked">',
7151
+ ' ' + result.title,
7152
+ '</label>'
7153
+ ].join(''));
7154
+
7155
+ // Copy default WP events onto checkbox.
7156
+ copyEvents( $prefs.find('input').first(), $label.find('input') );
7157
+
7158
+ // Append hide label
7159
+ $prefs.append( $label );
7160
+ }
7161
+
7162
+ // Copy default WP events onto metabox.
7163
+ if( $('.postbox').length ) {
7164
+ copyEvents( $('.postbox .handlediv').first(), $postbox.children('.handlediv') );
7165
+ copyEvents( $('.postbox .hndle').first(), $postbox.children('.hndle') );
7166
+ }
7167
+
7168
+ // Append metabox to the bottom of "side-sortables".
7169
+ if( result.position === 'side' ) {
7170
+ $('#' + result.position + '-sortables').append( $postbox );
7171
+
7172
+ // Prepend metabox to the top of "normal-sortbables".
7173
+ } else {
7174
+ $('#' + result.position + '-sortables').prepend( $postbox );
7175
+ }
7176
+
7177
+ // Position metabox amongst existing ACF metaboxes within the same location.
7178
+ var order = [];
7179
+ data.results.map(function( _result ){
7180
+ if( result.position === _result.position && $('#' + result.position + '-sortables #' + _result.id).length ) {
7181
+ order.push( _result.id );
7182
+ }
7183
+ });
7184
+ sortMetabox(result.id, order)
7185
+
7186
+ // Check 'sorted' for user preference.
7187
+ if( data.sorted ) {
7188
+
7189
+ // Loop over each position (acf_after_title, side, normal).
7190
+ for( var position in data.sorted ) {
7191
+
7192
+ // Explode string into array of ids.
7193
+ var order = data.sorted[position].split(',');
7194
+
7195
+ // Position metabox relative to order.
7196
+ if( sortMetabox(result.id, order) ) {
7197
+ break;
7198
+ }
7199
+ }
7200
+ }
7201
+
7202
+ // Initalize it (modifies HTML).
7203
+ postbox = acf.newPostbox( result );
7204
+
7205
+ // Trigger action.
7206
+ acf.doAction('append', $postbox);
7207
+ acf.doAction('append_postbox', postbox);
7208
+ }
7209
+
7210
+ // show postbox
7211
+ postbox.showEnable();
7212
+
7213
+ // append
7214
+ data.visible.push( result.id );
7215
+
7216
+ // Return result (may have changed).
7217
+ return result;
7218
+ });
7219
+
7220
+ // Hide these postboxes.
7221
+ acf.getPostboxes().map(function( postbox ){
7222
+ if( data.visible.indexOf( postbox.get('id') ) === -1 ) {
7223
+
7224
+ // Hide postbox.
7225
+ postbox.hideDisable();
7226
+
7227
+ // Append to data.
7228
+ data.hidden.push( postbox.get('id') );
7229
+ }
7230
+ });
7231
+
7232
+ // Update style.
7233
+ $('#acf-style').html( data.style );
7234
+
7235
+ // Do action.
7236
+ acf.doAction( 'refresh_post_screen', data );
7237
+ },
7238
+
7239
+ renderUserScreen: function( json ){
7240
+
7241
+ }
7242
+ });
7243
+
7244
+ /**
7245
+ * gutenScreen
7246
+ *
7247
+ * Adds compatibility with the Gutenberg edit screen.
7248
+ *
7249
+ * @date 11/12/18
7250
+ * @since 5.8.0
7251
+ *
7252
+ * @param void
7253
+ * @return void
7254
+ */
7255
+ var gutenScreen = new acf.Model({
7256
+
7257
+ // Keep a reference to the most recent post attributes.
7258
+ postEdits: {},
7259
+
7260
+ // Wait until assets have been loaded.
7261
+ wait: 'prepare',
7262
+
7263
+ initialize: function(){
7264
+
7265
+ // Bail early if not Gutenberg.
7266
+ if( !acf.isGutenberg() ) {
7267
+ return;
7268
+ }
7269
+
7270
+ // Listen for changes (use debounced version as this can fires often).
7271
+ wp.data.subscribe( acf.debounce(this.onChange).bind(this) );
7272
+
7273
+ // Customize "acf.screen.get" functions.
7274
+ acf.screen.getPageTemplate = this.getPageTemplate;
7275
+ acf.screen.getPageParent = this.getPageParent;
7276
+ acf.screen.getPostType = this.getPostType;
7277
+ acf.screen.getPostFormat = this.getPostFormat;
7278
+ acf.screen.getPostCoreTerms = this.getPostCoreTerms;
7279
+
7280
+ // Disable unload
7281
+ acf.unload.disable();
7282
+
7283
+ // Refresh metaboxes since WP 5.3.
7284
+ var wpMinorVersion = parseFloat( acf.get('wp_version') );
7285
+ if( wpMinorVersion >= 5.3 ) {
7286
+ this.addAction( 'refresh_post_screen', this.onRefreshPostScreen );
7287
+ }
7288
+
7289
+ // Trigger "refresh" after WP has moved metaboxes into place.
7290
+ wp.domReady( acf.refresh );
7291
+ },
7292
+
7293
+ onChange: function(){
7294
+
7295
+ // Determine attributes that can trigger a refresh.
7296
+ var attributes = [ 'template', 'parent', 'format' ];
7297
+
7298
+ // Append taxonomy attribute names to this list.
7299
+ ( wp.data.select( 'core' ).getTaxonomies() || [] ).map(function( taxonomy ){
7300
+ attributes.push( taxonomy.rest_base );
7301
+ });
7302
+
7303
+ // Get relevant current post edits.
7304
+ var _postEdits = wp.data.select( 'core/editor' ).getPostEdits();
7305
+ var postEdits = {};
7306
+ attributes.map(function( k ){
7307
+ if( _postEdits[k] !== undefined ) {
7308
+ postEdits[k] = _postEdits[k];
7309
+ }
7310
+ });
7311
+
7312
+ // Detect change.
7313
+ if( JSON.stringify(postEdits) !== JSON.stringify(this.postEdits) ) {
7314
+ this.postEdits = postEdits;
7315
+
7316
+ // Check screen.
7317
+ acf.screen.check();
7318
+ }
7319
+ },
7320
+
7321
+ getPageTemplate: function(){
7322
+ return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'template' );
7323
+ },
7324
+
7325
+ getPageParent: function( e, $el ){
7326
+ return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'parent' );
7327
+ },
7328
+
7329
+ getPostType: function(){
7330
+ return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'type' );
7331
+ },
7332
+
7333
+ getPostFormat: function( e, $el ){
7334
+ return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'format' );
7335
+ },
7336
+
7337
+ getPostCoreTerms: function(){
7338
+
7339
+ // vars
7340
+ var terms = {};
7341
+
7342
+ // Loop over taxonomies.
7343
+ var taxonomies = wp.data.select( 'core' ).getTaxonomies() || [];
7344
+ taxonomies.map(function( taxonomy ){
7345
+
7346
+ // Append selected taxonomies to terms object.
7347
+ var postTerms = wp.data.select( 'core/editor' ).getEditedPostAttribute( taxonomy.rest_base );
7348
+ if( postTerms ) {
7349
+ terms[ taxonomy.slug ] = postTerms;
7350
+ }
7351
+ });
7352
+
7353
+ // return
7354
+ return terms;
7355
+ },
7356
+
7357
+ /**
7358
+ * onRefreshPostScreen
7359
+ *
7360
+ * Fires after the Post edit screen metaboxs are refreshed to update the Block Editor API state.
7361
+ *
7362
+ * @date 11/11/19
7363
+ * @since 5.8.7
7364
+ *
7365
+ * @param object data The "check_screen" JSON response data.
7366
+ * @return void
7367
+ */
7368
+ onRefreshPostScreen: function( data ) {
7369
+
7370
+ // Extract vars.
7371
+ var select = wp.data.select( 'core/edit-post' );
7372
+ var dispatch = wp.data.dispatch( 'core/edit-post' );
7373
+
7374
+ // Load current metabox locations and data.
7375
+ var locations = {};
7376
+ select.getActiveMetaBoxLocations().map(function( location ){
7377
+ locations[ location ] = select.getMetaBoxesPerLocation( location );
7378
+ });
7379
+
7380
+ // Generate flat array of existing ids.
7381
+ var ids = [];
7382
+ for( var k in locations ) {
7383
+ locations[k].map(function( m ){
7384
+ ids.push( m.id );
7385
+ });
7386
+ }
7387
+
7388
+ // Append new ACF metaboxes (ignore those which already exist).
7389
+ data.results.filter(function( r ){
7390
+ return ( ids.indexOf( r.id ) === -1 );
7391
+ }).map(function( result, i ){
7392
+
7393
+ // Ensure location exists.
7394
+ var location = result.position;
7395
+ locations[ location ] = locations[ location ] || [];
7396
+
7397
+ // Append.
7398
+ locations[ location ].push({
7399
+ id: result.id,
7400
+ title: result.title
7401
+ });
7402
+ });
7403
+
7404
+ // Remove hidden ACF metaboxes.
7405
+ for( var k in locations ) {
7406
+ locations[k] = locations[k].filter(function( m ){
7407
+ return ( data.hidden.indexOf( m.id ) === -1 );
7408
+ });
7409
+ }
7410
+
7411
+ // Update state.
7412
+ dispatch.setAvailableMetaBoxesPerLocation( locations );
7413
+ }
7414
+ });
7415
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7416
  })(jQuery);
7417
+ (function($, undefined){
7418
+
7419
+ /**
7420
+ * acf.newSelect2
7421
+ *
7422
+ * description
7423
+ *
7424
+ * @date 13/1/18
7425
+ * @since 5.6.5
7426
+ *
7427
+ * @param type $var Description. Default.
7428
+ * @return type Description.
7429
+ */
7430
+
7431
+ acf.newSelect2 = function( $select, props ){
7432
+
7433
+ // defaults
7434
+ props = acf.parseArgs(props, {
7435
+ allowNull: false,
7436
+ placeholder: '',
7437
+ multiple: false,
7438
+ field: false,
7439
+ ajax: false,
7440
+ ajaxAction: '',
7441
+ ajaxData: function( data ){ return data; },
7442
+ ajaxResults: function( json ){ return json; },
7443
+ });
7444
+
7445
+ // initialize
7446
+ if( getVersion() == 4 ) {
7447
+ var select2 = new Select2_4( $select, props );
7448
+ } else {
7449
+ var select2 = new Select2_3( $select, props );
7450
+ }
7451
+
7452
+ // actions
7453
+ acf.doAction('new_select2', select2);
7454
+
7455
+ // return
7456
+ return select2;
7457
+ };
7458
+
7459
+ /**
7460
+ * getVersion
7461
+ *
7462
+ * description
7463
+ *
7464
+ * @date 13/1/18
7465
+ * @since 5.6.5
7466
+ *
7467
+ * @param type $var Description. Default.
7468
+ * @return type Description.
7469
+ */
7470
+
7471
+ function getVersion() {
7472
+
7473
+ // v4
7474
+ if( acf.isset(window, 'jQuery', 'fn', 'select2', 'amd') ) {
7475
+ return 4;
7476
+ }
7477
+
7478
+ // v3
7479
+ if( acf.isset(window, 'Select2') ) {
7480
+ return 3;
7481
+ }
7482
+
7483
+ // return
7484
+ return false;
7485
+ }
7486
+
7487
+ /**
7488
+ * Select2
7489
+ *
7490
+ * description
7491
+ *
7492
+ * @date 13/1/18
7493
+ * @since 5.6.5
7494
+ *
7495
+ * @param type $var Description. Default.
7496
+ * @return type Description.
7497
+ */
7498
+
7499
+ var Select2 = acf.Model.extend({
7500
+
7501
+ setup: function( $select, props ){
7502
+ $.extend(this.data, props);
7503
+ this.$el = $select;
7504
+ },
7505
+
7506
+ initialize: function(){
7507
+
7508
+ },
7509
+
7510
+ selectOption: function( value ){
7511
+ var $option = this.getOption( value );
7512
+ if( !$option.prop('selected') ) {
7513
+ $option.prop('selected', true).trigger('change');
7514
+ }
7515
+ },
7516
+
7517
+ unselectOption: function( value ){
7518
+ var $option = this.getOption( value );
7519
+ if( $option.prop('selected') ) {
7520
+ $option.prop('selected', false).trigger('change');
7521
+ }
7522
+ },
7523
+
7524
+ getOption: function( value ){
7525
+ return this.$('option[value="' + value + '"]');
7526
+ },
7527
+
7528
+ addOption: function( option ){
7529
+
7530
+ // defaults
7531
+ option = acf.parseArgs(option, {
7532
+ id: '',
7533
+ text: '',
7534
+ selected: false
7535
+ });
7536
+
7537
+ // vars
7538
+ var $option = this.getOption( option.id );
7539
+
7540
+ // append
7541
+ if( !$option.length ) {
7542
+ $option = $('<option></option>');
7543
+ $option.html( option.text );
7544
+ $option.attr('value', option.id);
7545
+ $option.prop('selected', option.selected);
7546
+ this.$el.append($option);
7547
+ }
7548
+
7549
+ // chain
7550
+ return $option;
7551
+ },
7552
+
7553
+ getValue: function(){
7554
+
7555
+ // vars
7556
+ var val = [];
7557
+ var $options = this.$el.find('option:selected');
7558
+
7559
+ // bail early if no selected
7560
+ if( !$options.exists() ) {
7561
+ return val;
7562
+ }
7563
+
7564
+ // sort by attribute
7565
+ $options = $options.sort(function(a, b) {
7566
+ return +a.getAttribute('data-i') - +b.getAttribute('data-i');
7567
+ });
7568
+
7569
+ // loop
7570
+ $options.each(function(){
7571
+ var $el = $(this);
7572
+ val.push({
7573
+ $el: $el,
7574
+ id: $el.attr('value'),
7575
+ text: $el.text(),
7576
+ });
7577
+ });
7578
+
7579
+ // return
7580
+ return val;
7581
+
7582
+ },
7583
+
7584
+ mergeOptions: function(){
7585
+
7586
+ },
7587
+
7588
+ getChoices: function(){
7589
+
7590
+ // callback
7591
+ var crawl = function( $parent ){
7592
+
7593
+ // vars
7594
+ var choices = [];
7595
+
7596
+ // loop
7597
+ $parent.children().each(function(){
7598
+
7599
+ // vars
7600
+ var $child = $(this);
7601
+
7602
+ // optgroup
7603
+ if( $child.is('optgroup') ) {
7604
+
7605
+ choices.push({
7606
+ text: $child.attr('label'),
7607
+ children: crawl( $child )
7608
+ });
7609
+
7610
+ // option
7611
+ } else {
7612
+
7613
+ choices.push({
7614
+ id: $child.attr('value'),
7615
+ text: $child.text()
7616
+ });
7617
+ }
7618
+ });
7619
+
7620
+ // return
7621
+ return choices;
7622
+ };
7623
+
7624
+ // crawl
7625
+ return crawl( this.$el );
7626
+ },
7627
+
7628
+ getAjaxData: function( params ){
7629
+
7630
+ // vars
7631
+ var ajaxData = {
7632
+ action: this.get('ajaxAction'),
7633
+ s: params.term || '',
7634
+ paged: params.page || 1
7635
+ };
7636
+
7637
+ // field helper
7638
+ var field = this.get('field');
7639
+ if( field ) {
7640
+ ajaxData.field_key = field.get('key');
7641
+ }
7642
+
7643
+ // callback
7644
+ var callback = this.get('ajaxData');
7645
+ if( callback ) {
7646
+ ajaxData = callback.apply( this, [ajaxData, params] );
7647
+ }
7648
+
7649
+ // filter
7650
+ ajaxData = acf.applyFilters( 'select2_ajax_data', ajaxData, this.data, this.$el, (field || false), this );
7651
+
7652
+ // return
7653
+ return acf.prepareForAjax(ajaxData);
7654
+ },
7655
+
7656
+ getAjaxResults: function( json, params ){
7657
+
7658
+ // defaults
7659
+ json = acf.parseArgs(json, {
7660
+ results: false,
7661
+ more: false,
7662
+ });
7663
+
7664
+ // callback
7665
+ var callback = this.get('ajaxResults');
7666
+ if( callback ) {
7667
+ json = callback.apply( this, [json, params] );
7668
+ }
7669
+
7670
+ // filter
7671
+ json = acf.applyFilters( 'select2_ajax_results', json, params, this );
7672
+
7673
+ // return
7674
+ return json;
7675
+ },
7676
+
7677
+ processAjaxResults: function( json, params ){
7678
+
7679
+ // vars
7680
+ var json = this.getAjaxResults( json, params );
7681
+
7682
+ // change more to pagination
7683
+ if( json.more ) {
7684
+ json.pagination = { more: true };
7685
+ }
7686
+
7687
+ // merge together groups
7688
+ setTimeout($.proxy(this.mergeOptions, this), 1);
7689
+
7690
+ // return
7691
+ return json;
7692
+ },
7693
+
7694
+ destroy: function(){
7695
+
7696
+ // destroy via api
7697
+ if( this.$el.data('select2') ) {
7698
+ this.$el.select2('destroy');
7699
+ }
7700
+
7701
+ // destory via HTML (duplicating HTML does not contain data)
7702
+ this.$el.siblings('.select2-container').remove();
7703
+ }
7704
+
7705
+ });
7706
+
7707
+
7708
+ /**
7709
+ * Select2_4
7710
+ *
7711
+ * description
7712
+ *
7713
+ * @date 13/1/18
7714
+ * @since 5.6.5
7715
+ *
7716
+ * @param type $var Description. Default.
7717
+ * @return type Description.
7718
+ */
7719
+
7720
+ var Select2_4 = Select2.extend({
7721
+
7722
+ initialize: function(){
7723
+
7724
+ // vars
7725
+ var $select = this.$el;
7726
+ var options = {
7727
+ width: '100%',
7728
+ allowClear: this.get('allowNull'),
7729
+ placeholder: this.get('placeholder'),
7730
+ multiple: this.get('multiple'),
7731
+ data: [],
7732
+ escapeMarkup: function( string ){
7733
+ return acf.escHtml( string );
7734
+ },
7735
+ };
7736
+
7737
+ // multiple
7738
+ if( options.multiple ) {
7739
+
7740
+ // reorder options
7741
+ this.getValue().map(function( item ){
7742
+ item.$el.detach().appendTo( $select );
7743
+ });
7744
+ }
7745
+
7746
+ // Temporarily remove conflicting attribute.
7747
+ var attrAjax = $select.attr( 'data-ajax' );
7748
+ if( attrAjax !== undefined ) {
7749
+ $select.removeData('ajax');
7750
+ $select.removeAttr('data-ajax');
7751
+ }
7752
+
7753
+ // ajax
7754
+ if( this.get('ajax') ) {
7755
+
7756
+ options.ajax = {
7757
+ url: acf.get('ajaxurl'),
7758
+ delay: 250,
7759
+ dataType: 'json',
7760
+ type: 'post',
7761
+ cache: false,
7762
+ data: $.proxy(this.getAjaxData, this),
7763
+ processResults: $.proxy(this.processAjaxResults, this),
7764
+ };
7765
+ }
7766
+
7767
+ // filter for 3rd party customization
7768
+ //options = acf.applyFilters( 'select2_args', options, $select, this );
7769
+ var field = this.get('field');
7770
+ options = acf.applyFilters( 'select2_args', options, $select, this.data, (field || false), this );
7771
+
7772
+ // add select2
7773
+ $select.select2( options );
7774
+
7775
+ // get container (Select2 v4 does not return this from constructor)
7776
+ var $container = $select.next('.select2-container');
7777
+
7778
+ // multiple
7779
+ if( options.multiple ) {
7780
+
7781
+ // vars
7782
+ var $ul = $container.find('ul');
7783
+
7784
+ // sortable
7785
+ $ul.sortable({
7786
+ stop: function( e ) {
7787
+
7788
+ // loop
7789
+ $ul.find('.select2-selection__choice').each(function() {
7790
+
7791
+ // vars
7792
+ var $option = $( $(this).data('data').element );
7793
+
7794
+ // detach and re-append to end
7795
+ $option.detach().appendTo( $select );
7796
+ });
7797
+
7798
+ // trigger change on input (JS error if trigger on select)
7799
+ $select.trigger('change');
7800
+ }
7801
+ });
7802
+
7803
+ // on select, move to end
7804
+ $select.on('select2:select', this.proxy(function( e ){
7805
+ this.getOption( e.params.data.id ).detach().appendTo( this.$el );
7806
+ }));
7807
+ }
7808
+
7809
+ // add class
7810
+ $container.addClass('-acf');
7811
+
7812
+ // Add back temporarily removed attr.
7813
+ if( attrAjax !== undefined ) {
7814
+ $select.attr('data-ajax', attrAjax);
7815
+ }
7816
+
7817
+ // action for 3rd party customization
7818
+ acf.doAction('select2_init', $select, options, this.data, (field || false), this);
7819
+ },
7820
+
7821
+ mergeOptions: function(){
7822
+
7823
+ // vars
7824
+ var $prevOptions = false;
7825
+ var $prevGroup = false;
7826
+
7827
+ // loop
7828
+ $('.select2-results__option[role="group"]').each(function(){
7829
+
7830
+ // vars
7831
+ var $options = $(this).children('ul');
7832
+ var $group = $(this).children('strong');
7833
+
7834
+ // compare to previous
7835
+ if( $prevGroup && $prevGroup.text() === $group.text() ) {
7836
+ $prevOptions.append( $options.children() );
7837
+ $(this).remove();
7838
+ return;
7839
+ }
7840
+
7841
+ // update vars
7842
+ $prevOptions = $options;
7843
+ $prevGroup = $group;
7844
+
7845
+ });
7846
+ },
7847
+
7848
+ });
7849
+
7850
+ /**
7851
+ * Select2_3
7852
+ *
7853
+ * description
7854
+ *
7855
+ * @date 13/1/18
7856
+ * @since 5.6.5
7857
+ *
7858
+ * @param type $var Description. Default.
7859
+ * @return type Description.
7860
+ */
7861
+
7862
+ var Select2_3 = Select2.extend({
7863
+
7864
+ initialize: function(){
7865
+
7866
+ // vars
7867
+ var $select = this.$el;
7868
+ var value = this.getValue();
7869
+ var multiple = this.get('multiple');
7870
+ var options = {
7871
+ width: '100%',
7872
+ allowClear: this.get('allowNull'),
7873
+ placeholder: this.get('placeholder'),
7874
+ separator: '||',
7875
+ multiple: this.get('multiple'),
7876
+ data: this.getChoices(),
7877
+ escapeMarkup: function( string ){
7878
+ return acf.escHtml( string );
7879
+ },
7880
+ dropdownCss: {
7881
+ 'z-index': '999999999'
7882
+ },
7883
+ initSelection: function( element, callback ) {
7884
+ if( multiple ) {
7885
+ callback( value );
7886
+ } else {
7887
+ callback( value.shift() );
7888
+ }
7889
+ }
7890
+ };
7891
+
7892
+ // get hidden input
7893
+ var $input = $select.siblings('input');
7894
+ if( !$input.length ) {
7895
+ $input = $('<input type="hidden" />');
7896
+ $select.before( $input );
7897
+ }
7898
+
7899
+ // set input value
7900
+ inputValue = value.map(function(item){ return item.id }).join('||');
7901
+ $input.val( inputValue );
7902
+
7903
+ // multiple
7904
+ if( options.multiple ) {
7905
+
7906
+ // reorder options
7907
+ value.map(function( item ){
7908
+ item.$el.detach().appendTo( $select );
7909
+ });
7910
+ }
7911
+
7912
+ // remove blank option as we have a clear all button
7913
+ if( options.allowClear ) {
7914
+ options.data = options.data.filter(function(item){
7915
+ return item.id !== '';
7916
+ });
7917
+ }
7918
+
7919
+ // remove conflicting atts
7920
+ $select.removeData('ajax');
7921
+ $select.removeAttr('data-ajax');
7922
+
7923
+ // ajax
7924
+ if( this.get('ajax') ) {
7925
+
7926
+ options.ajax = {
7927
+ url: acf.get('ajaxurl'),
7928
+ quietMillis: 250,
7929
+ dataType: 'json',
7930
+ type: 'post',
7931
+ cache: false,
7932
+ data: $.proxy(this.getAjaxData, this),
7933
+ results: $.proxy(this.processAjaxResults, this),
7934
+ };
7935
+ }
7936
+
7937
+ // filter for 3rd party customization
7938
+ var field = this.get('field');
7939
+ options = acf.applyFilters( 'select2_args', options, $select, this.data, (field || false), this );
7940
+
7941
+ // add select2
7942
+ $input.select2( options );
7943
+
7944
+ // get container
7945
+ var $container = $input.select2('container');
7946
+
7947
+ // helper to find this select's option
7948
+ var getOption = $.proxy(this.getOption, this);
7949
+
7950
+ // multiple
7951
+ if( options.multiple ) {
7952
+
7953
+ // vars
7954
+ var $ul = $container.find('ul');
7955
+
7956
+ // sortable
7957
+ $ul.sortable({
7958
+ stop: function() {
7959
+
7960
+ // loop
7961
+ $ul.find('.select2-search-choice').each(function() {
7962
+
7963
+ // vars
7964
+ var data = $(this).data('select2Data');
7965
+ var $option = getOption( data.id );
7966
+
7967
+ // detach and re-append to end
7968
+ $option.detach().appendTo( $select );
7969
+ });
7970
+
7971
+ // trigger change on input (JS error if trigger on select)
7972
+ $select.trigger('change');
7973
+ }
7974
+ });
7975
+ }
7976
+
7977
+ // on select, create option and move to end
7978
+ $input.on('select2-selecting', function( e ){
7979
+
7980
+ // vars
7981
+ var item = e.choice;
7982
+ var $option = getOption( item.id );
7983
+
7984
+ // create if doesn't exist
7985
+ if( !$option.length ) {
7986
+ $option = $('<option value="' + item.id + '">' + item.text + '</option>');
7987
+ }
7988
+
7989
+ // detach and re-append to end
7990
+ $option.detach().appendTo( $select );
7991
+ });
7992
+
7993
+ // add class
7994
+ $container.addClass('-acf');
7995
+
7996
+ // action for 3rd party customization
7997
+ acf.doAction('select2_init', $select, options, this.data, (field || false), this);
7998
+
7999
+ // change
8000
+ $input.on('change', function(){
8001
+ var val = $input.val();
8002
+ if( val.indexOf('||') ) {
8003
+ val = val.split('||');
8004
+ }
8005
+ $select.val( val ).trigger('change');
8006
+ });
8007
+
8008
+ // hide select
8009
+ $select.hide();
8010
+ },
8011
+
8012
+ mergeOptions: function(){
8013
+
8014
+ // vars
8015
+ var $prevOptions = false;
8016
+ var $prevGroup = false;
8017
+
8018
+ // loop
8019
+ $('#select2-drop .select2-result-with-children').each(function(){
8020
+
8021
+ // vars
8022
+ var $options = $(this).children('ul');
8023
+ var $group = $(this).children('.select2-result-label');
8024
+
8025
+ // compare to previous
8026
+ if( $prevGroup && $prevGroup.text() === $group.text() ) {
8027
+ $prevGroup.append( $options.children() );
8028
+ $(this).remove();
8029
+ return;
8030
+ }
8031
+
8032
+ // update vars
8033
+ $prevOptions = $options;
8034
+ $prevGroup = $group;
8035
+
8036
+ });
8037
+
8038
+ },
8039
+
8040
+ getAjaxData: function( term, page ){
8041
+
8042
+ // create Select2 v4 params
8043
+ var params = {
8044
+ term: term,
8045
+ page: page
8046
+ }
8047
+
8048
+ // return
8049
+ return Select2.prototype.getAjaxData.apply(this, [params]);
8050
+ },
8051
+
8052
+ });
8053
+
8054
+
8055
+ // manager
8056
+ var select2Manager = new acf.Model({
8057
+ priority: 5,
8058
+ wait: 'prepare',
8059
+ actions: {
8060
+ 'duplicate': 'onDuplicate'
8061
+ },
8062
+ initialize: function(){
8063
+
8064
+ // vars
8065
+ var locale = acf.get('locale');
8066
+ var rtl = acf.get('rtl');
8067
+ var l10n = acf.get('select2L10n');
8068
+ var version = getVersion();
8069
+
8070
+ // bail ealry if no l10n
8071
+ if( !l10n ) {
8072
+ return false;
8073
+ }
8074
+
8075
+ // bail early if 'en'
8076
+ if( locale.indexOf('en') === 0 ) {
8077
+ return false;
8078
+ }
8079
+
8080
+ // initialize
8081
+ if( version == 4 ) {
8082
+ this.addTranslations4();
8083
+ } else if( version == 3 ) {
8084
+ this.addTranslations3();
8085
+ }
8086
+ },
8087
+
8088
+ addTranslations4: function(){
8089
+
8090
+ // vars
8091
+ var l10n = acf.get('select2L10n');
8092
+ var locale = acf.get('locale');
8093
+
8094
+ // modify local to match html[lang] attribute (used by Select2)
8095
+ locale = locale.replace('_', '-');
8096
+
8097
+ // select2L10n
8098
+ var select2L10n = {
8099
+ errorLoading: function () {
8100
+ return l10n.load_fail;
8101
+ },
8102
+ inputTooLong: function (args) {
8103
+ var overChars = args.input.length - args.maximum;
8104
+ if( overChars > 1 ) {
8105
+ return l10n.input_too_long_n.replace( '%d', overChars );
8106
+ }
8107
+ return l10n.input_too_long_1;
8108
+ },
8109
+ inputTooShort: function( args ){
8110
+ var remainingChars = args.minimum - args.input.length;
8111
+ if( remainingChars > 1 ) {
8112
+ return l10n.input_too_short_n.replace( '%d', remainingChars );
8113
+ }
8114
+ return l10n.input_too_short_1;
8115
+ },
8116
+ loadingMore: function () {
8117
+ return l10n.load_more;
8118
+ },
8119
+ maximumSelected: function( args ) {
8120
+ var maximum = args.maximum;
8121
+ if( maximum > 1 ) {
8122
+ return l10n.selection_too_long_n.replace( '%d', maximum );
8123
+ }
8124
+ return l10n.selection_too_long_1;
8125
+ },
8126
+ noResults: function () {
8127
+ return l10n.matches_0;
8128
+ },
8129
+ searching: function () {
8130
+ return l10n.searching;
8131
+ }
8132
+ };
8133
+
8134
+ // append
8135
+ jQuery.fn.select2.amd.define('select2/i18n/' + locale, [], function(){
8136
+ return select2L10n;
8137
+ });
8138
+ },
8139
+
8140
+ addTranslations3: function(){
8141
+
8142
+ // vars
8143
+ var l10n = acf.get('select2L10n');
8144
+ var locale = acf.get('locale');
8145
+
8146
+ // modify local to match html[lang] attribute (used by Select2)
8147
+ locale = locale.replace('_', '-');
8148
+
8149
+ // select2L10n
8150
+ var select2L10n = {
8151
+ formatMatches: function( matches ) {
8152
+ if( matches > 1 ) {
8153
+ return l10n.matches_n.replace( '%d', matches );
8154
+ }
8155
+ return l10n.matches_1;
8156
+ },
8157
+ formatNoMatches: function() {
8158
+ return l10n.matches_0;
8159
+ },
8160
+ formatAjaxError: function() {
8161
+ return l10n.load_fail;
8162
+ },
8163
+ formatInputTooShort: function( input, min ) {
8164
+ var remainingChars = min - input.length;
8165
+ if( remainingChars > 1 ) {
8166
+ return l10n.input_too_short_n.replace( '%d', remainingChars );
8167
+ }
8168
+ return l10n.input_too_short_1;
8169
+ },
8170
+ formatInputTooLong: function( input, max ) {
8171
+ var overChars = input.length - max;
8172
+ if( overChars > 1 ) {
8173
+ return l10n.input_too_long_n.replace( '%d', overChars );
8174
+ }
8175
+ return l10n.input_too_long_1;
8176
+ },
8177
+ formatSelectionTooBig: function( maximum ) {
8178
+ if( maximum > 1 ) {
8179
+ return l10n.selection_too_long_n.replace( '%d', maximum );
8180
+ }
8181
+ return l10n.selection_too_long_1;
8182
+ },
8183
+ formatLoadMore: function() {
8184
+ return l10n.load_more;
8185
+ },
8186
+ formatSearching: function() {
8187
+ return l10n.searching;
8188
+ }
8189
+ };
8190
+
8191
+ // ensure locales exists
8192
+ $.fn.select2.locales = $.fn.select2.locales || {};
8193
+
8194
+ // append
8195
+ $.fn.select2.locales[ locale ] = select2L10n;
8196
+ $.extend($.fn.select2.defaults, select2L10n);
8197
+ },
8198
+
8199
+ onDuplicate: function( $el, $el2 ){
8200
+ $el2.find('.select2-container').remove();
8201
+ }
8202
+
8203
+ });
8204
+
8205
  })(jQuery);
8206
+ (function($, undefined){
8207
+
8208
+ acf.tinymce = {
8209
+
8210
+ /*
8211
+ * defaults
8212
+ *
8213
+ * This function will return default mce and qt settings
8214
+ *
8215
+ * @type function
8216
+ * @date 18/8/17
8217
+ * @since 5.6.0
8218
+ *
8219
+ * @param $post_id (int)
8220
+ * @return $post_id (int)
8221
+ */
8222
+
8223
+ defaults: function(){
8224
+
8225
+ // bail early if no tinyMCEPreInit
8226
+ if( typeof tinyMCEPreInit === 'undefined' ) return false;
8227
+
8228
+ // vars
8229
+ var defaults = {
8230
+ tinymce: tinyMCEPreInit.mceInit.acf_content,
8231
+ quicktags: tinyMCEPreInit.qtInit.acf_content
8232
+ };
8233
+
8234
+ // return
8235
+ return defaults;
8236
+ },
8237
+
8238
+
8239
+ /*
8240
+ * initialize
8241
+ *
8242
+ * This function will initialize the tinymce and quicktags instances
8243
+ *
8244
+ * @type function
8245
+ * @date 18/8/17
8246
+ * @since 5.6.0
8247
+ *
8248
+ * @param $post_id (int)
8249
+ * @return $post_id (int)
8250
+ */
8251
+
8252
+ initialize: function( id, args ){
8253
+
8254
+ // defaults
8255
+ args = acf.parseArgs(args, {
8256
+ tinymce: true,
8257
+ quicktags: true,
8258
+ toolbar: 'full',
8259
+ mode: 'visual', // visual,text
8260
+ field: false
8261
+ });
8262
+
8263
+ // tinymce
8264
+ if( args.tinymce ) {
8265
+ this.initializeTinymce( id, args );
8266
+ }
8267
+
8268
+ // quicktags
8269
+ if( args.quicktags ) {
8270
+ this.initializeQuicktags( id, args );
8271
+ }
8272
+ },
8273
+
8274
+
8275
+ /*
8276
+ * initializeTinymce
8277
+ *
8278
+ * This function will initialize the tinymce instance
8279
+ *
8280
+ * @type function
8281
+ * @date 18/8/17
8282
+ * @since 5.6.0
8283
+ *
8284
+ * @param $post_id (int)
8285
+ * @return $post_id (int)
8286
+ */
8287
+
8288
+ initializeTinymce: function( id, args ){
8289
+
8290
+ // vars
8291
+ var $textarea = $('#'+id);
8292
+ var defaults = this.defaults();
8293
+ var toolbars = acf.get('toolbars');
8294
+ var field = args.field || false;
8295
+ var $field = field.$el || false;
8296
+
8297
+ // bail early
8298
+ if( typeof tinymce === 'undefined' ) return false;
8299
+ if( !defaults ) return false;
8300
+
8301
+ // check if exists
8302
+ if( tinymce.get(id) ) {
8303
+ return this.enable( id );
8304
+ }
8305
+
8306
+ // settings
8307
+ var init = $.extend( {}, defaults.tinymce, args.tinymce );
8308
+ init.id = id;
8309
+ init.selector = '#' + id;
8310
+
8311
+ // toolbar
8312
+ var toolbar = args.toolbar;
8313
+ if( toolbar && toolbars && toolbars[toolbar] ) {
8314
+
8315
+ for( var i = 1; i <= 4; i++ ) {
8316
+ init[ 'toolbar' + i ] = toolbars[toolbar][i] || '';
8317
+ }
8318
+ }
8319
+
8320
+ // event
8321
+ init.setup = function( ed ){
8322
+
8323
+ ed.on('change', function(e) {
8324
+ ed.save(); // save to textarea
8325
+ $textarea.trigger('change');
8326
+ });
8327
+
8328
+ // Fix bug where Gutenberg does not hear "mouseup" event and tries to select multiple blocks.
8329
+ ed.on('mouseup', function(e) {
8330
+ var event = new MouseEvent('mouseup');
8331
+ window.dispatchEvent(event);
8332
+ });
8333
+
8334
+ // Temporarily comment out. May not be necessary due to wysiwyg field actions.
8335
+ //ed.on('unload', function(e) {
8336
+ // acf.tinymce.remove( id );
8337
+ //});
8338
+ };
8339
+
8340
+ // disable wp_autoresize_on (no solution yet for fixed toolbar)
8341
+ init.wp_autoresize_on = false;
8342
+
8343
+ // Enable wpautop allowing value to save without <p> tags.
8344
+ // Only if the "TinyMCE Advanced" plugin hasn't already set this functionality.
8345
+ if( !init.tadv_noautop ) {
8346
+ init.wpautop = true;
8347
+ }
8348
+
8349
+ // hook for 3rd party customization
8350
+ init = acf.applyFilters('wysiwyg_tinymce_settings', init, id, field);
8351
+
8352
+ // z-index fix (caused too many conflicts)
8353
+ //if( acf.isset(tinymce,'ui','FloatPanel') ) {
8354
+ // tinymce.ui.FloatPanel.zIndex = 900000;
8355
+ //}
8356
+
8357
+ // store settings
8358
+ tinyMCEPreInit.mceInit[ id ] = init;
8359
+
8360
+ // visual tab is active
8361
+ if( args.mode == 'visual' ) {
8362
+
8363
+ // init
8364
+ var result = tinymce.init( init );
8365
+
8366
+ // get editor
8367
+ var ed = tinymce.get( id );
8368
+
8369
+ // validate
8370
+ if( !ed ) {
8371
+ return false;
8372
+ }
8373
+
8374
+ // add reference
8375
+ ed.acf = args.field;
8376
+
8377
+ // action
8378
+ acf.doAction('wysiwyg_tinymce_init', ed, ed.id, init, field);
8379
+ }
8380
+ },
8381
+
8382
+ /*
8383
+ * initializeQuicktags
8384
+ *
8385
+ * This function will initialize the quicktags instance
8386
+ *
8387
+ * @type function
8388
+ * @date 18/8/17
8389
+ * @since 5.6.0
8390
+ *
8391
+ * @param $post_id (int)
8392
+ * @return $post_id (int)
8393
+ */
8394
+
8395
+ initializeQuicktags: function( id, args ){
8396
+
8397
+ // vars
8398
+ var defaults = this.defaults();
8399
+
8400
+ // bail early
8401
+ if( typeof quicktags === 'undefined' ) return false;
8402
+ if( !defaults ) return false;
8403
+
8404
+ // settings
8405
+ var init = $.extend( {}, defaults.quicktags, args.quicktags );
8406
+ init.id = id;
8407
+
8408
+ // filter
8409
+ var field = args.field || false;
8410
+ var $field = field.$el || false;
8411
+ init = acf.applyFilters('wysiwyg_quicktags_settings', init, init.id, field);
8412
+
8413
+ // store settings
8414
+ tinyMCEPreInit.qtInit[ id ] = init;
8415
+
8416
+ // init
8417
+ var ed = quicktags( init );
8418
+
8419
+ // validate
8420
+ if( !ed ) {
8421
+ return false;
8422
+ }
8423
+
8424
+ // generate HTML
8425
+ this.buildQuicktags( ed );
8426
+
8427
+ // action for 3rd party customization
8428
+ acf.doAction('wysiwyg_quicktags_init', ed, ed.id, init, field);
8429
+ },
8430
+
8431
+
8432
+ /*
8433
+ * buildQuicktags
8434
+ *
8435
+ * This function will build the quicktags HTML
8436
+ *
8437
+ * @type function
8438
+ * @date 18/8/17
8439
+ * @since 5.6.0
8440
+ *
8441
+ * @param $post_id (int)
8442
+ * @return $post_id (int)
8443
+ */
8444
+
8445
+ buildQuicktags: function( ed ){
8446
+
8447
+ var canvas, name, settings, theButtons, html, ed, id, i, use, instanceId,
8448
+ defaults = ',strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,';
8449
+
8450
+ canvas = ed.canvas;
8451
+ name = ed.name;
8452
+ settings = ed.settings;
8453
+ html = '';
8454
+ theButtons = {};
8455
+ use = '';
8456
+ instanceId = ed.id;
8457
+
8458
+ // set buttons
8459
+ if ( settings.buttons ) {
8460
+ use = ','+settings.buttons+',';
8461
+ }
8462
+
8463
+ for ( i in edButtons ) {
8464
+ if ( ! edButtons[i] ) {
8465
+ continue;
8466
+ }
8467
+
8468
+ id = edButtons[i].id;
8469
+ if ( use && defaults.indexOf( ',' + id + ',' ) !== -1 && use.indexOf( ',' + id + ',' ) === -1 ) {
8470
+ continue;
8471
+ }
8472
+
8473
+ if ( ! edButtons[i].instance || edButtons[i].instance === instanceId ) {
8474
+ theButtons[id] = edButtons[i];
8475
+
8476
+ if ( edButtons[i].html ) {
8477
+ html += edButtons[i].html( name + '_' );
8478
+ }
8479
+ }
8480
+ }
8481
+
8482
+ if ( use && use.indexOf(',dfw,') !== -1 ) {
8483
+ theButtons.dfw = new QTags.DFWButton();
8484
+ html += theButtons.dfw.html( name + '_' );
8485
+ }
8486
+
8487
+ if ( 'rtl' === document.getElementsByTagName( 'html' )[0].dir ) {
8488
+ theButtons.textdirection = new QTags.TextDirectionButton();
8489
+ html += theButtons.textdirection.html( name + '_' );
8490
+ }
8491
+
8492
+ ed.toolbar.innerHTML = html;
8493
+ ed.theButtons = theButtons;
8494
+
8495
+ if ( typeof jQuery !== 'undefined' ) {
8496
+ jQuery( document ).triggerHandler( 'quicktags-init', [ ed ] );
8497
+ }
8498
+
8499
+ },
8500
+
8501
+ disable: function( id ){
8502
+ this.destroyTinymce( id );
8503
+ },
8504
+
8505
+ remove: function( id ){
8506
+ this.destroyTinymce( id );
8507
+ },
8508
+
8509
+ destroy: function( id ){
8510
+ this.destroyTinymce( id );
8511
+ },
8512
+
8513
+ destroyTinymce: function( id ){
8514
+
8515
+ // bail early
8516
+ if( typeof tinymce === 'undefined' ) return false;
8517
+
8518
+ // get editor
8519
+ var ed = tinymce.get( id );
8520
+
8521
+ // bail early if no editor
8522
+ if( !ed ) return false;
8523
+
8524
+ // save
8525
+ ed.save();
8526
+
8527
+ // destroy editor
8528
+ ed.destroy();
8529
+
8530
+ // return
8531
+ return true;
8532
+ },
8533
+
8534
+ enable: function( id ){
8535
+ this.enableTinymce( id );
8536
+ },
8537
+
8538
+ enableTinymce: function( id ){
8539
+
8540
+ // bail early
8541
+ if( typeof switchEditors === 'undefined' ) return false;
8542
+
8543
+ // bail ealry if not initialized
8544
+ if( typeof tinyMCEPreInit.mceInit[ id ] === 'undefined' ) return false;
8545
+
8546
+ // Ensure textarea element is visible
8547
+ // - Fixes bug in block editor when switching between "Block" and "Document" tabs.
8548
+ $('#'+id).show();
8549
+
8550
+ // toggle
8551
+ switchEditors.go( id, 'tmce');
8552
+
8553
+ // return
8554
+ return true;
8555
+ }
8556
+ };
8557
+
8558
+ var editorManager = new acf.Model({
8559
+
8560
+ // hook in before fieldsEventManager, conditions, etc
8561
+ priority: 5,
8562
+
8563
+ actions: {
8564
+ 'prepare': 'onPrepare',
8565
+ 'ready': 'onReady',
8566
+ },
8567
+ onPrepare: function(){
8568
+
8569
+ // find hidden editor which may exist within a field
8570
+ var $div = $('#acf-hidden-wp-editor');
8571
+
8572
+ // move to footer
8573
+ if( $div.exists() ) {
8574
+ $div.appendTo('body');
8575
+ }
8576
+ },
8577
+ onReady: function(){
8578
+
8579
+ // Restore wp.editor functions used by tinymce removed in WP5.
8580
+ if( acf.isset(window,'wp','oldEditor') ) {
8581
+ wp.editor.autop = wp.oldEditor.autop;
8582
+ wp.editor.removep = wp.oldEditor.removep;
8583
+ }
8584
+
8585
+ // bail early if no tinymce
8586
+ if( !acf.isset(window,'tinymce','on') ) return;
8587
+
8588
+ // restore default activeEditor
8589
+ tinymce.on('AddEditor', function( data ){
8590
+
8591
+ // vars
8592
+ var editor = data.editor;
8593
+
8594
+ // bail early if not 'acf'
8595
+ if( editor.id.substr(0, 3) !== 'acf' ) return;
8596
+
8597
+ // override if 'content' exists
8598
+ editor = tinymce.editors.content || editor;
8599
+
8600
+ // update vars
8601
+ tinymce.activeEditor = editor;
8602
+ wpActiveEditor = editor.id;
8603
+ });
8604
+ }
8605
+ });
8606
+
8607
  })(jQuery);
8608
+ (function($, undefined){
8609
+
8610
+ /**
8611
+ * Validator
8612
+ *
8613
+ * The model for validating forms
8614
+ *
8615
+ * @date 4/9/18
8616
+ * @since 5.7.5
8617
+ *
8618
+ * @param void
8619
+ * @return void
8620
+ */
8621
+ var Validator = acf.Model.extend({
8622
+
8623
+ /** @var string The model identifier. */
8624
+ id: 'Validator',
8625
+
8626
+ /** @var object The model data. */
8627
+ data: {
8628
+
8629
+ /** @var array The form errors. */
8630
+ errors: [],
8631
+
8632
+ /** @var object The form notice. */
8633
+ notice: null,
8634
+
8635
+ /** @var string The form status. loading, invalid, valid */
8636
+ status: ''
8637
+ },
8638
+
8639
+ /** @var object The model events. */
8640
+ events: {
8641
+ 'changed:status': 'onChangeStatus'
8642
+ },
8643
+
8644
+ /**
8645
+ * addErrors
8646
+ *
8647
+ * Adds errors to the form.
8648
+ *
8649
+ * @date 4/9/18
8650
+ * @since 5.7.5
8651
+ *
8652
+ * @param array errors An array of errors.
8653
+ * @return void
8654
+ */
8655
+ addErrors: function( errors ){
8656
+ errors.map( this.addError, this );
8657
+ },
8658
+
8659
+ /**
8660
+ * addError
8661
+ *
8662
+ * Adds and error to the form.
8663
+ *
8664
+ * @date 4/9/18
8665
+ * @since 5.7.5
8666
+ *
8667
+ * @param object error An error object containing input and message.
8668
+ * @return void
8669
+ */
8670
+ addError: function( error ){
8671
+ this.data.errors.push( error );
8672
+ },
8673
+
8674
+ /**
8675
+ * hasErrors
8676
+ *
8677
+ * Returns true if the form has errors.
8678
+ *
8679
+ * @date 4/9/18
8680
+ * @since 5.7.5
8681
+ *
8682
+ * @param void
8683
+ * @return bool
8684
+ */
8685
+ hasErrors: function(){
8686
+ return this.data.errors.length;
8687
+ },
8688
+
8689
+ /**
8690
+ * clearErrors
8691
+ *
8692
+ * Removes any errors.
8693
+ *
8694
+ * @date 4/9/18
8695
+ * @since 5.7.5
8696
+ *
8697
+ * @param void
8698
+ * @return void
8699
+ */
8700
+ clearErrors: function(){
8701
+ return this.data.errors = [];
8702
+ },
8703
+
8704
+ /**
8705
+ * getErrors
8706
+ *
8707
+ * Returns the forms errors.
8708
+ *
8709
+ * @date 4/9/18
8710
+ * @since 5.7.5
8711
+ *
8712
+ * @param void
8713
+ * @return array
8714
+ */
8715
+ getErrors: function(){
8716
+ return this.data.errors;
8717
+ },
8718
+
8719
+ /**
8720
+ * getFieldErrors
8721
+ *
8722
+ * Returns the forms field errors.
8723
+ *
8724
+ * @date 4/9/18
8725
+ * @since 5.7.5
8726
+ *
8727
+ * @param void
8728
+ * @return array
8729
+ */
8730
+ getFieldErrors: function(){
8731
+
8732
+ // vars
8733
+ var errors = [];
8734
+ var inputs = [];
8735
+
8736
+ // loop
8737
+ this.getErrors().map(function(error){
8738
+
8739
+ // bail early if global
8740
+ if( !error.input ) return;
8741
+
8742
+ // update if exists
8743
+ var i = inputs.indexOf(error.input);
8744
+ if( i > -1 ) {
8745
+ errors[ i ] = error;
8746
+
8747
+ // update
8748
+ } else {
8749
+ errors.push( error );
8750
+ inputs.push( error.input );
8751
+ }
8752
+ });
8753
+
8754
+ // return
8755
+ return errors;
8756
+ },
8757
+
8758
+ /**
8759
+ * getGlobalErrors
8760
+ *
8761
+ * Returns the forms global errors (errors without a specific input).
8762
+ *
8763
+ * @date 4/9/18
8764
+ * @since 5.7.5
8765
+ *
8766
+ * @param void
8767
+ * @return array
8768
+ */
8769
+ getGlobalErrors: function(){
8770
+
8771
+ // return array of errors that contain no input
8772
+ return this.getErrors().filter(function(error){
8773
+ return !error.input;
8774
+ });
8775
+ },
8776
+
8777
+ /**
8778
+ * showErrors
8779
+ *
8780
+ * Displays all errors for this form.
8781
+ *
8782
+ * @date 4/9/18
8783
+ * @since 5.7.5
8784
+ *
8785
+ * @param void
8786
+ * @return void
8787
+ */
8788
+ showErrors: function(){
8789
+
8790
+ // bail early if no errors
8791
+ if( !this.hasErrors() ) {
8792
+ return;
8793
+ }
8794
+
8795
+ // vars
8796
+ var fieldErrors = this.getFieldErrors();
8797
+ var globalErrors = this.getGlobalErrors();
8798
+
8799
+ // vars
8800
+ var errorCount = 0;
8801
+ var $scrollTo = false;
8802
+
8803
+ // loop
8804
+ fieldErrors.map(function( error ){
8805
+
8806
+ // get input
8807
+ var $input = this.$('[name="' + error.input + '"]').first();
8808
+
8809
+ // if $_POST value was an array, this $input may not exist
8810
+ if( !$input.length ) {
8811
+ $input = this.$('[name^="' + error.input + '"]').first();
8812
+ }
8813
+
8814
+ // bail early if input doesn't exist
8815
+ if( !$input.length ) {
8816
+ return;
8817
+ }
8818
+
8819
+ // increase
8820
+ errorCount++;
8821
+
8822
+ // get field
8823
+ var field = acf.getClosestField( $input );
8824
+
8825
+ // show error
8826
+ field.showError( error.message );
8827
+
8828
+ // set $scrollTo
8829
+ if( !$scrollTo ) {
8830
+ $scrollTo = field.$el;
8831
+ }
8832
+ }, this);
8833
+
8834
+ // errorMessage
8835
+ var errorMessage = acf.__('Validation failed');
8836
+ globalErrors.map(function( error ){
8837
+ errorMessage += '. ' + error.message;
8838
+ });
8839
+ if( errorCount == 1 ) {
8840
+ errorMessage += '. ' + acf.__('1 field requires attention');
8841
+ } else if( errorCount > 1 ) {
8842
+ errorMessage += '. ' + acf.__('%d fields require attention').replace('%d', errorCount);
8843
+ }
8844
+
8845
+ // notice
8846
+ if( this.has('notice') ) {
8847
+ this.get('notice').update({
8848
+ type: 'error',
8849
+ text: errorMessage
8850
+ });
8851
+ } else {
8852
+ var notice = acf.newNotice({
8853
+ type: 'error',
8854
+ text: errorMessage,
8855
+ target: this.$el
8856
+ });
8857
+ this.set('notice', notice);
8858
+ }
8859
+
8860
+ // if no $scrollTo, set to message
8861
+ if( !$scrollTo ) {
8862
+ $scrollTo = this.get('notice').$el;
8863
+ }
8864
+
8865
+ // timeout
8866
+ setTimeout(function(){
8867
+ $("html, body").animate({ scrollTop: $scrollTo.offset().top - ( $(window).height() / 2 ) }, 500);
8868
+ }, 10);
8869
+ },
8870
+
8871
+ /**
8872
+ * onChangeStatus
8873
+ *
8874
+ * Update the form class when changing the 'status' data
8875
+ *
8876
+ * @date 4/9/18
8877
+ * @since 5.7.5
8878
+ *
8879
+ * @param object e The event object.
8880
+ * @param jQuery $el The form element.
8881
+ * @param string value The new status.
8882
+ * @param string prevValue The old status.
8883
+ * @return void
8884
+ */
8885
+ onChangeStatus: function( e, $el, value, prevValue ){
8886
+ this.$el.removeClass('is-'+prevValue).addClass('is-'+value);
8887
+ },
8888
+
8889
+ /**
8890
+ * validate
8891
+ *
8892
+ * Vaildates the form via AJAX.
8893
+ *
8894
+ * @date 4/9/18
8895
+ * @since 5.7.5
8896
+ *
8897
+ * @param object args A list of settings to customize the validation process.
8898
+ * @return bool True if the form is valid.
8899
+ */
8900
+ validate: function( args ){
8901
+
8902
+ // default args
8903
+ args = acf.parseArgs(args, {
8904
+
8905
+ // trigger event
8906
+ event: false,
8907
+
8908
+ // reset the form after submit
8909
+ reset: false,
8910
+
8911
+ // loading callback
8912
+ loading: function(){},
8913
+
8914
+ // complete callback
8915
+ complete: function(){},
8916
+
8917
+ // failure callback
8918
+ failure: function(){},
8919
+
8920
+ // success callback
8921
+ success: function( $form ){
8922
+ $form.submit();
8923
+ }
8924
+ });
8925
+
8926
+ // return true if is valid - allows form submit
8927
+ if( this.get('status') == 'valid' ) {
8928
+ return true;
8929
+ }
8930
+
8931
+ // return false if is currently validating - prevents form submit
8932
+ if( this.get('status') == 'validating' ) {
8933
+ return false;
8934
+ }
8935
+
8936
+ // return true if no ACF fields exist (no need to validate)
8937
+ if( !this.$('.acf-field').length ) {
8938
+ return true;
8939
+ }
8940
+
8941
+ // if event is provided, create a new success callback.
8942
+ if( args.event ) {
8943
+ var event = $.Event(null, args.event);
8944
+ args.success = function(){
8945
+ acf.enableSubmit( $(event.target) ).trigger( event );
8946
+ }
8947
+ }
8948
+
8949
+ // action for 3rd party
8950
+ acf.doAction('validation_begin', this.$el);
8951
+
8952
+ // lock form
8953
+ acf.lockForm( this.$el );
8954
+
8955
+ // loading callback
8956
+ args.loading( this.$el, this );
8957
+
8958
+ // update status
8959
+ this.set('status', 'validating');
8960
+
8961
+ // success callback
8962
+ var onSuccess = function( json ){
8963
+
8964
+ // validate
8965
+ if( !acf.isAjaxSuccess(json) ) {
8966
+ return;
8967
+ }
8968
+
8969
+ // filter
8970
+ var data = acf.applyFilters('validation_complete', json.data, this.$el, this);
8971
+
8972
+ // add errors
8973
+ if( !data.valid ) {
8974
+ this.addErrors( data.errors );
8975
+ }
8976
+ };
8977
+
8978
+ // complete
8979
+ var onComplete = function(){
8980
+
8981
+ // unlock form
8982
+ acf.unlockForm( this.$el );
8983
+
8984
+ // failure
8985
+ if( this.hasErrors() ) {
8986
+
8987
+ // update status
8988
+ this.set('status', 'invalid');
8989
+
8990
+ // action
8991
+ acf.doAction('validation_failure', this.$el, this);
8992
+
8993
+ // display errors
8994
+ this.showErrors();
8995
+
8996
+ // failure callback
8997
+ args.failure( this.$el, this );
8998
+
8999
+ // success
9000
+ } else {
9001
+
9002
+ // update status
9003
+ this.set('status', 'valid');
9004
+
9005
+ // remove previous error message
9006
+ if( this.has('notice') ) {
9007
+ this.get('notice').update({
9008
+ type: 'success',
9009
+ text: acf.__('Validation successful'),
9010
+ timeout: 1000
9011
+ });
9012
+ }
9013
+
9014
+ // action
9015
+ acf.doAction('validation_success', this.$el, this);
9016
+ acf.doAction('submit', this.$el);
9017
+
9018
+ // success callback (submit form)
9019
+ args.success( this.$el, this );
9020
+
9021
+ // lock form
9022
+ acf.lockForm( this.$el );
9023
+
9024
+ // reset
9025
+ if( args.reset ) {
9026
+ this.reset();
9027
+ }
9028
+ }
9029
+
9030
+ // complete callback
9031
+ args.complete( this.$el, this );
9032
+
9033
+ // clear errors
9034
+ this.clearErrors();
9035
+ };
9036
+
9037
+ // serialize form data
9038
+ var data = acf.serialize( this.$el );
9039
+ data.action = 'acf/validate_save_post';
9040
+
9041
+ // ajax
9042
+ $.ajax({
9043
+ url: acf.get('ajaxurl'),
9044
+ data: acf.prepareForAjax(data),
9045
+ type: 'post',
9046
+ dataType: 'json',
9047
+ context: this,
9048
+ success: onSuccess,
9049
+ complete: onComplete
9050
+ });
9051
+
9052
+ // return false to fail validation and allow AJAX
9053
+ return false
9054
+ },
9055
+
9056
+ /**
9057
+ * setup
9058
+ *
9059
+ * Called during the constructor function to setup this instance
9060
+ *
9061
+ * @date 4/9/18
9062
+ * @since 5.7.5
9063
+ *
9064
+ * @param jQuery $form The form element.
9065
+ * @return void
9066
+ */
9067
+ setup: function( $form ){
9068
+
9069
+ // set $el
9070
+ this.$el = $form;
9071
+ },
9072
+
9073
+ /**
9074
+ * reset
9075
+ *
9076
+ * Rests the validation to be used again.
9077
+ *
9078
+ * @date 6/9/18
9079
+ * @since 5.7.5
9080
+ *
9081
+ * @param void
9082
+ * @return void
9083
+ */
9084
+ reset: function(){
9085
+
9086
+ // reset data
9087
+ this.set('errors', []);
9088
+ this.set('notice', null);
9089
+ this.set('status', '');
9090
+
9091
+ // unlock form
9092
+ acf.unlockForm( this.$el );
9093
+ }
9094
+ });
9095
+
9096
+ /**
9097
+ * getValidator
9098
+ *
9099
+ * Returns the instance for a given form element.
9100
+ *
9101
+ * @date 4/9/18
9102
+ * @since 5.7.5
9103
+ *
9104
+ * @param jQuery $el The form element.
9105
+ * @return object
9106
+ */
9107
+ var getValidator = function( $el ){
9108
+
9109
+ // instantiate
9110
+ var validator = $el.data('acf');
9111
+ if( !validator ) {
9112
+ validator = new Validator( $el );
9113
+ }
9114
+
9115
+ // return
9116
+ return validator;
9117
+ };
9118
+
9119
+ /**
9120
+ * acf.validateForm
9121
+ *
9122
+ * A helper function for the Validator.validate() function.
9123
+ * Returns true if form is valid, or fetches a validation request and returns false.
9124
+ *
9125
+ * @date 4/4/18
9126
+ * @since 5.6.9
9127
+ *
9128
+ * @param object args A list of settings to customize the validation process.
9129
+ * @return bool
9130
+ */
9131
+
9132
+ acf.validateForm = function( args ){
9133
+ return getValidator( args.form ).validate( args );
9134
+ };
9135
+
9136
+ /**
9137
+ * acf.enableSubmit
9138
+ *
9139
+ * Enables a submit button and returns the element.
9140
+ *
9141
+ * @date 30/8/18
9142
+ * @since 5.7.4
9143
+ *
9144
+ * @param jQuery $submit The submit button.
9145
+ * @return jQuery
9146
+ */
9147
+ acf.enableSubmit = function( $submit ){
9148
+ return $submit.removeClass('disabled');
9149
+ };
9150
+
9151
+ /**
9152
+ * acf.disableSubmit
9153
+ *
9154
+ * Disables a submit button and returns the element.
9155
+ *
9156
+ * @date 30/8/18
9157
+ * @since 5.7.4
9158
+ *
9159
+ * @param jQuery $submit The submit button.
9160
+ * @return jQuery
9161
+ */
9162
+ acf.disableSubmit = function( $submit ){
9163
+ return $submit.addClass('disabled');
9164
+ };
9165
+
9166
+ /**
9167
+ * acf.showSpinner
9168
+ *
9169
+ * Shows the spinner element.
9170
+ *
9171
+ * @date 4/9/18
9172
+ * @since 5.7.5
9173
+ *
9174
+ * @param jQuery $spinner The spinner element.
9175
+ * @return jQuery
9176
+ */
9177
+ acf.showSpinner = function( $spinner ){
9178
+ $spinner.addClass('is-active'); // add class (WP > 4.2)
9179
+ $spinner.css('display', 'inline-block'); // css (WP < 4.2)
9180
+ return $spinner;
9181
+ };
9182
+
9183
+ /**
9184
+ * acf.hideSpinner
9185
+ *
9186
+ * Hides the spinner element.
9187
+ *
9188
+ * @date 4/9/18
9189
+ * @since 5.7.5
9190
+ *
9191
+ * @param jQuery $spinner The spinner element.
9192
+ * @return jQuery
9193
+ */
9194
+ acf.hideSpinner = function( $spinner ){
9195
+ $spinner.removeClass('is-active'); // add class (WP > 4.2)
9196
+ $spinner.css('display', 'none'); // css (WP < 4.2)
9197
+ return $spinner;
9198
+ };
9199
+
9200
+ /**
9201
+ * acf.lockForm
9202
+ *
9203
+ * Locks a form by disabeling its primary inputs and showing a spinner.
9204
+ *
9205
+ * @date 4/9/18
9206
+ * @since 5.7.5
9207
+ *
9208
+ * @param jQuery $form The form element.
9209
+ * @return jQuery
9210
+ */
9211
+ acf.lockForm = function( $form ){
9212
+
9213
+ // vars
9214
+ var $wrap = findSubmitWrap( $form );
9215
+ var $submit = $wrap.find('.button, [type="submit"]');
9216
+ var $spinner = $wrap.find('.spinner, .acf-spinner');
9217
+
9218
+ // hide all spinners (hides the preview spinner)
9219
+ acf.hideSpinner( $spinner );
9220
+
9221
+ // lock
9222
+ acf.disableSubmit( $submit );
9223
+ acf.showSpinner( $spinner.last() );
9224
+ return $form;
9225
+ };
9226
+
9227
+ /**
9228
+ * acf.unlockForm
9229
+ *
9230
+ * Unlocks a form by enabeling its primary inputs and hiding all spinners.
9231
+ *
9232
+ * @date 4/9/18
9233
+ * @since 5.7.5
9234
+ *
9235
+ * @param jQuery $form The form element.
9236
+ * @return jQuery
9237
+ */
9238
+ acf.unlockForm = function( $form ){
9239
+
9240
+ // vars
9241
+ var $wrap = findSubmitWrap( $form );
9242
+ var $submit = $wrap.find('.button, [type="submit"]');
9243
+ var $spinner = $wrap.find('.spinner, .acf-spinner');
9244
+
9245
+ // unlock
9246
+ acf.enableSubmit( $submit );
9247
+ acf.hideSpinner( $spinner );
9248
+ return $form;
9249
+ };
9250
+
9251
+ /**
9252
+ * findSubmitWrap
9253
+ *
9254
+ * An internal function to find the 'primary' form submit wrapping element.
9255
+ *
9256
+ * @date 4/9/18
9257
+ * @since 5.7.5
9258
+ *
9259
+ * @param jQuery $form The form element.
9260
+ * @return jQuery
9261
+ */
9262
+ var findSubmitWrap = function( $form ){
9263
+
9264
+ // default post submit div
9265
+ var $wrap = $form.find('#submitdiv');
9266
+ if( $wrap.length ) {
9267
+ return $wrap;
9268
+ }
9269
+
9270
+ // 3rd party publish box
9271
+ var $wrap = $form.find('#submitpost');
9272
+ if( $wrap.length ) {
9273
+ return $wrap;
9274
+ }
9275
+
9276
+ // term, user
9277
+ var $wrap = $form.find('p.submit').last();
9278
+ if( $wrap.length ) {
9279
+ return $wrap;
9280
+ }
9281
+
9282
+ // front end form
9283
+ var $wrap = $form.find('.acf-form-submit');
9284
+ if( $wrap.length ) {
9285
+ return $wrap;
9286
+ }
9287
+
9288
+ // default
9289
+ return $form;
9290
+ };
9291
+
9292
+ /**
9293
+ * A debounced function to trigger a form submission.
9294
+ *
9295
+ * @date 15/07/2020
9296
+ * @since 5.9.0
9297
+ *
9298
+ * @param type Var Description.
9299
+ * @return type Description.
9300
+ */
9301
+ var submitFormDebounced = acf.debounce(function( $form ){
9302
+ $form.submit();
9303
+ });
9304
+
9305
+ /**
9306
+ * acf.validation
9307
+ *
9308
+ * Global validation logic
9309
+ *
9310
+ * @date 4/4/18
9311
+ * @since 5.6.9
9312
+ *
9313
+ * @param void
9314
+ * @return void
9315
+ */
9316
+
9317
+ acf.validation = new acf.Model({
9318
+
9319
+ /** @var string The model identifier. */
9320
+ id: 'validation',
9321
+
9322
+ /** @var bool The active state. Set to false before 'prepare' to prevent validation. */
9323
+ active: true,
9324
+
9325
+ /** @var string The model initialize time. */
9326
+ wait: 'prepare',
9327
+
9328
+ /** @var object The model actions. */
9329
+ actions: {
9330
+ 'ready': 'addInputEvents',
9331
+ 'append': 'addInputEvents'
9332
+ },
9333
+
9334
+ /** @var object The model events. */
9335
+ events: {
9336
+ 'click input[type="submit"]': 'onClickSubmit',
9337
+ 'click button[type="submit"]': 'onClickSubmit',
9338
+ //'click #editor .editor-post-publish-button': 'onClickSubmitGutenberg',
9339
+ 'click #save-post': 'onClickSave',
9340
+ 'submit form#post': 'onSubmitPost',
9341
+ 'submit form': 'onSubmit',
9342
+ },
9343
+
9344
+ /**
9345
+ * initialize
9346
+ *
9347
+ * Called when initializing the model.
9348
+ *
9349
+ * @date 4/9/18
9350
+ * @since 5.7.5
9351
+ *
9352
+ * @param void
9353
+ * @return void
9354
+ */
9355
+ initialize: function(){
9356
+
9357
+ // check 'validation' setting
9358
+ if( !acf.get('validation') ) {
9359
+ this.active = false;
9360
+ this.actions = {};
9361
+ this.events = {};
9362
+ }
9363
+ },
9364
+
9365
+ /**
9366
+ * enable
9367
+ *
9368
+ * Enables validation.
9369
+ *
9370
+ * @date 4/9/18
9371
+ * @since 5.7.5
9372
+ *
9373
+ * @param void
9374
+ * @return void
9375
+ */
9376
+ enable: function(){
9377
+ this.active = true;
9378
+ },
9379
+
9380
+ /**
9381
+ * disable
9382
+ *
9383
+ * Disables validation.
9384
+ *
9385
+ * @date 4/9/18
9386
+ * @since 5.7.5
9387
+ *
9388
+ * @param void
9389
+ * @return void
9390
+ */
9391
+ disable: function(){
9392
+ this.active = false;
9393
+ },
9394
+
9395
+ /**
9396
+ * reset
9397
+ *
9398
+ * Rests the form validation to be used again
9399
+ *
9400
+ * @date 6/9/18
9401
+ * @since 5.7.5
9402
+ *
9403
+ * @param jQuery $form The form element.
9404
+ * @return void
9405
+ */
9406
+ reset: function( $form ){
9407
+ getValidator( $form ).reset();
9408
+ },
9409
+
9410
+ /**
9411
+ * addInputEvents
9412
+ *
9413
+ * Adds 'invalid' event listeners to HTML inputs.
9414
+ *
9415
+ * @date 4/9/18
9416
+ * @since 5.7.5
9417
+ *
9418
+ * @param jQuery $el The element being added / readied.
9419
+ * @return void
9420
+ */
9421
+ addInputEvents: function( $el ){
9422
+
9423
+ // Bug exists in Safari where custom "invalid" handeling prevents draft from saving.
9424
+ if( acf.get('browser') === 'safari' )
9425
+ return;
9426
+
9427
+ // vars
9428
+ var $inputs = $('.acf-field [name]', $el);
9429
+
9430
+ // check
9431
+ if( $inputs.length ) {
9432
+ this.on( $inputs, 'invalid', 'onInvalid' );
9433
+ }
9434
+ },
9435
+
9436
+ /**
9437
+ * onInvalid
9438
+ *
9439
+ * Callback for the 'invalid' event.
9440
+ *
9441
+ * @date 4/9/18
9442
+ * @since 5.7.5
9443
+ *
9444
+ * @param object e The event object.
9445
+ * @param jQuery $el The input element.
9446
+ * @return void
9447
+ */
9448
+ onInvalid: function( e, $el ){
9449
+
9450
+ // prevent default
9451
+ // - prevents browser error message
9452
+ // - also fixes chrome bug where 'hidden-by-tab' field throws focus error
9453
+ e.preventDefault();
9454
+
9455
+ // vars
9456
+ var $form = $el.closest('form');
9457
+
9458
+ // check form exists
9459
+ if( $form.length ) {
9460
+
9461
+ // add error to validator
9462
+ getValidator( $form ).addError({
9463
+ input: $el.attr('name'),
9464
+ message: acf.strEscape( e.target.validationMessage )
9465
+ });
9466
+
9467
+ // trigger submit on $form
9468
+ // - allows for "save", "preview" and "publish" to work
9469
+ submitFormDebounced( $form );
9470
+ }
9471
+ },
9472
+
9473
+ /**
9474
+ * onClickSubmit
9475
+ *
9476
+ * Callback when clicking submit.
9477
+ *
9478
+ * @date 4/9/18
9479
+ * @since 5.7.5
9480
+ *
9481
+ * @param object e The event object.
9482
+ * @param jQuery $el The input element.
9483
+ * @return void
9484
+ */
9485
+ onClickSubmit: function( e, $el ){
9486
+
9487
+ // store the "click event" for later use in this.onSubmit()
9488
+ this.set('originalEvent', e);
9489
+ },
9490
+
9491
+ /**
9492
+ * onClickSave
9493
+ *
9494
+ * Set ignore to true when saving a draft.
9495
+ *
9496
+ * @date 4/9/18
9497
+ * @since 5.7.5
9498
+ *
9499
+ * @param object e The event object.
9500
+ * @param jQuery $el The input element.
9501
+ * @return void
9502
+ */
9503
+ onClickSave: function( e, $el ) {
9504
+ this.set('ignore', true);
9505
+ },
9506
+
9507
+ /**
9508
+ * onClickSubmitGutenberg
9509
+ *
9510
+ * Custom validation event for the gutenberg editor.
9511
+ *
9512
+ * @date 29/10/18
9513
+ * @since 5.8.0
9514
+ *
9515
+ * @param object e The event object.
9516
+ * @param jQuery $el The input element.
9517
+ * @return void
9518
+ */
9519
+ onClickSubmitGutenberg: function( e, $el ){
9520
+
9521
+ // validate
9522
+ var valid = acf.validateForm({
9523
+ form: $('#editor'),
9524
+ event: e,
9525
+ reset: true,
9526
+ failure: function( $form, validator ){
9527
+ var $notice = validator.get('notice').$el;
9528
+ $notice.appendTo('.components-notice-list');
9529
+ $notice.find('.acf-notice-dismiss').removeClass('small');
9530
+ }
9531
+ });
9532
+
9533
+ // if not valid, stop event and allow validation to continue
9534
+ if( !valid ) {
9535
+ e.preventDefault();
9536
+ e.stopImmediatePropagation();
9537
+ }
9538
+ },
9539
+
9540
+ /**
9541
+ * onSubmitPost
9542
+ *
9543
+ * Callback when the 'post' form is submit.
9544
+ *
9545
+ * @date 5/3/19
9546
+ * @since 5.7.13
9547
+ *
9548
+ * @param object e The event object.
9549
+ * @param jQuery $el The input element.
9550
+ * @return void
9551
+ */
9552
+ onSubmitPost: function( e, $el ) {
9553
+
9554
+ // Check if is preview.
9555
+ if( $('input#wp-preview').val() === 'dopreview' ) {
9556
+
9557
+ // Ignore validation.
9558
+ this.set('ignore', true);
9559
+
9560
+ // Unlock form to fix conflict with core "submit.edit-post" event causing all submit buttons to be disabled.
9561
+ acf.unlockForm( $el )
9562
+ }
9563
+ },
9564
+
9565
+ /**
9566
+ * onSubmit
9567
+ *
9568
+ * Callback when the form is submit.
9569
+ *
9570
+ * @date 4/9/18
9571
+ * @since 5.7.5
9572
+ *
9573
+ * @param object e The event object.
9574
+ * @param jQuery $el The input element.
9575
+ * @return void
9576
+ */
9577
+ onSubmit: function( e, $el ){
9578
+
9579
+ // Allow form to submit if...
9580
+ if(
9581
+ // Validation has been disabled.
9582
+ !this.active
9583
+
9584
+ // Or this event is to be ignored.
9585
+ || this.get('ignore')
9586
+
9587
+ // Or this event has already been prevented.
9588
+ || e.isDefaultPrevented()
9589
+ ) {
9590
+ // Return early and call reset function.
9591
+ return this.allowSubmit();
9592
+ }
9593
+
9594
+ // Validate form.
9595
+ var valid = acf.validateForm({
9596
+ form: $el,
9597
+ event: this.get('originalEvent')
9598
+ });
9599
+
9600
+ // If not valid, stop event to prevent form submit.
9601
+ if( !valid ) {
9602
+ e.preventDefault();
9603
+ }
9604
+ },
9605
+
9606
+ /**
9607
+ * allowSubmit
9608
+ *
9609
+ * Resets data during onSubmit when the form is allowed to submit.
9610
+ *
9611
+ * @date 5/3/19
9612
+ * @since 5.7.13
9613
+ *
9614
+ * @param void
9615
+ * @return void
9616
+ */
9617
+ allowSubmit: function(){
9618
+
9619
+ // Reset "ignore" state.
9620
+ this.set('ignore', false);
9621
+
9622
+ // Reset "originalEvent" object.
9623
+ this.set('originalEvent', false);
9624
+
9625
+ // Return true
9626
+ return true;
9627
+ }
9628
+ });
9629
+
9630
+ var gutenbergValidation = new acf.Model({
9631
+ wait: 'prepare',
9632
+ initialize: function(){
9633
+
9634
+ // Bail early if not Gutenberg.
9635
+ if( !acf.isGutenberg() ) {
9636
+ return;
9637
+ }
9638
+
9639
+ // Custommize the editor.
9640
+ this.customizeEditor();
9641
+ },
9642
+ customizeEditor: function(){
9643
+
9644
+ // Extract vars.
9645
+ var editor = wp.data.dispatch( 'core/editor' );
9646
+ var editorSelect = wp.data.select( 'core/editor' );
9647
+ var notices = wp.data.dispatch( 'core/notices' );
9648
+
9649
+ // Backup original method.
9650
+ var savePost = editor.savePost;
9651
+
9652
+ // Listen for changes to post status and perform actions:
9653
+ // a) Enable validation for "publish" action.
9654
+ // b) Remember last non "publish" status used for restoring after validation fail.
9655
+ var useValidation = false;
9656
+ var lastPostStatus = '';
9657
+ wp.data.subscribe(function() {
9658
+ var postStatus = editorSelect.getEditedPostAttribute( 'status' );
9659
+ useValidation = ( postStatus === 'publish' );
9660
+ lastPostStatus = ( postStatus !== 'publish' ) ? postStatus : lastPostStatus;
9661
+ });
9662
+
9663
+ // Create validation version.
9664
+ editor.savePost = function( options ){
9665
+ options = options || {};
9666
+
9667
+ // Backup vars.
9668
+ var _this = this;
9669
+ var _args = arguments;
9670
+
9671
+ // Perform validation within a Promise.
9672
+ return new Promise(function( resolve, reject ) {
9673
+
9674
+ // Bail early if is autosave or preview.
9675
+ if( options.isAutosave || options.isPreview ) {
9676
+ return resolve( 'Validation ignored (autosave).' );
9677
+ }
9678
+
9679
+ // Bail early if validation is not neeed.
9680
+ if( !useValidation ) {
9681
+ return resolve( 'Validation ignored (draft).' );
9682
+ }
9683
+
9684
+ // Validate the editor form.
9685
+ var valid = acf.validateForm({
9686
+ form: $('#editor'),
9687
+ reset: true,
9688
+ complete: function( $form, validator ){
9689
+
9690
+ // Always unlock the form after AJAX.
9691
+ editor.unlockPostSaving( 'acf' );
9692
+ },
9693
+ failure: function( $form, validator ){
9694
+
9695
+ // Get validation error and append to Gutenberg notices.
9696
+ var notice = validator.get('notice');
9697
+ notices.createErrorNotice( notice.get('text'), {
9698
+ id: 'acf-validation',
9699
+ isDismissible: true
9700
+ });
9701
+ notice.remove();
9702
+
9703
+ // Restore last non "publish" status.
9704
+ if( lastPostStatus ) {
9705
+ editor.editPost({
9706
+ status: lastPostStatus
9707
+ });
9708
+ }
9709
+
9710
+ // Rejext promise and prevent savePost().
9711
+ reject( 'Validation failed.' );
9712
+ },
9713
+ success: function(){
9714
+ notices.removeNotice( 'acf-validation' );
9715
+
9716
+ // Resolve promise and allow savePost().
9717
+ resolve( 'Validation success.' );
9718
+ }
9719
+ });
9720
+
9721
+ // Resolve promise and allow savePost() if no validation is needed.
9722
+ if( valid ) {
9723
+ resolve( 'Validation bypassed.' );
9724
+
9725
+ // Otherwise, lock the form and wait for AJAX response.
9726
+ } else {
9727
+ editor.lockPostSaving( 'acf' );
9728
+ }
9729
+ }).then(function(){
9730
+ return savePost.apply(_this, _args);
9731
+ });
9732
+ };
9733
+ }
9734
+ });
9735
+
9736
  })(jQuery);
9737
+ (function($, undefined){
9738
+
9739
+ /**
9740
+ * refreshHelper
9741
+ *
9742
+ * description
9743
+ *
9744
+ * @date 1/7/18
9745
+ * @since 5.6.9
9746
+ *
9747
+ * @param type $var Description. Default.
9748
+ * @return type Description.
9749
+ */
9750
+
9751
+ var refreshHelper = new acf.Model({
9752
+ priority: 90,
9753
+ actions: {
9754
+ 'new_field': 'refresh',
9755
+ 'show_field': 'refresh',
9756
+ 'hide_field': 'refresh',
9757
+ 'remove_field': 'refresh',
9758
+ 'unmount_field': 'refresh',
9759
+ 'remount_field': 'refresh',
9760
+ },
9761
+ refresh: function(){
9762
+ acf.refresh();
9763
+ }
9764
+ });
9765
+
9766
+ /**
9767
+ * mountHelper
9768
+ *
9769
+ * Adds compatiblity for the 'unmount' and 'remount' actions added in 5.8.0
9770
+ *
9771
+ * @date 7/3/19
9772
+ * @since 5.7.14
9773
+ *
9774
+ * @param void
9775
+ * @return void
9776
+ */
9777
+ var mountHelper = new acf.Model({
9778
+ priority: 1,
9779
+ actions: {
9780
+ 'sortstart': 'onSortstart',
9781
+ 'sortstop': 'onSortstop'
9782
+ },
9783
+ onSortstart: function( $item ){
9784
+ acf.doAction('unmount', $item);
9785
+ },
9786
+ onSortstop: function( $item ){
9787
+ acf.doAction('remount', $item);
9788
+ }
9789
+ });
9790
+
9791
+ /**
9792
+ * sortableHelper
9793
+ *
9794
+ * Adds compatibility for sorting a <tr> element
9795
+ *
9796
+ * @date 6/3/18
9797
+ * @since 5.6.9
9798
+ *
9799
+ * @param void
9800
+ * @return void
9801
+ */
9802
+
9803
+ var sortableHelper = new acf.Model({
9804
+ actions: {
9805
+ 'sortstart': 'onSortstart'
9806
+ },
9807
+ onSortstart: function( $item, $placeholder ){
9808
+
9809
+ // if $item is a tr, apply some css to the elements
9810
+ if( $item.is('tr') ) {
9811
+
9812
+ // replace $placeholder children with a single td
9813
+ // fixes "width calculation issues" due to conditional logic hiding some children
9814
+ $placeholder.html('<td style="padding:0;" colspan="' + $placeholder.children().length + '"></td>');
9815
+
9816
+ // add helper class to remove absolute positioning
9817
+ $item.addClass('acf-sortable-tr-helper');
9818
+
9819
+ // set fixed widths for children
9820
+ $item.children().each(function(){
9821
+ $(this).width( $(this).width() );
9822
+ });
9823
+
9824
+ // mimic height
9825
+ $placeholder.height( $item.height() + 'px' );
9826
+
9827
+ // remove class
9828
+ $item.removeClass('acf-sortable-tr-helper');
9829
+ }
9830
+ }
9831
+ });
9832
+
9833
+ /**
9834
+ * duplicateHelper
9835
+ *
9836
+ * Fixes browser bugs when duplicating an element
9837
+ *
9838
+ * @date 6/3/18
9839
+ * @since 5.6.9
9840
+ *
9841
+ * @param void
9842
+ * @return void
9843
+ */
9844
+
9845
+ var duplicateHelper = new acf.Model({
9846
+ actions: {
9847
+ 'after_duplicate': 'onAfterDuplicate'
9848
+ },
9849
+ onAfterDuplicate: function( $el, $el2 ){
9850
+
9851
+ // get original values
9852
+ var vals = [];
9853
+ $el.find('select').each(function(i){
9854
+ vals.push( $(this).val() );
9855
+ });
9856
+
9857
+ // set duplicate values
9858
+ $el2.find('select').each(function(i){
9859
+ $(this).val( vals[i] );
9860
+ });
9861
+ }
9862
+ });
9863
+
9864
+ /**
9865
+ * tableHelper
9866
+ *
9867
+ * description
9868
+ *
9869
+ * @date 6/3/18
9870
+ * @since 5.6.9
9871
+ *
9872
+ * @param type $var Description. Default.
9873
+ * @return type Description.
9874
+ */
9875
+
9876
+ var tableHelper = new acf.Model({
9877
+
9878
+ id: 'tableHelper',
9879
+
9880
+ priority: 20,
9881
+
9882
+ actions: {
9883
+ 'refresh': 'renderTables'
9884
+ },
9885
+
9886
+ renderTables: function( $el ){
9887
+
9888
+ // loop
9889
+ var self = this;
9890
+ $('.acf-table:visible').each(function(){
9891
+ self.renderTable( $(this) );
9892
+ });
9893
+ },
9894
+
9895
+ renderTable: function( $table ){
9896
+
9897
+ // vars
9898
+ var $ths = $table.find('> thead > tr:visible > th[data-key]');
9899
+ var $tds = $table.find('> tbody > tr:visible > td[data-key]');
9900
+
9901
+ // bail early if no thead
9902
+ if( !$ths.length || !$tds.length ) {
9903
+ return false;
9904
+ }
9905
+
9906
+
9907
+ // visiblity
9908
+ $ths.each(function( i ){
9909
+
9910
+ // vars
9911
+ var $th = $(this);
9912
+ var key = $th.data('key');
9913
+ var $cells = $tds.filter('[data-key="' + key + '"]');
9914
+ var $hidden = $cells.filter('.acf-hidden');
9915
+
9916
+ // always remove empty and allow cells to be hidden
9917
+ $cells.removeClass('acf-empty');
9918
+
9919
+ // hide $th if all cells are hidden
9920
+ if( $cells.length === $hidden.length ) {
9921
+ acf.hide( $th );
9922
+
9923
+ // force all hidden cells to appear empty
9924
+ } else {
9925
+ acf.show( $th );
9926
+ $hidden.addClass('acf-empty');
9927
+ }
9928
+ });
9929
+
9930
+
9931
+ // clear width
9932
+ $ths.css('width', 'auto');
9933
+
9934
+ // get visible
9935
+ $ths = $ths.not('.acf-hidden');
9936
+
9937
+ // vars
9938
+ var availableWidth = 100;
9939
+ var colspan = $ths.length;
9940
+
9941
+ // set custom widths first
9942
+ var $fixedWidths = $ths.filter('[data-width]');
9943
+ $fixedWidths.each(function(){
9944
+ var width = $(this).data('width');
9945
+ $(this).css('width', width + '%');
9946
+ availableWidth -= width;
9947
+ });
9948
+
9949
+ // set auto widths
9950
+ var $auoWidths = $ths.not('[data-width]');
9951
+ if( $auoWidths.length ) {
9952
+ var width = availableWidth / $auoWidths.length;
9953
+ $auoWidths.css('width', width + '%');
9954
+ availableWidth = 0;
9955
+ }
9956
+
9957
+ // avoid stretching issue
9958
+ if( availableWidth > 0 ) {
9959
+ $ths.last().css('width', 'auto');
9960
+ }
9961
+
9962
+
9963
+ // update colspan on collapsed
9964
+ $tds.filter('.-collapsed-target').each(function(){
9965
+
9966
+ // vars
9967
+ var $td = $(this);
9968
+
9969
+ // check if collapsed
9970
+ if( $td.parent().hasClass('-collapsed') ) {
9971
+ $td.attr('colspan', $ths.length);
9972
+ } else {
9973
+ $td.removeAttr('colspan');
9974
+ }
9975
+ });
9976
+ }
9977
+ });
9978
+
9979
+
9980
+ /**
9981
+ * fieldsHelper
9982
+ *
9983
+ * description
9984
+ *
9985
+ * @date 6/3/18
9986
+ * @since 5.6.9
9987
+ *
9988
+ * @param type $var Description. Default.
9989
+ * @return type Description.
9990
+ */
9991
+
9992
+ var fieldsHelper = new acf.Model({
9993
+
9994
+ id: 'fieldsHelper',
9995
+
9996
+ priority: 30,
9997
+
9998
+ actions: {
9999
+ 'refresh': 'renderGroups'
10000
+ },
10001
+
10002
+ renderGroups: function(){
10003
+
10004
+ // loop
10005
+ var self = this;
10006
+ $('.acf-fields:visible').each(function(){
10007
+ self.renderGroup( $(this) );
10008
+ });
10009
+ },
10010
+
10011
+ renderGroup: function( $el ){
10012
+
10013
+ // vars
10014
+ var top = 0;
10015
+ var height = 0;
10016
+ var $row = $();
10017
+
10018
+ // get fields
10019
+ var $fields = $el.children('.acf-field[data-width]:visible');
10020
+
10021
+ // bail early if no fields
10022
+ if( !$fields.length ) {
10023
+ return false;
10024
+ }
10025
+
10026
+ // bail ealry if is .-left
10027
+ if( $el.hasClass('-left') ) {
10028
+ $fields.removeAttr('data-width');
10029
+ $fields.css('width', 'auto');
10030
+ return false;
10031
+ }
10032
+
10033
+ // reset fields
10034
+ $fields.removeClass('-r0 -c0').css({'min-height': 0});
10035
+
10036
+ // loop
10037
+ $fields.each(function( i ){
10038
+
10039
+ // vars
10040
+ var $field = $(this);
10041
+ var position = $field.position();
10042
+ var thisTop = Math.ceil( position.top );
10043
+ var thisLeft = Math.ceil( position.left );
10044
+
10045
+ // detect change in row
10046
+ if( $row.length && thisTop > top ) {
10047
+
10048
+ // set previous heights
10049
+ $row.css({'min-height': height+'px'});
10050
+
10051
+ // update position due to change in row above
10052
+ position = $field.position();
10053
+ thisTop = Math.ceil( position.top );
10054
+ thisLeft = Math.ceil( position.left );
10055
+
10056
+ // reset vars
10057
+ top = 0;
10058
+ height = 0;
10059
+ $row = $();
10060
+ }
10061
+
10062
+ // rtl
10063
+ if( acf.get('rtl') ) {
10064
+ thisLeft = Math.ceil( $field.parent().width() - (position.left + $field.outerWidth()) );
10065
+ }
10066
+
10067
+ // add classes
10068
+ if( thisTop == 0 ) {
10069
+ $field.addClass('-r0');
10070
+ } else if( thisLeft == 0 ) {
10071
+ $field.addClass('-c0');
10072
+ }
10073
+
10074
+ // get height after class change
10075
+ // - add 1 for subpixel rendering
10076
+ var thisHeight = Math.ceil( $field.outerHeight() ) + 1;
10077
+
10078
+ // set height
10079
+ height = Math.max( height, thisHeight );
10080
+
10081
+ // set y
10082
+ top = Math.max( top, thisTop );
10083
+
10084
+ // append
10085
+ $row = $row.add( $field );
10086
+ });
10087
+
10088
+ // clean up
10089
+ if( $row.length ) {
10090
+ $row.css({'min-height': height+'px'});
10091
+ }
10092
+ }
10093
+ });
10094
+
10095
+ /**
10096
+ * Adds a body class when holding down the "shift" key.
10097
+ *
10098
+ * @date 06/05/2020
10099
+ * @since 5.9.0
10100
+ */
10101
+ var bodyClassShiftHelper = new acf.Model({
10102
+ id: 'bodyClassShiftHelper',
10103
+ events: {
10104
+ 'keydown': 'onKeyDown',
10105
+ 'keyup': 'onKeyUp'
10106
+ },
10107
+ isShiftKey: function( e ){
10108
+ return ( e.keyCode === 16 );
10109
+ },
10110
+ onKeyDown: function( e ){
10111
+ if( this.isShiftKey(e) ) {
10112
+ $('body').addClass('acf-keydown-shift');
10113
+ }
10114
+ },
10115
+ onKeyUp: function( e ){
10116
+ if( this.isShiftKey(e) ) {
10117
+ $('body').removeClass('acf-keydown-shift');
10118
+ }
10119
+ },
10120
+ });
10121
+
10122
  })(jQuery);
10123
+ (function($, undefined){
10124
+
10125
+ /**
10126
+ * acf.newCompatibility
10127
+ *
10128
+ * Inserts a new __proto__ object compatibility layer
10129
+ *
10130
+ * @date 15/2/18
10131
+ * @since 5.6.9
10132
+ *
10133
+ * @param object instance The object to modify.
10134
+ * @param object compatibilty Optional. The compatibilty layer.
10135
+ * @return object compatibilty
10136
+ */
10137
+
10138
+ acf.newCompatibility = function( instance, compatibilty ){
10139
+
10140
+ // defaults
10141
+ compatibilty = compatibilty || {};
10142
+
10143
+ // inherit __proto_-
10144
+ compatibilty.__proto__ = instance.__proto__;
10145
+
10146
+ // inject
10147
+ instance.__proto__ = compatibilty;
10148
+
10149
+ // reference
10150
+ instance.compatibility = compatibilty;
10151
+
10152
+ // return
10153
+ return compatibilty;
10154
+ };
10155
+
10156
+ /**
10157
+ * acf.getCompatibility
10158
+ *
10159
+ * Returns the compatibility layer for a given instance
10160
+ *
10161
+ * @date 13/3/18
10162
+ * @since 5.6.9
10163
+ *
10164
+ * @param object instance The object to look in.
10165
+ * @return object|null compatibility The compatibility object or null on failure.
10166
+ */
10167
+
10168
+ acf.getCompatibility = function( instance ) {
10169
+ return instance.compatibility || null;
10170
+ };
10171
+
10172
+ /**
10173
+ * acf (compatibility)
10174
+ *
10175
+ * Compatibility layer for the acf object
10176
+ *
10177
+ * @date 15/2/18
10178
+ * @since 5.6.9
10179
+ *
10180
+ * @param void
10181
+ * @return void
10182
+ */
10183
+
10184
+ var _acf = acf.newCompatibility(acf, {
10185
+
10186
+ // storage
10187
+ l10n: {},
10188
+ o: {},
10189
+ fields: {},
10190
+
10191
+ // changed function names
10192
+ update: acf.set,
10193
+ add_action: acf.addAction,
10194
+ remove_action: acf.removeAction,
10195
+ do_action: acf.doAction,
10196
+ add_filter: acf.addFilter,
10197
+ remove_filter: acf.removeFilter,
10198
+ apply_filters: acf.applyFilters,
10199
+ parse_args: acf.parseArgs,
10200
+ disable_el: acf.disable,
10201
+ disable_form: acf.disable,
10202
+ enable_el: acf.enable,
10203
+ enable_form: acf.enable,
10204
+ update_user_setting: acf.updateUserSetting,
10205
+ prepare_for_ajax: acf.prepareForAjax,
10206
+ is_ajax_success: acf.isAjaxSuccess,
10207
+ remove_el: acf.remove,
10208
+ remove_tr: acf.remove,
10209
+ str_replace: acf.strReplace,
10210
+ render_select: acf.renderSelect,
10211
+ get_uniqid: acf.uniqid,
10212
+ serialize_form: acf.serialize,
10213
+ esc_html: acf.strEscape,
10214
+ str_sanitize: acf.strSanitize,
10215
+
10216
+ });
10217
+
10218
+ _acf._e = function( k1, k2 ){
10219
+
10220
+ // defaults
10221
+ k1 = k1 || '';
10222
+ k2 = k2 || '';
10223
+
10224
+ // compability
10225
+ var compatKey = k2 ? k1 + '.' + k2 : k1;
10226
+ var compats = {
10227
+ 'image.select': 'Select Image',
10228
+ 'image.edit': 'Edit Image',
10229
+ 'image.update': 'Update Image'
10230
+ };
10231
+ if( compats[compatKey] ) {
10232
+ return acf.__(compats[compatKey]);
10233
+ }
10234
+
10235
+ // try k1
10236
+ var string = this.l10n[ k1 ] || '';
10237
+
10238
+ // try k2
10239
+ if( k2 ) {
10240
+ string = string[ k2 ] || '';
10241
+ }
10242
+
10243
+ // return
10244
+ return string;
10245
+ };
10246
+
10247
+ _acf.get_selector = function( s ) {
10248
+
10249
+ // vars
10250
+ var selector = '.acf-field';
10251
+
10252
+ // bail early if no search
10253
+ if( !s ) {
10254
+ return selector;
10255
+ }
10256
+
10257
+ // compatibility with object
10258
+ if( $.isPlainObject(s) ) {
10259
+ if( $.isEmptyObject(s) ) {
10260
+ return selector;
10261
+ } else {
10262
+ for( var k in s ) { s = s[k]; break; }
10263
+ }
10264
+ }
10265
+
10266
+ // append
10267
+ selector += '-' + s;
10268
+
10269
+ // replace underscores (split/join replaces all and is faster than regex!)
10270
+ selector = acf.strReplace('_', '-', selector);
10271
+
10272
+ // remove potential double up
10273
+ selector = acf.strReplace('field-field-', 'field-', selector);
10274
+
10275
+ // return
10276
+ return selector;
10277
+ };
10278
+
10279
+ _acf.get_fields = function( s, $el, all ){
10280
+
10281
+ // args
10282
+ var args = {
10283
+ is: s || '',
10284
+ parent: $el || false,
10285
+ suppressFilters: all || false,
10286
+ };
10287
+
10288
+ // change 'field_123' to '.acf-field-123'
10289
+ if( args.is ) {
10290
+ args.is = this.get_selector( args.is );
10291
+ }
10292
+
10293
+ // return
10294
+ return acf.findFields(args);
10295
+ };
10296
+
10297
+ _acf.get_field = function( s, $el ){
10298
+
10299
+ // get fields
10300
+ var $fields = this.get_fields.apply(this, arguments);
10301
+
10302
+ // return
10303
+ if( $fields.length ) {
10304
+ return $fields.first();
10305
+ } else {
10306
+ return false;
10307
+ }
10308
+ };
10309
+
10310
+ _acf.get_closest_field = function( $el, s ){
10311
+ return $el.closest( this.get_selector(s) );
10312
+ };
10313
+
10314
+ _acf.get_field_wrap = function( $el ){
10315
+ return $el.closest( this.get_selector() );
10316
+ };
10317
+
10318
+ _acf.get_field_key = function( $field ){
10319
+ return $field.data('key');
10320
+ };
10321
+
10322
+ _acf.get_field_type = function( $field ){
10323
+ return $field.data('type');
10324
+ };
10325
+
10326
+ _acf.get_data = function( $el, defaults ){
10327
+ return acf.parseArgs( $el.data(), defaults );
10328
+ };
10329
+
10330
+ _acf.maybe_get = function( obj, key, value ){
10331
+
10332
+ // default
10333
+ if( value === undefined ) {
10334
+ value = null;
10335
+ }
10336
+
10337
+ // get keys
10338
+ keys = String(key).split('.');
10339
+
10340
+ // acf.isget
10341
+ for( var i = 0; i < keys.length; i++ ) {
10342
+ if( !obj.hasOwnProperty(keys[i]) ) {
10343
+ return value;
10344
+ }
10345
+ obj = obj[ keys[i] ];
10346
+ }
10347
+ return obj;
10348
+ };
10349
+
10350
+
10351
+ /**
10352
+ * hooks
10353
+ *
10354
+ * Modify add_action and add_filter functions to add compatibility with changed $field parameter
10355
+ * Using the acf.add_action() or acf.add_filter() functions will interpret new field parameters as jQuery $field
10356
+ *
10357
+ * @date 12/5/18
10358
+ * @since 5.6.9
10359
+ *
10360
+ * @param void
10361
+ * @return void
10362
+ */
10363
+
10364
+ var compatibleArgument = function( arg ){
10365
+ return ( arg instanceof acf.Field ) ? arg.$el : arg;
10366
+ };
10367
+
10368
+ var compatibleArguments = function( args ){
10369
+ return acf.arrayArgs( args ).map( compatibleArgument );
10370
+ }
10371
+
10372
+ var compatibleCallback = function( origCallback ){
10373
+ return function(){
10374
+
10375
+ // convert to compatible arguments
10376
+ if( arguments.length ) {
10377
+ var args = compatibleArguments(arguments);
10378
+
10379
+ // add default argument for 'ready', 'append' and 'load' events
10380
+ } else {
10381
+ var args = [ $(document) ];
10382
+ }
10383
+
10384
+ // return
10385
+ return origCallback.apply(this, args);
10386
+ }
10387
+ }
10388
+
10389
+ _acf.add_action = function( action, callback, priority, context ){
10390
+
10391
+ // handle multiple actions
10392
+ var actions = action.split(' ');
10393
+ var length = actions.length;
10394
+ if( length > 1 ) {
10395
+ for( var i = 0; i < length; i++) {
10396
+ action = actions[i];
10397
+ _acf.add_action.apply(this, arguments);
10398
+ }
10399
+ return this;
10400
+ }
10401
+
10402
+ // single
10403
+ var callback = compatibleCallback(callback);
10404
+ return acf.addAction.apply(this, arguments);
10405
+ };
10406
+
10407
+ _acf.add_filter = function( action, callback, priority, context ){
10408
+ var callback = compatibleCallback(callback);
10409
+ return acf.addFilter.apply(this, arguments);
10410
+ };
10411
+
10412
+ /*
10413
+ * acf.model
10414
+ *
10415
+ * This model acts as a scafold for action.event driven modules
10416
+ *
10417
+ * @type object
10418
+ * @date 8/09/2014
10419
+ * @since 5.0.0
10420
+ *
10421
+ * @param (object)
10422
+ * @return (object)
10423
+ */
10424
+
10425
+ _acf.model = {
10426
+ actions: {},
10427
+ filters: {},
10428
+ events: {},
10429
+ extend: function( args ){
10430
+
10431
+ // extend
10432
+ var model = $.extend( {}, this, args );
10433
+
10434
+ // setup actions
10435
+ $.each(model.actions, function( name, callback ){
10436
+ model._add_action( name, callback );
10437
+ });
10438
+
10439
+ // setup filters
10440
+ $.each(model.filters, function( name, callback ){
10441
+ model._add_filter( name, callback );
10442
+ });
10443
+
10444
+ // setup events
10445
+ $.each(model.events, function( name, callback ){
10446
+ model._add_event( name, callback );
10447
+ });
10448
+
10449
+ // return
10450
+ return model;
10451
+ },
10452
+
10453
+ _add_action: function( name, callback ) {
10454
+
10455
+ // split
10456
+ var model = this,
10457
+ data = name.split(' ');
10458
+
10459
+ // add missing priority
10460
+ var name = data[0] || '',
10461
+ priority = data[1] || 10;
10462
+
10463
+ // add action
10464
+ acf.add_action(name, model[ callback ], priority, model);
10465
+
10466
+ },
10467
+
10468
+ _add_filter: function( name, callback ) {
10469
+
10470
+ // split
10471
+ var model = this,
10472
+ data = name.split(' ');
10473
+
10474
+ // add missing priority
10475
+ var name = data[0] || '',
10476
+ priority = data[1] || 10;
10477
+
10478
+ // add action
10479
+ acf.add_filter(name, model[ callback ], priority, model);
10480
+ },
10481
+
10482
+ _add_event: function( name, callback ) {
10483
+
10484
+ // vars
10485
+ var model = this,
10486
+ i = name.indexOf(' '),
10487
+ event = (i > 0) ? name.substr(0,i) : name,
10488
+ selector = (i > 0) ? name.substr(i+1) : '';
10489
+
10490
+ // event
10491
+ var fn = function( e ){
10492
+
10493
+ // append $el to event object
10494
+ e.$el = $(this);
10495
+
10496
+ // append $field to event object (used in field group)
10497
+ if( acf.field_group ) {
10498
+ e.$field = e.$el.closest('.acf-field-object');
10499
+ }
10500
+
10501
+ // event
10502
+ if( typeof model.event === 'function' ) {
10503
+ e = model.event( e );
10504
+ }
10505
+
10506
+ // callback
10507
+ model[ callback ].apply(model, arguments);
10508
+
10509
+ };
10510
+
10511
+ // add event
10512
+ if( selector ) {
10513
+ $(document).on(event, selector, fn);
10514
+ } else {
10515
+ $(document).on(event, fn);
10516
+ }
10517
+ },
10518
+
10519
+ get: function( name, value ){
10520
+
10521
+ // defaults
10522
+ value = value || null;
10523
+
10524
+ // get
10525
+ if( typeof this[ name ] !== 'undefined' ) {
10526
+ value = this[ name ];
10527
+ }
10528
+
10529
+ // return
10530
+ return value;
10531
+ },
10532
+
10533
+ set: function( name, value ){
10534
+
10535
+ // set
10536
+ this[ name ] = value;
10537
+
10538
+ // function for 3rd party
10539
+ if( typeof this[ '_set_' + name ] === 'function' ) {
10540
+ this[ '_set_' + name ].apply(this);
10541
+ }
10542
+
10543
+ // return for chaining
10544
+ return this;
10545
+ }
10546
+ };
10547
+
10548
+ /*
10549
+ * field
10550
+ *
10551
+ * This model sets up many of the field's interactions
10552
+ *
10553
+ * @type function
10554
+ * @date 21/02/2014
10555
+ * @since 3.5.1
10556
+ *
10557
+ * @param n/a
10558
+ * @return n/a
10559
+ */
10560
+
10561
+ _acf.field = acf.model.extend({
10562
+ type: '',
10563
+ o: {},
10564
+ $field: null,
10565
+ _add_action: function( name, callback ) {
10566
+
10567
+ // vars
10568
+ var model = this;
10569
+
10570
+ // update name
10571
+ name = name + '_field/type=' + model.type;
10572
+
10573
+ // add action
10574
+ acf.add_action(name, function( $field ){
10575
+
10576
+ // focus
10577
+ model.set('$field', $field);
10578
+
10579
+ // callback
10580
+ model[ callback ].apply(model, arguments);
10581
+ });
10582
+ },
10583
+
10584
+ _add_filter: function( name, callback ) {
10585
+
10586
+ // vars
10587
+ var model = this;
10588
+
10589
+ // update name
10590
+ name = name + '_field/type=' + model.type;
10591
+
10592
+ // add action
10593
+ acf.add_filter(name, function( $field ){
10594
+
10595
+ // focus
10596
+ model.set('$field', $field);
10597
+
10598
+ // callback
10599
+ model[ callback ].apply(model, arguments);
10600
+ });
10601
+ },
10602
+
10603
+ _add_event: function( name, callback ) {
10604
+
10605
+ // vars
10606
+ var model = this,
10607
+ event = name.substr(0,name.indexOf(' ')),
10608
+ selector = name.substr(name.indexOf(' ')+1),
10609
+ context = acf.get_selector(model.type);
10610
+
10611
+ // add event
10612
+ $(document).on(event, context + ' ' + selector, function( e ){
10613
+
10614
+ // vars
10615
+ var $el = $(this);
10616
+ var $field = acf.get_closest_field( $el, model.type );
10617
+
10618
+ // bail early if no field
10619
+ if( !$field.length ) return;
10620
+
10621
+ // focus
10622
+ if( !$field.is(model.$field) ) {
10623
+ model.set('$field', $field);
10624
+ }
10625
+
10626
+ // append to event
10627
+ e.$el = $el;
10628
+ e.$field = $field;
10629
+
10630
+ // callback
10631
+ model[ callback ].apply(model, [e]);
10632
+ });
10633
+ },
10634
+
10635
+ _set_$field: function(){
10636
+
10637
+ // callback
10638
+ if( typeof this.focus === 'function' ) {
10639
+ this.focus();
10640
+ }
10641
+ },
10642
+
10643
+ // depreciated
10644
+ doFocus: function( $field ){
10645
+ return this.set('$field', $field);
10646
+ }
10647
+ });
10648
+
10649
+
10650
+ /**
10651
+ * validation
10652
+ *
10653
+ * description
10654
+ *
10655
+ * @date 15/2/18
10656
+ * @since 5.6.9
10657
+ *
10658
+ * @param type $var Description. Default.
10659
+ * @return type Description.
10660
+ */
10661
+
10662
+ var _validation = acf.newCompatibility(acf.validation, {
10663
+ remove_error: function( $field ){
10664
+ acf.getField( $field ).removeError();
10665
+ },
10666
+ add_warning: function( $field, message ){
10667
+ acf.getField( $field ).showNotice({
10668
+ text: message,
10669
+ type: 'warning',
10670
+ timeout: 1000
10671
+ });
10672
+ },
10673
+ fetch: acf.validateForm,
10674
+ enableSubmit: acf.enableSubmit,
10675
+ disableSubmit: acf.disableSubmit,
10676
+ showSpinner: acf.showSpinner,
10677
+ hideSpinner: acf.hideSpinner,
10678
+ unlockForm: acf.unlockForm,
10679
+ lockForm: acf.lockForm
10680
+ });
10681
+
10682
+
10683
+ /**
10684
+ * tooltip
10685
+ *
10686
+ * description
10687
+ *
10688
+ * @date 15/2/18
10689
+ * @since 5.6.9
10690
+ *
10691
+ * @param type $var Description. Default.
10692
+ * @return type Description.
10693
+ */
10694
+
10695
+ _acf.tooltip = {
10696
+
10697
+ tooltip: function( text, $el ){
10698
+
10699
+ var tooltip = acf.newTooltip({
10700
+ text: text,
10701
+ target: $el
10702
+ });
10703
+
10704
+ // return
10705
+ return tooltip.$el;
10706
+ },
10707
+
10708
+ temp: function( text, $el ){
10709
+
10710
+ var tooltip = acf.newTooltip({
10711
+ text: text,
10712
+ target: $el,
10713
+ timeout: 250
10714
+ });
10715
+ },
10716
+
10717
+ confirm: function( $el, callback, text, button_y, button_n ){
10718
+
10719
+ var tooltip = acf.newTooltip({
10720
+ confirm: true,
10721
+ text: text,
10722
+ target: $el,
10723
+ confirm: function(){
10724
+ callback(true);
10725
+ },
10726
+ cancel: function(){
10727
+ callback(false);
10728
+ }
10729
+ });
10730
+ },
10731
+
10732
+ confirm_remove: function( $el, callback ){
10733
+
10734
+ var tooltip = acf.newTooltip({
10735
+ confirmRemove: true,
10736
+ target: $el,
10737
+ confirm: function(){
10738
+ callback(true);
10739
+ },
10740
+ cancel: function(){
10741
+ callback(false);
10742
+ }
10743
+ });
10744
+ },
10745
+ };
10746
+
10747
+ /**
10748
+ * tooltip
10749
+ *
10750
+ * description
10751
+ *
10752
+ * @date 15/2/18
10753
+ * @since 5.6.9
10754
+ *
10755
+ * @param type $var Description. Default.
10756
+ * @return type Description.
10757
+ */
10758
+
10759
+ _acf.media = new acf.Model({
10760
+ activeFrame: false,
10761
+ actions: {
10762
+ 'new_media_popup': 'onNewMediaPopup'
10763
+ },
10764
+
10765
+ frame: function(){
10766
+ return this.activeFrame;
10767
+ },
10768
+
10769
+ onNewMediaPopup: function( popup ){
10770
+ this.activeFrame = popup.frame;
10771
+ },
10772
+
10773
+ popup: function( props ){
10774
+
10775
+ // update props
10776
+ if( props.mime_types ) {
10777
+ props.allowedTypes = props.mime_types;
10778
+ }
10779
+ if( props.id ) {
10780
+ props.attachment = props.id;
10781
+ }
10782
+
10783
+ // new
10784
+ var popup = acf.newMediaPopup( props );
10785
+
10786
+ // append
10787
+ /*
10788
+ if( props.selected ) {
10789
+ popup.selected = props.selected;
10790
+ }
10791
+ */
10792
+
10793
+ // return
10794
+ return popup.frame;
10795
+ }
10796
+ });
10797
+
10798
+
10799
+ /**
10800
+ * Select2
10801
+ *
10802
+ * description
10803
+ *
10804
+ * @date 11/6/18
10805
+ * @since 5.6.9
10806
+ *
10807
+ * @param type $var Description. Default.
10808
+ * @return type Description.
10809
+ */
10810
+
10811
+ _acf.select2 = {
10812
+ init: function( $select, args, $field ){
10813
+
10814
+ // compatible args
10815
+ if( args.allow_null ) {
10816
+ args.allowNull = args.allow_null;
10817
+ }
10818
+ if( args.ajax_action ) {
10819
+ args.ajaxAction = args.ajax_action;
10820
+ }
10821
+ if( $field ) {
10822
+ args.field = acf.getField($field);
10823
+ }
10824
+
10825
+ // return
10826
+ return acf.newSelect2( $select, args );
10827
+ },
10828
+
10829
+ destroy: function( $select ){
10830
+ return acf.getInstance( $select ).destroy();
10831
+
10832
+ },
10833
+ };
10834
+
10835
+ /**
10836
+ * postbox
10837
+ *
10838
+ * description
10839
+ *
10840
+ * @date 11/6/18
10841
+ * @since 5.6.9
10842
+ *
10843
+ * @param type $var Description. Default.
10844
+ * @return type Description.
10845
+ */
10846
+
10847
+ _acf.postbox = {
10848
+ render: function( args ){
10849
+
10850
+ // compatible args
10851
+ if( args.edit_url ) {
10852
+ args.editLink = args.edit_url;
10853
+ }
10854
+ if( args.edit_title ) {
10855
+ args.editTitle = args.edit_title;
10856
+ }
10857
+
10858
+ // return
10859
+ return acf.newPostbox( args );
10860
+ }
10861
+ };
10862
+
10863
+ /**
10864
+ * acf.screen
10865
+ *
10866
+ * description
10867
+ *
10868
+ * @date 11/6/18
10869
+ * @since 5.6.9
10870
+ *
10871
+ * @param type $var Description. Default.
10872
+ * @return type Description.
10873
+ */
10874
+
10875
+ acf.newCompatibility(acf.screen, {
10876
+ update: function(){
10877
+ return this.set.apply(this, arguments);
10878
+ },
10879
+ fetch: acf.screen.check
10880
+ });
10881
+ _acf.ajax = acf.screen;
10882
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10883
  })(jQuery);
assets/build/js/acf.js CHANGED
@@ -1,4139 +1,4449 @@
1
- (function ($, undefined) {
2
- /**
3
- * acf
4
- *
5
- * description
6
- *
7
- * @date 14/12/17
8
- * @since 5.6.5
9
- *
10
- * @param type $var Description. Default.
11
- * @return type Description.
12
- */
13
- // The global acf object
14
- var acf = {}; // Set as a browser global
15
-
16
- window.acf = acf;
17
- /** @var object Data sent from PHP */
18
-
19
- acf.data = {};
20
- /**
21
- * get
22
- *
23
- * Gets a specific data value
24
- *
25
- * @date 14/12/17
26
- * @since 5.6.5
27
- *
28
- * @param string name
29
- * @return mixed
30
- */
31
-
32
- acf.get = function (name) {
33
- return this.data[name] || null;
34
- };
35
- /**
36
- * has
37
- *
38
- * Returns `true` if the data exists and is not null
39
- *
40
- * @date 14/12/17
41
- * @since 5.6.5
42
- *
43
- * @param string name
44
- * @return boolean
45
- */
46
-
47
-
48
- acf.has = function (name) {
49
- return this.get(name) !== null;
50
- };
51
- /**
52
- * set
53
- *
54
- * Sets a specific data value
55
- *
56
- * @date 14/12/17
57
- * @since 5.6.5
58
- *
59
- * @param string name
60
- * @param mixed value
61
- * @return this
62
- */
63
-
64
-
65
- acf.set = function (name, value) {
66
- this.data[name] = value;
67
- return this;
68
- };
69
- /**
70
- * uniqueId
71
- *
72
- * Returns a unique ID
73
- *
74
- * @date 9/11/17
75
- * @since 5.6.3
76
- *
77
- * @param string prefix Optional prefix.
78
- * @return string
79
- */
80
-
81
-
82
- var idCounter = 0;
83
-
84
- acf.uniqueId = function (prefix) {
85
- var id = ++idCounter + '';
86
- return prefix ? prefix + id : id;
87
- };
88
- /**
89
- * acf.uniqueArray
90
- *
91
- * Returns a new array with only unique values
92
- * Credit: https://stackoverflow.com/questions/1960473/get-all-unique-values-in-an-array-remove-duplicates
93
- *
94
- * @date 23/3/18
95
- * @since 5.6.9
96
- *
97
- * @param type $var Description. Default.
98
- * @return type Description.
99
- */
100
-
101
-
102
- acf.uniqueArray = function (array) {
103
- function onlyUnique(value, index, self) {
104
- return self.indexOf(value) === index;
105
- }
106
-
107
- return array.filter(onlyUnique);
108
- };
109
- /**
110
- * uniqid
111
- *
112
- * Returns a unique ID (PHP version)
113
- *
114
- * @date 9/11/17
115
- * @since 5.6.3
116
- * @source http://locutus.io/php/misc/uniqid/
117
- *
118
- * @param string prefix Optional prefix.
119
- * @return string
120
- */
121
-
122
-
123
- var uniqidSeed = '';
124
-
125
- acf.uniqid = function (prefix, moreEntropy) {
126
- // discuss at: http://locutus.io/php/uniqid/
127
- // original by: Kevin van Zonneveld (http://kvz.io)
128
- // revised by: Kankrelune (http://www.webfaktory.info/)
129
- // note 1: Uses an internal counter (in locutus global) to avoid collision
130
- // example 1: var $id = uniqid()
131
- // example 1: var $result = $id.length === 13
132
- // returns 1: true
133
- // example 2: var $id = uniqid('foo')
134
- // example 2: var $result = $id.length === (13 + 'foo'.length)
135
- // returns 2: true
136
- // example 3: var $id = uniqid('bar', true)
137
- // example 3: var $result = $id.length === (23 + 'bar'.length)
138
- // returns 3: true
139
- if (typeof prefix === 'undefined') {
140
- prefix = '';
141
- }
142
-
143
- var retId;
144
-
145
- var formatSeed = function (seed, reqWidth) {
146
- seed = parseInt(seed, 10).toString(16); // to hex str
147
-
148
- if (reqWidth < seed.length) {
149
- // so long we split
150
- return seed.slice(seed.length - reqWidth);
151
- }
152
-
153
- if (reqWidth > seed.length) {
154
- // so short we pad
155
- return Array(1 + (reqWidth - seed.length)).join('0') + seed;
156
- }
157
-
158
- return seed;
159
- };
160
-
161
- if (!uniqidSeed) {
162
- // init seed with big random int
163
- uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
164
- }
165
-
166
- uniqidSeed++;
167
- retId = prefix; // start with prefix, add current milliseconds hex string
168
-
169
- retId += formatSeed(parseInt(new Date().getTime() / 1000, 10), 8);
170
- retId += formatSeed(uniqidSeed, 5); // add seed hex string
171
-
172
- if (moreEntropy) {
173
- // for more entropy we add a float lower to 10
174
- retId += (Math.random() * 10).toFixed(8).toString();
175
- }
176
-
177
- return retId;
178
- };
179
- /**
180
- * strReplace
181
- *
182
- * Performs a string replace
183
- *
184
- * @date 14/12/17
185
- * @since 5.6.5
186
- *
187
- * @param string search
188
- * @param string replace
189
- * @param string subject
190
- * @return string
191
- */
192
-
193
-
194
- acf.strReplace = function (search, replace, subject) {
195
- return subject.split(search).join(replace);
196
- };
197
- /**
198
- * strCamelCase
199
- *
200
- * Converts a string into camelCase
201
- * Thanks to https://stackoverflow.com/questions/2970525/converting-any-string-into-camel-case
202
- *
203
- * @date 14/12/17
204
- * @since 5.6.5
205
- *
206
- * @param string str
207
- * @return string
208
- */
209
-
210
-
211
- acf.strCamelCase = function (str) {
212
- var matches = str.match(/([a-zA-Z0-9]+)/g);
213
- return matches ? matches.map(function (s, i) {
214
- var c = s.charAt(0);
215
- return (i === 0 ? c.toLowerCase() : c.toUpperCase()) + s.slice(1);
216
- }).join('') : '';
217
- };
218
- /**
219
- * strPascalCase
220
- *
221
- * Converts a string into PascalCase
222
- * Thanks to https://stackoverflow.com/questions/1026069/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript
223
- *
224
- * @date 14/12/17
225
- * @since 5.6.5
226
- *
227
- * @param string str
228
- * @return string
229
- */
230
-
231
-
232
- acf.strPascalCase = function (str) {
233
- var camel = acf.strCamelCase(str);
234
- return camel.charAt(0).toUpperCase() + camel.slice(1);
235
- };
236
- /**
237
- * acf.strSlugify
238
- *
239
- * Converts a string into a HTML class friendly slug
240
- *
241
- * @date 21/3/18
242
- * @since 5.6.9
243
- *
244
- * @param string str
245
- * @return string
246
- */
247
-
248
-
249
- acf.strSlugify = function (str) {
250
- return acf.strReplace('_', '-', str.toLowerCase());
251
- };
252
-
253
- acf.strSanitize = function (str) {
254
- // chars (https://jsperf.com/replace-foreign-characters)
255
- var map = {
256
- "À": "A",
257
- "Á": "A",
258
- "Â": "A",
259
- "Ã": "A",
260
- "Ä": "A",
261
- "Å": "A",
262
- "Æ": "AE",
263
- "Ç": "C",
264
- "È": "E",
265
- "É": "E",
266
- "Ê": "E",
267
- "Ë": "E",
268
- "Ì": "I",
269
- "Í": "I",
270
- "Î": "I",
271
- "Ï": "I",
272
- "Ð": "D",
273
- "Ñ": "N",
274
- "Ò": "O",
275
- "Ó": "O",
276
- "Ô": "O",
277
- "Õ": "O",
278
- "Ö": "O",
279
- "Ø": "O",
280
- "Ù": "U",
281
- "Ú": "U",
282
- "Û": "U",
283
- "Ü": "U",
284
- "Ý": "Y",
285
- "ß": "s",
286
- "à": "a",
287
- "á": "a",
288
- "â": "a",
289
- "ã": "a",
290
- "ä": "a",
291
- "å": "a",
292
- "æ": "ae",
293
- "ç": "c",
294
- "è": "e",
295
- "é": "e",
296
- "ê": "e",
297
- "ë": "e",
298
- "ì": "i",
299
- "í": "i",
300
- "î": "i",
301
- "ï": "i",
302
- "ñ": "n",
303
- "ò": "o",
304
- "ó": "o",
305
- "ô": "o",
306
- "õ": "o",
307
- "ö": "o",
308
- "ø": "o",
309
- "ù": "u",
310
- "ú": "u",
311
- "û": "u",
312
- "ü": "u",
313
- "ý": "y",
314
- "ÿ": "y",
315
- "Ā": "A",
316
- "ā": "a",
317
- "Ă": "A",
318
- "ă": "a",
319
- "Ą": "A",
320
- "ą": "a",
321
- "Ć": "C",
322
- "ć": "c",
323
- "Ĉ": "C",
324
- "ĉ": "c",
325
- "Ċ": "C",
326
- "ċ": "c",
327
- "Č": "C",
328
- "č": "c",
329
- "Ď": "D",
330
- "ď": "d",
331
- "Đ": "D",
332
- "đ": "d",
333
- "Ē": "E",
334
- "ē": "e",
335
- "Ĕ": "E",
336
- "ĕ": "e",
337
- "Ė": "E",
338
- "ė": "e",
339
- "Ę": "E",
340
- "ę": "e",
341
- "Ě": "E",
342
- "ě": "e",
343
- "Ĝ": "G",
344
- "ĝ": "g",
345
- "Ğ": "G",
346
- "ğ": "g",
347
- "Ġ": "G",
348
- "ġ": "g",
349
- "Ģ": "G",
350
- "ģ": "g",
351
- "Ĥ": "H",
352
- "ĥ": "h",
353
- "Ħ": "H",
354
- "ħ": "h",
355
- "Ĩ": "I",
356
- "ĩ": "i",
357
- "Ī": "I",
358
- "ī": "i",
359
- "Ĭ": "I",
360
- "ĭ": "i",
361
- "Į": "I",
362
- "į": "i",
363
- "İ": "I",
364
- "ı": "i",
365
- "IJ": "IJ",
366
- "ij": "ij",
367
- "Ĵ": "J",
368
- "ĵ": "j",
369
- "Ķ": "K",
370
- "ķ": "k",
371
- "Ĺ": "L",
372
- "ĺ": "l",
373
- "Ļ": "L",
374
- "ļ": "l",
375
- "Ľ": "L",
376
- "ľ": "l",
377
- "Ŀ": "L",
378
- "ŀ": "l",
379
- "Ł": "l",
380
- "ł": "l",
381
- "Ń": "N",
382
- "ń": "n",
383
- "Ņ": "N",
384
- "ņ": "n",
385
- "Ň": "N",
386
- "ň": "n",
387
- "ʼn": "n",
388
- "Ō": "O",
389
- "ō": "o",
390
- "Ŏ": "O",
391
- "ŏ": "o",
392
- "Ő": "O",
393
- "ő": "o",
394
- "Œ": "OE",
395
- "œ": "oe",
396
- "Ŕ": "R",
397
- "ŕ": "r",
398
- "Ŗ": "R",
399
- "ŗ": "r",
400
- "Ř": "R",
401
- "ř": "r",
402
- "Ś": "S",
403
- "ś": "s",
404
- "Ŝ": "S",
405
- "ŝ": "s",
406
- "Ş": "S",
407
- "ş": "s",
408
- "Š": "S",
409
- "š": "s",
410
- "Ţ": "T",
411
- "ţ": "t",
412
- "Ť": "T",
413
- "ť": "t",
414
- "Ŧ": "T",
415
- "ŧ": "t",
416
- "Ũ": "U",
417
- "ũ": "u",
418
- "Ū": "U",
419
- "ū": "u",
420
- "Ŭ": "U",
421
- "ŭ": "u",
422
- "Ů": "U",
423
- "ů": "u",
424
- "Ű": "U",
425
- "ű": "u",
426
- "Ų": "U",
427
- "ų": "u",
428
- "Ŵ": "W",
429
- "ŵ": "w",
430
- "Ŷ": "Y",
431
- "ŷ": "y",
432
- "Ÿ": "Y",
433
- "Ź": "Z",
434
- "ź": "z",
435
- "Ż": "Z",
436
- "ż": "z",
437
- "Ž": "Z",
438
- "ž": "z",
439
- "ſ": "s",
440
- "ƒ": "f",
441
- "Ơ": "O",
442
- "ơ": "o",
443
- "Ư": "U",
444
- "ư": "u",
445
- "Ǎ": "A",
446
- "ǎ": "a",
447
- "Ǐ": "I",
448
- "ǐ": "i",
449
- "Ǒ": "O",
450
- "ǒ": "o",
451
- "Ǔ": "U",
452
- "ǔ": "u",
453
- "Ǖ": "U",
454
- "ǖ": "u",
455
- "Ǘ": "U",
456
- "ǘ": "u",
457
- "Ǚ": "U",
458
- "ǚ": "u",
459
- "Ǜ": "U",
460
- "ǜ": "u",
461
- "Ǻ": "A",
462
- "ǻ": "a",
463
- "Ǽ": "AE",
464
- "ǽ": "ae",
465
- "Ǿ": "O",
466
- "ǿ": "o",
467
- // extra
468
- ' ': '_',
469
- "'": '',
470
- '?': '',
471
- '/': '',
472
- '\\': '',
473
- '.': '',
474
- ',': '',
475
- '`': '',
476
- '>': '',
477
- '<': '',
478
- '"': '',
479
- '[': '',
480
- ']': '',
481
- '|': '',
482
- '{': '',
483
- '}': '',
484
- '(': '',
485
- ')': ''
486
- }; // vars
487
-
488
- var nonWord = /\W/g;
489
-
490
- var mapping = function (c) {
491
- return map[c] !== undefined ? map[c] : c;
492
- }; // replace
493
-
494
-
495
- str = str.replace(nonWord, mapping); // lowercase
496
-
497
- str = str.toLowerCase(); // return
498
-
499
- return str;
500
- };
501
- /**
502
- * acf.strMatch
503
- *
504
- * Returns the number of characters that match between two strings
505
- *
506
- * @date 1/2/18
507
- * @since 5.6.5
508
- *
509
- * @param type $var Description. Default.
510
- * @return type Description.
511
- */
512
-
513
-
514
- acf.strMatch = function (s1, s2) {
515
- // vars
516
- var val = 0;
517
- var min = Math.min(s1.length, s2.length); // loop
518
-
519
- for (var i = 0; i < min; i++) {
520
- if (s1[i] !== s2[i]) {
521
- break;
522
- }
523
-
524
- val++;
525
- } // return
526
-
527
-
528
- return val;
529
- };
530
- /**
531
- * Escapes HTML entities from a string.
532
- *
533
- * @date 08/06/2020
534
- * @since 5.9.0
535
- *
536
- * @param string string The input string.
537
- * @return string
538
- */
539
-
540
-
541
- acf.strEscape = function (string) {
542
- var htmlEscapes = {
543
- '&': '&amp;',
544
- '<': '&lt;',
545
- '>': '&gt;',
546
- '"': '&quot;',
547
- "'": '&#39;'
548
- };
549
- return ('' + string).replace(/[&<>"']/g, function (chr) {
550
- return htmlEscapes[chr];
551
- });
552
- }; // Tests.
553
- //console.log( acf.strEscape('Test 1') );
554
- //console.log( acf.strEscape('Test & 1') );
555
- //console.log( acf.strEscape('Test\'s &amp; 1') );
556
- //console.log( acf.strEscape('<script>js</script>') );
557
-
558
- /**
559
- * Unescapes HTML entities from a string.
560
- *
561
- * @date 08/06/2020
562
- * @since 5.9.0
563
- *
564
- * @param string string The input string.
565
- * @return string
566
- */
567
-
568
-
569
- acf.strUnescape = function (string) {
570
- var htmlUnescapes = {
571
- '&amp;': '&',
572
- '&lt;': '<',
573
- '&gt;': '>',
574
- '&quot;': '"',
575
- '&#39;': "'"
576
- };
577
- return ('' + string).replace(/&amp;|&lt;|&gt;|&quot;|&#39;/g, function (entity) {
578
- return htmlUnescapes[entity];
579
- });
580
- }; // Tests.
581
- //console.log( acf.strUnescape( acf.strEscape('Test 1') ) );
582
- //console.log( acf.strUnescape( acf.strEscape('Test & 1') ) );
583
- //console.log( acf.strUnescape( acf.strEscape('Test\'s &amp; 1') ) );
584
- //console.log( acf.strUnescape( acf.strEscape('<script>js</script>') ) );
585
-
586
- /**
587
- * Escapes HTML entities from a string.
588
- *
589
- * @date 08/06/2020
590
- * @since 5.9.0
591
- *
592
- * @param string string The input string.
593
- * @return string
594
- */
595
-
596
-
597
- acf.escAttr = acf.strEscape;
598
- /**
599
- * Encodes <script> tags for safe HTML output.
600
- *
601
- * @date 08/06/2020
602
- * @since 5.9.0
603
- *
604
- * @param string string The input string.
605
- * @return string
606
- */
607
-
608
- acf.escHtml = function (string) {
609
- return ('' + string).replace(/<script|<\/script/g, function (html) {
610
- return acf.strEscape(html);
611
- });
612
- }; // Tests.
613
- //console.log( acf.escHtml('<script>js</script>') );
614
- //console.log( acf.escHtml( acf.strEscape('<script>js</script>') ) );
615
- //console.log( acf.escHtml( '<script>js1</script><script>js2</script>' ) );
616
-
617
- /**
618
- * acf.decode
619
- *
620
- * description
621
- *
622
- * @date 13/1/18
623
- * @since 5.6.5
624
- *
625
- * @param type $var Description. Default.
626
- * @return type Description.
627
- */
628
-
629
-
630
- acf.decode = function (string) {
631
- return $('<textarea/>').html(string).text();
632
- };
633
- /**
634
- * parseArgs
635
- *
636
- * Merges together defaults and args much like the WP wp_parse_args function
637
- *
638
- * @date 14/12/17
639
- * @since 5.6.5
640
- *
641
- * @param object args
642
- * @param object defaults
643
- * @return object
644
- */
645
-
646
-
647
- acf.parseArgs = function (args, defaults) {
648
- if (typeof args !== 'object') args = {};
649
- if (typeof defaults !== 'object') defaults = {};
650
- return $.extend({}, defaults, args);
651
- };
652
- /**
653
- * __
654
- *
655
- * Retrieve the translation of $text.
656
- *
657
- * @date 16/4/18
658
- * @since 5.6.9
659
- *
660
- * @param string text Text to translate.
661
- * @return string Translated text.
662
- */
663
-
664
-
665
- if (window.acfL10n == undefined) {
666
- acfL10n = {};
667
- }
668
-
669
- acf.__ = function (text) {
670
- return acfL10n[text] || text;
671
- };
672
- /**
673
- * _x
674
- *
675
- * Retrieve translated string with gettext context.
676
- *
677
- * @date 16/4/18
678
- * @since 5.6.9
679
- *
680
- * @param string text Text to translate.
681
- * @param string context Context information for the translators.
682
- * @return string Translated text.
683
- */
684
-
685
-
686
- acf._x = function (text, context) {
687
- return acfL10n[text + '.' + context] || acfL10n[text] || text;
688
- };
689
- /**
690
- * _n
691
- *
692
- * Retrieve the plural or single form based on the amount.
693
- *
694
- * @date 16/4/18
695
- * @since 5.6.9
696
- *
697
- * @param string single Single text to translate.
698
- * @param string plural Plural text to translate.
699
- * @param int number The number to compare against.
700
- * @return string Translated text.
701
- */
702
-
703
-
704
- acf._n = function (single, plural, number) {
705
- if (number == 1) {
706
- return acf.__(single);
707
- } else {
708
- return acf.__(plural);
709
- }
710
- };
711
-
712
- acf.isArray = function (a) {
713
- return Array.isArray(a);
714
- };
715
-
716
- acf.isObject = function (a) {
717
- return typeof a === 'object';
718
- };
719
- /**
720
- * serialize
721
- *
722
- * description
723
- *
724
- * @date 24/12/17
725
- * @since 5.6.5
726
- *
727
- * @param type $var Description. Default.
728
- * @return type Description.
729
- */
730
-
731
-
732
- var buildObject = function (obj, name, value) {
733
- // replace [] with placeholder
734
- name = name.replace('[]', '[%%index%%]'); // vars
735
-
736
- var keys = name.match(/([^\[\]])+/g);
737
- if (!keys) return;
738
- var length = keys.length;
739
- var ref = obj; // loop
740
-
741
- for (var i = 0; i < length; i++) {
742
- // vars
743
- var key = String(keys[i]); // value
744
-
745
- if (i == length - 1) {
746
- // %%index%%
747
- if (key === '%%index%%') {
748
- ref.push(value); // default
749
- } else {
750
- ref[key] = value;
751
- } // path
752
-
753
- } else {
754
- // array
755
- if (keys[i + 1] === '%%index%%') {
756
- if (!acf.isArray(ref[key])) {
757
- ref[key] = [];
758
- } // object
759
-
760
- } else {
761
- if (!acf.isObject(ref[key])) {
762
- ref[key] = {};
763
- }
764
- } // crawl
765
-
766
-
767
- ref = ref[key];
768
- }
769
- }
770
- };
771
-
772
- acf.serialize = function ($el, prefix) {
773
- // vars
774
- var obj = {};
775
- var inputs = acf.serializeArray($el); // prefix
776
-
777
- if (prefix !== undefined) {
778
- // filter and modify
779
- inputs = inputs.filter(function (item) {
780
- return item.name.indexOf(prefix) === 0;
781
- }).map(function (item) {
782
- item.name = item.name.slice(prefix.length);
783
- return item;
784
- });
785
- } // loop
786
-
787
-
788
- for (var i = 0; i < inputs.length; i++) {
789
- buildObject(obj, inputs[i].name, inputs[i].value);
790
- } // return
791
-
792
-
793
- return obj;
794
- };
795
- /**
796
- * acf.serializeArray
797
- *
798
- * Similar to $.serializeArray() but works with a parent wrapping element.
799
- *
800
- * @date 19/8/18
801
- * @since 5.7.3
802
- *
803
- * @param jQuery $el The element or form to serialize.
804
- * @return array
805
- */
806
-
807
-
808
- acf.serializeArray = function ($el) {
809
- return $el.find('select, textarea, input').serializeArray();
810
- };
811
- /**
812
- * acf.serializeForAjax
813
- *
814
- * Returns an object containing name => value data ready to be encoded for Ajax.
815
- *
816
- * @date 17/12/18
817
- * @since 5.8.0
818
- *
819
- * @param jQUery $el The element or form to serialize.
820
- * @return object
821
- */
822
-
823
-
824
- acf.serializeForAjax = function ($el) {
825
- // vars
826
- var data = {};
827
- var index = {}; // Serialize inputs.
828
-
829
- var inputs = acf.serializeArray($el); // Loop over inputs and build data.
830
-
831
- inputs.map(function (item) {
832
- // Append to array.
833
- if (item.name.slice(-2) === '[]') {
834
- data[item.name] = data[item.name] || [];
835
- data[item.name].push(item.value); // Append
836
- } else {
837
- data[item.name] = item.value;
838
- }
839
- }); // return
840
-
841
- return data;
842
- };
843
- /**
844
- * addAction
845
- *
846
- * Wrapper for acf.hooks.addAction
847
- *
848
- * @date 14/12/17
849
- * @since 5.6.5
850
- *
851
- * @param n/a
852
- * @return this
853
- */
854
-
855
- /*
856
- var prefixAction = function( action ){
857
- return 'acf_' + action;
858
- }
859
- */
860
-
861
-
862
- acf.addAction = function (action, callback, priority, context) {
863
- //action = prefixAction(action);
864
- acf.hooks.addAction.apply(this, arguments);
865
- return this;
866
- };
867
- /**
868
- * removeAction
869
- *
870
- * Wrapper for acf.hooks.removeAction
871
- *
872
- * @date 14/12/17
873
- * @since 5.6.5
874
- *
875
- * @param n/a
876
- * @return this
877
- */
878
-
879
-
880
- acf.removeAction = function (action, callback) {
881
- //action = prefixAction(action);
882
- acf.hooks.removeAction.apply(this, arguments);
883
- return this;
884
- };
885
- /**
886
- * doAction
887
- *
888
- * Wrapper for acf.hooks.doAction
889
- *
890
- * @date 14/12/17
891
- * @since 5.6.5
892
- *
893
- * @param n/a
894
- * @return this
895
- */
896
-
897
-
898
- var actionHistory = {}; //var currentAction = false;
899
-
900
- acf.doAction = function (action) {
901
- //action = prefixAction(action);
902
- //currentAction = action;
903
- actionHistory[action] = 1;
904
- acf.hooks.doAction.apply(this, arguments);
905
- actionHistory[action] = 0;
906
- return this;
907
- };
908
- /**
909
- * doingAction
910
- *
911
- * Return true if doing action
912
- *
913
- * @date 14/12/17
914
- * @since 5.6.5
915
- *
916
- * @param n/a
917
- * @return this
918
- */
919
-
920
-
921
- acf.doingAction = function (action) {
922
- //action = prefixAction(action);
923
- return actionHistory[action] === 1;
924
- };
925
- /**
926
- * didAction
927
- *
928
- * Wrapper for acf.hooks.doAction
929
- *
930
- * @date 14/12/17
931
- * @since 5.6.5
932
- *
933
- * @param n/a
934
- * @return this
935
- */
936
-
937
-
938
- acf.didAction = function (action) {
939
- //action = prefixAction(action);
940
- return actionHistory[action] !== undefined;
941
- };
942
- /**
943
- * currentAction
944
- *
945
- * Wrapper for acf.hooks.doAction
946
- *
947
- * @date 14/12/17
948
- * @since 5.6.5
949
- *
950
- * @param n/a
951
- * @return this
952
- */
953
-
954
-
955
- acf.currentAction = function () {
956
- for (var k in actionHistory) {
957
- if (actionHistory[k]) {
958
- return k;
959
- }
960
- }
961
-
962
- return false;
963
- };
964
- /**
965
- * addFilter
966
- *
967
- * Wrapper for acf.hooks.addFilter
968
- *
969
- * @date 14/12/17
970
- * @since 5.6.5
971
- *
972
- * @param n/a
973
- * @return this
974
- */
975
-
976
-
977
- acf.addFilter = function (action) {
978
- //action = prefixAction(action);
979
- acf.hooks.addFilter.apply(this, arguments);
980
- return this;
981
- };
982
- /**
983
- * removeFilter
984
- *
985
- * Wrapper for acf.hooks.removeFilter
986
- *
987
- * @date 14/12/17
988
- * @since 5.6.5
989
- *
990
- * @param n/a
991
- * @return this
992
- */
993
-
994
-
995
- acf.removeFilter = function (action) {
996
- //action = prefixAction(action);
997
- acf.hooks.removeFilter.apply(this, arguments);
998
- return this;
999
- };
1000
- /**
1001
- * applyFilters
1002
- *
1003
- * Wrapper for acf.hooks.applyFilters
1004
- *
1005
- * @date 14/12/17
1006
- * @since 5.6.5
1007
- *
1008
- * @param n/a
1009
- * @return this
1010
- */
1011
-
1012
-
1013
- acf.applyFilters = function (action) {
1014
- //action = prefixAction(action);
1015
- return acf.hooks.applyFilters.apply(this, arguments);
1016
- };
1017
- /**
1018
- * getArgs
1019
- *
1020
- * description
1021
- *
1022
- * @date 15/12/17
1023
- * @since 5.6.5
1024
- *
1025
- * @param type $var Description. Default.
1026
- * @return type Description.
1027
- */
1028
-
1029
-
1030
- acf.arrayArgs = function (args) {
1031
- return Array.prototype.slice.call(args);
1032
- };
1033
- /**
1034
- * extendArgs
1035
- *
1036
- * description
1037
- *
1038
- * @date 15/12/17
1039
- * @since 5.6.5
1040
- *
1041
- * @param type $var Description. Default.
1042
- * @return type Description.
1043
- */
1044
-
1045
- /*
1046
- acf.extendArgs = function( ){
1047
- var args = Array.prototype.slice.call( arguments );
1048
- var realArgs = args.shift();
1049
-
1050
- Array.prototype.push.call(arguments, 'bar')
1051
- return Array.prototype.push.apply( args, arguments );
1052
- };
1053
- */
1054
- // Preferences
1055
- // - use try/catch to avoid JS error if cookies are disabled on front-end form
1056
-
1057
-
1058
- try {
1059
- var preferences = JSON.parse(localStorage.getItem('acf')) || {};
1060
- } catch (e) {
1061
- var preferences = {};
1062
- }
1063
- /**
1064
- * getPreferenceName
1065
- *
1066
- * Gets the true preference name.
1067
- * Converts "this.thing" to "thing-123" if editing post 123.
1068
- *
1069
- * @date 11/11/17
1070
- * @since 5.6.5
1071
- *
1072
- * @param string name
1073
- * @return string
1074
- */
1075
-
1076
-
1077
- var getPreferenceName = function (name) {
1078
- if (name.substr(0, 5) === 'this.') {
1079
- name = name.substr(5) + '-' + acf.get('post_id');
1080
- }
1081
-
1082
- return name;
1083
- };
1084
- /**
1085
- * acf.getPreference
1086
- *
1087
- * Gets a preference setting or null if not set.
1088
- *
1089
- * @date 11/11/17
1090
- * @since 5.6.5
1091
- *
1092
- * @param string name
1093
- * @return mixed
1094
- */
1095
-
1096
-
1097
- acf.getPreference = function (name) {
1098
- name = getPreferenceName(name);
1099
- return preferences[name] || null;
1100
- };
1101
- /**
1102
- * acf.setPreference
1103
- *
1104
- * Sets a preference setting.
1105
- *
1106
- * @date 11/11/17
1107
- * @since 5.6.5
1108
- *
1109
- * @param string name
1110
- * @param mixed value
1111
- * @return n/a
1112
- */
1113
-
1114
-
1115
- acf.setPreference = function (name, value) {
1116
- name = getPreferenceName(name);
1117
-
1118
- if (value === null) {
1119
- delete preferences[name];
1120
- } else {
1121
- preferences[name] = value;
1122
- }
1123
-
1124
- localStorage.setItem('acf', JSON.stringify(preferences));
1125
- };
1126
- /**
1127
- * acf.removePreference
1128
- *
1129
- * Removes a preference setting.
1130
- *
1131
- * @date 11/11/17
1132
- * @since 5.6.5
1133
- *
1134
- * @param string name
1135
- * @return n/a
1136
- */
1137
-
1138
-
1139
- acf.removePreference = function (name) {
1140
- acf.setPreference(name, null);
1141
- };
1142
- /**
1143
- * remove
1144
- *
1145
- * Removes an element with fade effect
1146
- *
1147
- * @date 1/1/18
1148
- * @since 5.6.5
1149
- *
1150
- * @param type $var Description. Default.
1151
- * @return type Description.
1152
- */
1153
-
1154
-
1155
- acf.remove = function (props) {
1156
- // allow jQuery
1157
- if (props instanceof jQuery) {
1158
- props = {
1159
- target: props
1160
- };
1161
- } // defaults
1162
-
1163
-
1164
- props = acf.parseArgs(props, {
1165
- target: false,
1166
- endHeight: 0,
1167
- complete: function () {}
1168
- }); // action
1169
-
1170
- acf.doAction('remove', props.target); // tr
1171
-
1172
- if (props.target.is('tr')) {
1173
- removeTr(props); // div
1174
- } else {
1175
- removeDiv(props);
1176
- }
1177
- };
1178
- /**
1179
- * removeDiv
1180
- *
1181
- * description
1182
- *
1183
- * @date 16/2/18
1184
- * @since 5.6.9
1185
- *
1186
- * @param type $var Description. Default.
1187
- * @return type Description.
1188
- */
1189
-
1190
-
1191
- var removeDiv = function (props) {
1192
- // vars
1193
- var $el = props.target;
1194
- var height = $el.height();
1195
- var width = $el.width();
1196
- var margin = $el.css('margin');
1197
- var outerHeight = $el.outerHeight(true);
1198
- var style = $el.attr('style') + ''; // needed to copy
1199
- // wrap
1200
-
1201
- $el.wrap('<div class="acf-temp-remove" style="height:' + outerHeight + 'px"></div>');
1202
- var $wrap = $el.parent(); // set pos
1203
-
1204
- $el.css({
1205
- height: height,
1206
- width: width,
1207
- margin: margin,
1208
- position: 'absolute'
1209
- }); // fade wrap
1210
-
1211
- setTimeout(function () {
1212
- $wrap.css({
1213
- opacity: 0,
1214
- height: props.endHeight
1215
- });
1216
- }, 50); // remove
1217
-
1218
- setTimeout(function () {
1219
- $el.attr('style', style);
1220
- $wrap.remove();
1221
- props.complete();
1222
- }, 301);
1223
- };
1224
- /**
1225
- * removeTr
1226
- *
1227
- * description
1228
- *
1229
- * @date 16/2/18
1230
- * @since 5.6.9
1231
- *
1232
- * @param type $var Description. Default.
1233
- * @return type Description.
1234
- */
1235
-
1236
-
1237
- var removeTr = function (props) {
1238
- // vars
1239
- var $tr = props.target;
1240
- var height = $tr.height();
1241
- var children = $tr.children().length; // create dummy td
1242
-
1243
- var $td = $('<td class="acf-temp-remove" style="padding:0; height:' + height + 'px" colspan="' + children + '"></td>'); // fade away tr
1244
-
1245
- $tr.addClass('acf-remove-element'); // update HTML after fade animation
1246
-
1247
- setTimeout(function () {
1248
- $tr.html($td);
1249
- }, 251); // allow .acf-temp-remove to exist before changing CSS
1250
-
1251
- setTimeout(function () {
1252
- // remove class
1253
- $tr.removeClass('acf-remove-element'); // collapse
1254
-
1255
- $td.css({
1256
- height: props.endHeight
1257
- });
1258
- }, 300); // remove
1259
-
1260
- setTimeout(function () {
1261
- $tr.remove();
1262
- props.complete();
1263
- }, 451);
1264
- };
1265
- /**
1266
- * duplicate
1267
- *
1268
- * description
1269
- *
1270
- * @date 3/1/18
1271
- * @since 5.6.5
1272
- *
1273
- * @param type $var Description. Default.
1274
- * @return type Description.
1275
- */
1276
-
1277
-
1278
- acf.duplicate = function (args) {
1279
- // allow jQuery
1280
- if (args instanceof jQuery) {
1281
- args = {
1282
- target: args
1283
- };
1284
- } // defaults
1285
-
1286
-
1287
- args = acf.parseArgs(args, {
1288
- target: false,
1289
- search: '',
1290
- replace: '',
1291
- rename: true,
1292
- before: function ($el) {},
1293
- after: function ($el, $el2) {},
1294
- append: function ($el, $el2) {
1295
- $el.after($el2);
1296
- }
1297
- }); // compatibility
1298
-
1299
- args.target = args.target || args.$el; // vars
1300
-
1301
- var $el = args.target; // search
1302
-
1303
- args.search = args.search || $el.attr('data-id');
1304
- args.replace = args.replace || acf.uniqid(); // before
1305
- // - allow acf to modify DOM
1306
- // - fixes bug where select field option is not selected
1307
-
1308
- args.before($el);
1309
- acf.doAction('before_duplicate', $el); // clone
1310
-
1311
- var $el2 = $el.clone(); // rename
1312
-
1313
- if (args.rename) {
1314
- acf.rename({
1315
- target: $el2,
1316
- search: args.search,
1317
- replace: args.replace,
1318
- replacer: typeof args.rename === 'function' ? args.rename : null
1319
- });
1320
- } // remove classes
1321
-
1322
-
1323
- $el2.removeClass('acf-clone');
1324
- $el2.find('.ui-sortable').removeClass('ui-sortable'); // after
1325
- // - allow acf to modify DOM
1326
-
1327
- args.after($el, $el2);
1328
- acf.doAction('after_duplicate', $el, $el2); // append
1329
-
1330
- args.append($el, $el2);
1331
- /**
1332
- * Fires after an element has been duplicated and appended to the DOM.
1333
- *
1334
- * @date 30/10/19
1335
- * @since 5.8.7
1336
- *
1337
- * @param jQuery $el The original element.
1338
- * @param jQuery $el2 The duplicated element.
1339
- */
1340
-
1341
- acf.doAction('duplicate', $el, $el2); // append
1342
-
1343
- acf.doAction('append', $el2); // return
1344
-
1345
- return $el2;
1346
- };
1347
- /**
1348
- * rename
1349
- *
1350
- * description
1351
- *
1352
- * @date 7/1/18
1353
- * @since 5.6.5
1354
- *
1355
- * @param type $var Description. Default.
1356
- * @return type Description.
1357
- */
1358
-
1359
-
1360
- acf.rename = function (args) {
1361
- // Allow jQuery param.
1362
- if (args instanceof jQuery) {
1363
- args = {
1364
- target: args
1365
- };
1366
- } // Apply default args.
1367
-
1368
-
1369
- args = acf.parseArgs(args, {
1370
- target: false,
1371
- destructive: false,
1372
- search: '',
1373
- replace: '',
1374
- replacer: null
1375
- }); // Extract args.
1376
-
1377
- var $el = args.target; // Provide backup for empty args.
1378
-
1379
- if (!args.search) {
1380
- args.search = $el.attr('data-id');
1381
- }
1382
-
1383
- if (!args.replace) {
1384
- args.replace = acf.uniqid('acf');
1385
- }
1386
-
1387
- if (!args.replacer) {
1388
- args.replacer = function (name, value, search, replace) {
1389
- return value.replace(search, replace);
1390
- };
1391
- } // Callback function for jQuery replacing.
1392
-
1393
-
1394
- var withReplacer = function (name) {
1395
- return function (i, value) {
1396
- return args.replacer(name, value, args.search, args.replace);
1397
- };
1398
- }; // Destructive Replace.
1399
-
1400
-
1401
- if (args.destructive) {
1402
- var html = acf.strReplace(args.search, args.replace, $el.outerHTML());
1403
- $el.replaceWith(html); // Standard Replace.
1404
- } else {
1405
- $el.attr('data-id', args.replace);
1406
- $el.find('[id*="' + args.search + '"]').attr('id', withReplacer('id'));
1407
- $el.find('[for*="' + args.search + '"]').attr('for', withReplacer('for'));
1408
- $el.find('[name*="' + args.search + '"]').attr('name', withReplacer('name'));
1409
- } // return
1410
-
1411
-
1412
- return $el;
1413
- };
1414
- /**
1415
- * acf.prepareForAjax
1416
- *
1417
- * description
1418
- *
1419
- * @date 4/1/18
1420
- * @since 5.6.5
1421
- *
1422
- * @param type $var Description. Default.
1423
- * @return type Description.
1424
- */
1425
-
1426
-
1427
- acf.prepareForAjax = function (data) {
1428
- // required
1429
- data.nonce = acf.get('nonce');
1430
- data.post_id = acf.get('post_id'); // language
1431
-
1432
- if (acf.has('language')) {
1433
- data.lang = acf.get('language');
1434
- } // filter for 3rd party customization
1435
-
1436
-
1437
- data = acf.applyFilters('prepare_for_ajax', data); // return
1438
-
1439
- return data;
1440
- };
1441
- /**
1442
- * acf.startButtonLoading
1443
- *
1444
- * description
1445
- *
1446
- * @date 5/1/18
1447
- * @since 5.6.5
1448
- *
1449
- * @param type $var Description. Default.
1450
- * @return type Description.
1451
- */
1452
-
1453
-
1454
- acf.startButtonLoading = function ($el) {
1455
- $el.prop('disabled', true);
1456
- $el.after(' <i class="acf-loading"></i>');
1457
- };
1458
-
1459
- acf.stopButtonLoading = function ($el) {
1460
- $el.prop('disabled', false);
1461
- $el.next('.acf-loading').remove();
1462
- };
1463
- /**
1464
- * acf.showLoading
1465
- *
1466
- * description
1467
- *
1468
- * @date 12/1/18
1469
- * @since 5.6.5
1470
- *
1471
- * @param type $var Description. Default.
1472
- * @return type Description.
1473
- */
1474
-
1475
-
1476
- acf.showLoading = function ($el) {
1477
- $el.append('<div class="acf-loading-overlay"><i class="acf-loading"></i></div>');
1478
- };
1479
-
1480
- acf.hideLoading = function ($el) {
1481
- $el.children('.acf-loading-overlay').remove();
1482
- };
1483
- /**
1484
- * acf.updateUserSetting
1485
- *
1486
- * description
1487
- *
1488
- * @date 5/1/18
1489
- * @since 5.6.5
1490
- *
1491
- * @param type $var Description. Default.
1492
- * @return type Description.
1493
- */
1494
-
1495
-
1496
- acf.updateUserSetting = function (name, value) {
1497
- var ajaxData = {
1498
- action: 'acf/ajax/user_setting',
1499
- name: name,
1500
- value: value
1501
- };
1502
- $.ajax({
1503
- url: acf.get('ajaxurl'),
1504
- data: acf.prepareForAjax(ajaxData),
1505
- type: 'post',
1506
- dataType: 'html'
1507
- });
1508
- };
1509
- /**
1510
- * acf.val
1511
- *
1512
- * description
1513
- *
1514
- * @date 8/1/18
1515
- * @since 5.6.5
1516
- *
1517
- * @param type $var Description. Default.
1518
- * @return type Description.
1519
- */
1520
-
1521
-
1522
- acf.val = function ($input, value, silent) {
1523
- // vars
1524
- var prevValue = $input.val(); // bail if no change
1525
-
1526
- if (value === prevValue) {
1527
- return false;
1528
- } // update value
1529
-
1530
-
1531
- $input.val(value); // prevent select elements displaying blank value if option doesn't exist
1532
-
1533
- if ($input.is('select') && $input.val() === null) {
1534
- $input.val(prevValue);
1535
- return false;
1536
- } // update with trigger
1537
-
1538
-
1539
- if (silent !== true) {
1540
- $input.trigger('change');
1541
- } // return
1542
-
1543
-
1544
- return true;
1545
- };
1546
- /**
1547
- * acf.show
1548
- *
1549
- * description
1550
- *
1551
- * @date 9/2/18
1552
- * @since 5.6.5
1553
- *
1554
- * @param type $var Description. Default.
1555
- * @return type Description.
1556
- */
1557
-
1558
-
1559
- acf.show = function ($el, lockKey) {
1560
- // unlock
1561
- if (lockKey) {
1562
- acf.unlock($el, 'hidden', lockKey);
1563
- } // bail early if $el is still locked
1564
-
1565
-
1566
- if (acf.isLocked($el, 'hidden')) {
1567
- //console.log( 'still locked', getLocks( $el, 'hidden' ));
1568
- return false;
1569
- } // $el is hidden, remove class and return true due to change in visibility
1570
-
1571
-
1572
- if ($el.hasClass('acf-hidden')) {
1573
- $el.removeClass('acf-hidden');
1574
- return true; // $el is visible, return false due to no change in visibility
1575
- } else {
1576
- return false;
1577
- }
1578
- };
1579
- /**
1580
- * acf.hide
1581
- *
1582
- * description
1583
- *
1584
- * @date 9/2/18
1585
- * @since 5.6.5
1586
- *
1587
- * @param type $var Description. Default.
1588
- * @return type Description.
1589
- */
1590
-
1591
-
1592
- acf.hide = function ($el, lockKey) {
1593
- // lock
1594
- if (lockKey) {
1595
- acf.lock($el, 'hidden', lockKey);
1596
- } // $el is hidden, return false due to no change in visibility
1597
-
1598
-
1599
- if ($el.hasClass('acf-hidden')) {
1600
- return false; // $el is visible, add class and return true due to change in visibility
1601
- } else {
1602
- $el.addClass('acf-hidden');
1603
- return true;
1604
- }
1605
- };
1606
- /**
1607
- * acf.isHidden
1608
- *
1609
- * description
1610
- *
1611
- * @date 9/2/18
1612
- * @since 5.6.5
1613
- *
1614
- * @param type $var Description. Default.
1615
- * @return type Description.
1616
- */
1617
-
1618
-
1619
- acf.isHidden = function ($el) {
1620
- return $el.hasClass('acf-hidden');
1621
- };
1622
- /**
1623
- * acf.isVisible
1624
- *
1625
- * description
1626
- *
1627
- * @date 9/2/18
1628
- * @since 5.6.5
1629
- *
1630
- * @param type $var Description. Default.
1631
- * @return type Description.
1632
- */
1633
-
1634
-
1635
- acf.isVisible = function ($el) {
1636
- return !acf.isHidden($el);
1637
- };
1638
- /**
1639
- * enable
1640
- *
1641
- * description
1642
- *
1643
- * @date 12/3/18
1644
- * @since 5.6.9
1645
- *
1646
- * @param type $var Description. Default.
1647
- * @return type Description.
1648
- */
1649
-
1650
-
1651
- var enable = function ($el, lockKey) {
1652
- // check class. Allow .acf-disabled to overrule all JS
1653
- if ($el.hasClass('acf-disabled')) {
1654
- return false;
1655
- } // unlock
1656
-
1657
-
1658
- if (lockKey) {
1659
- acf.unlock($el, 'disabled', lockKey);
1660
- } // bail early if $el is still locked
1661
-
1662
-
1663
- if (acf.isLocked($el, 'disabled')) {
1664
- return false;
1665
- } // $el is disabled, remove prop and return true due to change
1666
-
1667
-
1668
- if ($el.prop('disabled')) {
1669
- $el.prop('disabled', false);
1670
- return true; // $el is enabled, return false due to no change
1671
- } else {
1672
- return false;
1673
- }
1674
- };
1675
- /**
1676
- * acf.enable
1677
- *
1678
- * description
1679
- *
1680
- * @date 9/2/18
1681
- * @since 5.6.5
1682
- *
1683
- * @param type $var Description. Default.
1684
- * @return type Description.
1685
- */
1686
-
1687
-
1688
- acf.enable = function ($el, lockKey) {
1689
- // enable single input
1690
- if ($el.attr('name')) {
1691
- return enable($el, lockKey);
1692
- } // find and enable child inputs
1693
- // return true if any inputs have changed
1694
-
1695
-
1696
- var results = false;
1697
- $el.find('[name]').each(function () {
1698
- var result = enable($(this), lockKey);
1699
-
1700
- if (result) {
1701
- results = true;
1702
- }
1703
- });
1704
- return results;
1705
- };
1706
- /**
1707
- * disable
1708
- *
1709
- * description
1710
- *
1711
- * @date 12/3/18
1712
- * @since 5.6.9
1713
- *
1714
- * @param type $var Description. Default.
1715
- * @return type Description.
1716
- */
1717
-
1718
-
1719
- var disable = function ($el, lockKey) {
1720
- // lock
1721
- if (lockKey) {
1722
- acf.lock($el, 'disabled', lockKey);
1723
- } // $el is disabled, return false due to no change
1724
-
1725
-
1726
- if ($el.prop('disabled')) {
1727
- return false; // $el is enabled, add prop and return true due to change
1728
- } else {
1729
- $el.prop('disabled', true);
1730
- return true;
1731
- }
1732
- };
1733
- /**
1734
- * acf.disable
1735
- *
1736
- * description
1737
- *
1738
- * @date 9/2/18
1739
- * @since 5.6.5
1740
- *
1741
- * @param type $var Description. Default.
1742
- * @return type Description.
1743
- */
1744
-
1745
-
1746
- acf.disable = function ($el, lockKey) {
1747
- // disable single input
1748
- if ($el.attr('name')) {
1749
- return disable($el, lockKey);
1750
- } // find and enable child inputs
1751
- // return true if any inputs have changed
1752
-
1753
-
1754
- var results = false;
1755
- $el.find('[name]').each(function () {
1756
- var result = disable($(this), lockKey);
1757
-
1758
- if (result) {
1759
- results = true;
1760
- }
1761
- });
1762
- return results;
1763
- };
1764
- /**
1765
- * acf.isset
1766
- *
1767
- * description
1768
- *
1769
- * @date 10/1/18
1770
- * @since 5.6.5
1771
- *
1772
- * @param type $var Description. Default.
1773
- * @return type Description.
1774
- */
1775
-
1776
-
1777
- acf.isset = function (obj
1778
- /*, level1, level2, ... */
1779
- ) {
1780
- for (var i = 1; i < arguments.length; i++) {
1781
- if (!obj || !obj.hasOwnProperty(arguments[i])) {
1782
- return false;
1783
- }
1784
-
1785
- obj = obj[arguments[i]];
1786
- }
1787
-
1788
- return true;
1789
- };
1790
- /**
1791
- * acf.isget
1792
- *
1793
- * description
1794
- *
1795
- * @date 10/1/18
1796
- * @since 5.6.5
1797
- *
1798
- * @param type $var Description. Default.
1799
- * @return type Description.
1800
- */
1801
-
1802
-
1803
- acf.isget = function (obj
1804
- /*, level1, level2, ... */
1805
- ) {
1806
- for (var i = 1; i < arguments.length; i++) {
1807
- if (!obj || !obj.hasOwnProperty(arguments[i])) {
1808
- return null;
1809
- }
1810
-
1811
- obj = obj[arguments[i]];
1812
- }
1813
-
1814
- return obj;
1815
- };
1816
- /**
1817
- * acf.getFileInputData
1818
- *
1819
- * description
1820
- *
1821
- * @date 10/1/18
1822
- * @since 5.6.5
1823
- *
1824
- * @param type $var Description. Default.
1825
- * @return type Description.
1826
- */
1827
-
1828
-
1829
- acf.getFileInputData = function ($input, callback) {
1830
- // vars
1831
- var value = $input.val(); // bail early if no value
1832
-
1833
- if (!value) {
1834
- return false;
1835
- } // data
1836
-
1837
-
1838
- var data = {
1839
- url: value
1840
- }; // modern browsers
1841
-
1842
- var file = acf.isget($input[0], 'files', 0);
1843
-
1844
- if (file) {
1845
- // update data
1846
- data.size = file.size;
1847
- data.type = file.type; // image
1848
-
1849
- if (file.type.indexOf('image') > -1) {
1850
- // vars
1851
- var windowURL = window.URL || window.webkitURL;
1852
- var img = new Image();
1853
-
1854
- img.onload = function () {
1855
- // update
1856
- data.width = this.width;
1857
- data.height = this.height;
1858
- callback(data);
1859
- };
1860
-
1861
- img.src = windowURL.createObjectURL(file);
1862
- } else {
1863
- callback(data);
1864
- }
1865
- } else {
1866
- callback(data);
1867
- }
1868
- };
1869
- /**
1870
- * acf.isAjaxSuccess
1871
- *
1872
- * description
1873
- *
1874
- * @date 18/1/18
1875
- * @since 5.6.5
1876
- *
1877
- * @param type $var Description. Default.
1878
- * @return type Description.
1879
- */
1880
-
1881
-
1882
- acf.isAjaxSuccess = function (json) {
1883
- return json && json.success;
1884
- };
1885
- /**
1886
- * acf.getAjaxMessage
1887
- *
1888
- * description
1889
- *
1890
- * @date 18/1/18
1891
- * @since 5.6.5
1892
- *
1893
- * @param type $var Description. Default.
1894
- * @return type Description.
1895
- */
1896
-
1897
-
1898
- acf.getAjaxMessage = function (json) {
1899
- return acf.isget(json, 'data', 'message');
1900
- };
1901
- /**
1902
- * acf.getAjaxError
1903
- *
1904
- * description
1905
- *
1906
- * @date 18/1/18
1907
- * @since 5.6.5
1908
- *
1909
- * @param type $var Description. Default.
1910
- * @return type Description.
1911
- */
1912
-
1913
-
1914
- acf.getAjaxError = function (json) {
1915
- return acf.isget(json, 'data', 'error');
1916
- };
1917
- /**
1918
- * Returns the error message from an XHR object.
1919
- *
1920
- * @date 17/3/20
1921
- * @since 5.8.9
1922
- *
1923
- * @param object xhr The XHR object.
1924
- * @return (string)
1925
- */
1926
-
1927
-
1928
- acf.getXhrError = function (xhr) {
1929
- if (xhr.responseJSON && xhr.responseJSON.message) {
1930
- return xhr.responseJSON.message;
1931
- } else if (xhr.statusText) {
1932
- return xhr.statusText;
1933
- }
1934
-
1935
- return "";
1936
- };
1937
- /**
1938
- * acf.renderSelect
1939
- *
1940
- * Renders the innter html for a select field.
1941
- *
1942
- * @date 19/2/18
1943
- * @since 5.6.9
1944
- *
1945
- * @param jQuery $select The select element.
1946
- * @param array choices An array of choices.
1947
- * @return void
1948
- */
1949
-
1950
-
1951
- acf.renderSelect = function ($select, choices) {
1952
- // vars
1953
- var value = $select.val();
1954
- var values = []; // callback
1955
-
1956
- var crawl = function (items) {
1957
- // vars
1958
- var itemsHtml = ''; // loop
1959
-
1960
- items.map(function (item) {
1961
- // vars
1962
- var text = item.text || item.label || '';
1963
- var id = item.id || item.value || ''; // append
1964
-
1965
- values.push(id); // optgroup
1966
-
1967
- if (item.children) {
1968
- itemsHtml += '<optgroup label="' + acf.escAttr(text) + '">' + crawl(item.children) + '</optgroup>'; // option
1969
- } else {
1970
- itemsHtml += '<option value="' + acf.escAttr(id) + '"' + (item.disabled ? ' disabled="disabled"' : '') + '>' + acf.strEscape(text) + '</option>';
1971
- }
1972
- }); // return
1973
-
1974
- return itemsHtml;
1975
- }; // update HTML
1976
-
1977
-
1978
- $select.html(crawl(choices)); // update value
1979
-
1980
- if (values.indexOf(value) > -1) {
1981
- $select.val(value);
1982
- } // return selected value
1983
-
1984
-
1985
- return $select.val();
1986
- };
1987
- /**
1988
- * acf.lock
1989
- *
1990
- * Creates a "lock" on an element for a given type and key
1991
- *
1992
- * @date 22/2/18
1993
- * @since 5.6.9
1994
- *
1995
- * @param jQuery $el The element to lock.
1996
- * @param string type The type of lock such as "condition" or "visibility".
1997
- * @param string key The key that will be used to unlock.
1998
- * @return void
1999
- */
2000
-
2001
-
2002
- var getLocks = function ($el, type) {
2003
- return $el.data('acf-lock-' + type) || [];
2004
- };
2005
-
2006
- var setLocks = function ($el, type, locks) {
2007
- $el.data('acf-lock-' + type, locks);
2008
- };
2009
-
2010
- acf.lock = function ($el, type, key) {
2011
- var locks = getLocks($el, type);
2012
- var i = locks.indexOf(key);
2013
-
2014
- if (i < 0) {
2015
- locks.push(key);
2016
- setLocks($el, type, locks);
2017
- }
2018
- };
2019
- /**
2020
- * acf.unlock
2021
- *
2022
- * Unlocks a "lock" on an element for a given type and key
2023
- *
2024
- * @date 22/2/18
2025
- * @since 5.6.9
2026
- *
2027
- * @param jQuery $el The element to lock.
2028
- * @param string type The type of lock such as "condition" or "visibility".
2029
- * @param string key The key that will be used to unlock.
2030
- * @return void
2031
- */
2032
-
2033
-
2034
- acf.unlock = function ($el, type, key) {
2035
- var locks = getLocks($el, type);
2036
- var i = locks.indexOf(key);
2037
-
2038
- if (i > -1) {
2039
- locks.splice(i, 1);
2040
- setLocks($el, type, locks);
2041
- } // return true if is unlocked (no locks)
2042
-
2043
-
2044
- return locks.length === 0;
2045
- };
2046
- /**
2047
- * acf.isLocked
2048
- *
2049
- * Returns true if a lock exists for a given type
2050
- *
2051
- * @date 22/2/18
2052
- * @since 5.6.9
2053
- *
2054
- * @param jQuery $el The element to lock.
2055
- * @param string type The type of lock such as "condition" or "visibility".
2056
- * @return void
2057
- */
2058
-
2059
-
2060
- acf.isLocked = function ($el, type) {
2061
- return getLocks($el, type).length > 0;
2062
- };
2063
- /**
2064
- * acf.isGutenberg
2065
- *
2066
- * Returns true if the Gutenberg editor is being used.
2067
- *
2068
- * @date 14/11/18
2069
- * @since 5.8.0
2070
- *
2071
- * @param vois
2072
- * @return bool
2073
- */
2074
-
2075
-
2076
- acf.isGutenberg = function () {
2077
- return !!(window.wp && wp.data && wp.data.select && wp.data.select('core/editor'));
2078
- };
2079
- /**
2080
- * acf.objectToArray
2081
- *
2082
- * Returns an array of items from the given object.
2083
- *
2084
- * @date 20/11/18
2085
- * @since 5.8.0
2086
- *
2087
- * @param object obj The object of items.
2088
- * @return array
2089
- */
2090
-
2091
-
2092
- acf.objectToArray = function (obj) {
2093
- return Object.keys(obj).map(function (key) {
2094
- return obj[key];
2095
- });
2096
- };
2097
- /**
2098
- * acf.debounce
2099
- *
2100
- * Returns a debounced version of the passed function which will postpone its execution until after `wait` milliseconds have elapsed since the last time it was invoked.
2101
- *
2102
- * @date 28/8/19
2103
- * @since 5.8.1
2104
- *
2105
- * @param function callback The callback function.
2106
- * @return int wait The number of milliseconds to wait.
2107
- */
2108
-
2109
-
2110
- acf.debounce = function (callback, wait) {
2111
- var timeout;
2112
- return function () {
2113
- var context = this;
2114
- var args = arguments;
2115
-
2116
- var later = function () {
2117
- callback.apply(context, args);
2118
- };
2119
-
2120
- clearTimeout(timeout);
2121
- timeout = setTimeout(later, wait);
2122
- };
2123
- };
2124
- /**
2125
- * acf.throttle
2126
- *
2127
- * Returns a throttled version of the passed function which will allow only one execution per `limit` time period.
2128
- *
2129
- * @date 28/8/19
2130
- * @since 5.8.1
2131
- *
2132
- * @param function callback The callback function.
2133
- * @return int wait The number of milliseconds to wait.
2134
- */
2135
-
2136
-
2137
- acf.throttle = function (callback, limit) {
2138
- var busy = false;
2139
- return function () {
2140
- if (busy) return;
2141
- busy = true;
2142
- setTimeout(function () {
2143
- busy = false;
2144
- }, limit);
2145
- callback.apply(this, arguments);
2146
- };
2147
- };
2148
- /**
2149
- * acf.isInView
2150
- *
2151
- * Returns true if the given element is in view.
2152
- *
2153
- * @date 29/8/19
2154
- * @since 5.8.1
2155
- *
2156
- * @param elem el The dom element to inspect.
2157
- * @return bool
2158
- */
2159
-
2160
-
2161
- acf.isInView = function (el) {
2162
- if (el instanceof jQuery) {
2163
- el = el[0];
2164
- }
2165
-
2166
- var rect = el.getBoundingClientRect();
2167
- return rect.top !== rect.bottom && rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
2168
- };
2169
- /**
2170
- * acf.onceInView
2171
- *
2172
- * Watches for a dom element to become visible in the browser and then excecutes the passed callback.
2173
- *
2174
- * @date 28/8/19
2175
- * @since 5.8.1
2176
- *
2177
- * @param dom el The dom element to inspect.
2178
- * @param function callback The callback function.
2179
- */
2180
-
2181
-
2182
- acf.onceInView = function () {
2183
- // Define list.
2184
- var items = [];
2185
- var id = 0; // Define check function.
2186
-
2187
- var check = function () {
2188
- items.forEach(function (item) {
2189
- if (acf.isInView(item.el)) {
2190
- item.callback.apply(this);
2191
- pop(item.id);
2192
- }
2193
- });
2194
- }; // And create a debounced version.
2195
-
2196
-
2197
- var debounced = acf.debounce(check, 300); // Define add function.
2198
-
2199
- var push = function (el, callback) {
2200
- // Add event listener.
2201
- if (!items.length) {
2202
- $(window).on('scroll resize', debounced).on('acfrefresh orientationchange', check);
2203
- } // Append to list.
2204
-
2205
-
2206
- items.push({
2207
- id: id++,
2208
- el: el,
2209
- callback: callback
2210
- });
2211
- }; // Define remove function.
2212
-
2213
-
2214
- var pop = function (id) {
2215
- // Remove from list.
2216
- items = items.filter(function (item) {
2217
- return item.id !== id;
2218
- }); // Clean up listener.
2219
-
2220
- if (!items.length) {
2221
- $(window).off('scroll resize', debounced).off('acfrefresh orientationchange', check);
2222
- }
2223
- }; // Define returned function.
2224
-
2225
-
2226
- return function (el, callback) {
2227
- // Allow jQuery object.
2228
- if (el instanceof jQuery) el = el[0]; // Execute callback if already in view or add to watch list.
2229
-
2230
- if (acf.isInView(el)) {
2231
- callback.apply(this);
2232
- } else {
2233
- push(el, callback);
2234
- }
2235
- };
2236
- }();
2237
- /**
2238
- * acf.once
2239
- *
2240
- * Creates a function that is restricted to invoking `func` once.
2241
- *
2242
- * @date 2/9/19
2243
- * @since 5.8.1
2244
- *
2245
- * @param function func The function to restrict.
2246
- * @return function
2247
- */
2248
-
2249
-
2250
- acf.once = function (func) {
2251
- var i = 0;
2252
- return function () {
2253
- if (i++ > 0) {
2254
- return func = undefined;
2255
- }
2256
-
2257
- return func.apply(this, arguments);
2258
- };
2259
- };
2260
- /**
2261
- * Focuses attention to a specific element.
2262
- *
2263
- * @date 05/05/2020
2264
- * @since 5.9.0
2265
- *
2266
- * @param jQuery $el The jQuery element to focus.
2267
- * @return void
2268
- */
2269
-
2270
-
2271
- acf.focusAttention = function ($el) {
2272
- var wait = 1000; // Apply class to focus attention.
2273
-
2274
- $el.addClass('acf-attention -focused'); // Scroll to element if needed.
2275
-
2276
- var scrollTime = 500;
2277
-
2278
- if (!acf.isInView($el)) {
2279
- $('body, html').animate({
2280
- scrollTop: $el.offset().top - $(window).height() / 2
2281
- }, scrollTime);
2282
- wait += scrollTime;
2283
- } // Remove class after $wait amount of time.
2284
-
2285
-
2286
- var fadeTime = 250;
2287
- setTimeout(function () {
2288
- $el.removeClass('-focused');
2289
- setTimeout(function () {
2290
- $el.removeClass('acf-attention');
2291
- }, fadeTime);
2292
- }, wait);
2293
- };
2294
- /**
2295
- * Description
2296
- *
2297
- * @date 05/05/2020
2298
- * @since 5.9.0
2299
- *
2300
- * @param type Var Description.
2301
- * @return type Description.
2302
- */
2303
-
2304
-
2305
- acf.onFocus = function ($el, callback) {
2306
- // Only run once per element.
2307
- // if( $el.data('acf.onFocus') ) {
2308
- // return false;
2309
- // }
2310
- // Vars.
2311
- var ignoreBlur = false;
2312
- var focus = false; // Functions.
2313
-
2314
- var onFocus = function () {
2315
- ignoreBlur = true;
2316
- setTimeout(function () {
2317
- ignoreBlur = false;
2318
- }, 1);
2319
- setFocus(true);
2320
- };
2321
-
2322
- var onBlur = function () {
2323
- if (!ignoreBlur) {
2324
- setFocus(false);
2325
- }
2326
- };
2327
-
2328
- var addEvents = function () {
2329
- $(document).on('click', onBlur); //$el.on('acfBlur', onBlur);
2330
-
2331
- $el.on('blur', 'input, select, textarea', onBlur);
2332
- };
2333
-
2334
- var removeEvents = function () {
2335
- $(document).off('click', onBlur); //$el.off('acfBlur', onBlur);
2336
-
2337
- $el.off('blur', 'input, select, textarea', onBlur);
2338
- };
2339
-
2340
- var setFocus = function (value) {
2341
- if (focus === value) {
2342
- return;
2343
- }
2344
-
2345
- if (value) {
2346
- addEvents();
2347
- } else {
2348
- removeEvents();
2349
- }
2350
-
2351
- focus = value;
2352
- callback(value);
2353
- }; // Add events and set data.
2354
-
2355
-
2356
- $el.on('click', onFocus); //$el.on('acfFocus', onFocus);
2357
-
2358
- $el.on('focus', 'input, select, textarea', onFocus); //$el.data('acf.onFocus', true);
2359
- };
2360
- /*
2361
- * exists
2362
- *
2363
- * This function will return true if a jQuery selection exists
2364
- *
2365
- * @type function
2366
- * @date 8/09/2014
2367
- * @since 5.0.0
2368
- *
2369
- * @param n/a
2370
- * @return (boolean)
2371
- */
2372
-
2373
-
2374
- $.fn.exists = function () {
2375
- return $(this).length > 0;
2376
- };
2377
- /*
2378
- * outerHTML
2379
- *
2380
- * This function will return a string containing the HTML of the selected element
2381
- *
2382
- * @type function
2383
- * @date 19/11/2013
2384
- * @since 5.0.0
2385
- *
2386
- * @param $.fn
2387
- * @return (string)
2388
- */
2389
-
2390
-
2391
- $.fn.outerHTML = function () {
2392
- return $(this).get(0).outerHTML;
2393
- };
2394
- /*
2395
- * indexOf
2396
- *
2397
- * This function will provide compatibility for ie8
2398
- *
2399
- * @type function
2400
- * @date 5/3/17
2401
- * @since 5.5.10
2402
- *
2403
- * @param n/a
2404
- * @return n/a
2405
- */
2406
-
2407
-
2408
- if (!Array.prototype.indexOf) {
2409
- Array.prototype.indexOf = function (val) {
2410
- return $.inArray(val, this);
2411
- };
2412
- }
2413
- /**
2414
- * Returns true if value is a number or a numeric string.
2415
- *
2416
- * @date 30/11/20
2417
- * @since 5.9.4
2418
- * @link https://stackoverflow.com/questions/9716468/pure-javascript-a-function-like-jquerys-isnumeric/9716488#9716488
2419
- *
2420
- * @param mixed n The variable being evaluated.
2421
- * @return bool.
2422
- */
2423
-
2424
-
2425
- acf.isNumeric = function (n) {
2426
- return !isNaN(parseFloat(n)) && isFinite(n);
2427
- };
2428
- /**
2429
- * Triggers a "refresh" action used by various Components to redraw the DOM.
2430
- *
2431
- * @date 26/05/2020
2432
- * @since 5.9.0
2433
- *
2434
- * @param void
2435
- * @return void
2436
- */
2437
-
2438
-
2439
- acf.refresh = acf.debounce(function () {
2440
- $(window).trigger('acfrefresh');
2441
- acf.doAction('refresh');
2442
- }, 0); // Set up actions from events
2443
-
2444
- $(document).ready(function () {
2445
- acf.doAction('ready');
2446
- });
2447
- $(window).on('load', function () {
2448
- // Use timeout to ensure action runs after Gutenberg has modified DOM elements during "DOMContentLoaded".
2449
- setTimeout(function () {
2450
- acf.doAction('load');
2451
- });
2452
- });
2453
- $(window).on('beforeunload', function () {
2454
- acf.doAction('unload');
2455
- });
2456
- $(window).on('resize', function () {
2457
- acf.doAction('resize');
2458
- });
2459
- $(document).on('sortstart', function (event, ui) {
2460
- acf.doAction('sortstart', ui.item, ui.placeholder);
2461
- });
2462
- $(document).on('sortstop', function (event, ui) {
2463
- acf.doAction('sortstop', ui.item, ui.placeholder);
2464
- });
2465
- })(jQuery);
2466
-
2467
- (function (window, undefined) {
2468
- "use strict";
2469
- /**
2470
- * Handles managing all events for whatever you plug it into. Priorities for hooks are based on lowest to highest in
2471
- * that, lowest priority hooks are fired first.
2472
- */
2473
-
2474
- var EventManager = function () {
2475
- /**
2476
- * Maintain a reference to the object scope so our public methods never get confusing.
2477
- */
2478
- var MethodsAvailable = {
2479
- removeFilter: removeFilter,
2480
- applyFilters: applyFilters,
2481
- addFilter: addFilter,
2482
- removeAction: removeAction,
2483
- doAction: doAction,
2484
- addAction: addAction,
2485
- storage: getStorage
2486
- };
2487
- /**
2488
- * Contains the hooks that get registered with this EventManager. The array for storage utilizes a "flat"
2489
- * object literal such that looking up the hook utilizes the native object literal hash.
2490
- */
2491
-
2492
- var STORAGE = {
2493
- actions: {},
2494
- filters: {}
2495
- };
2496
-
2497
- function getStorage() {
2498
- return STORAGE;
2499
- }
2500
-
2501
- ;
2502
- /**
2503
- * Adds an action to the event manager.
2504
- *
2505
- * @param action Must contain namespace.identifier
2506
- * @param callback Must be a valid callback function before this action is added
2507
- * @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
2508
- * @param [context] Supply a value to be used for this
2509
- */
2510
-
2511
- function addAction(action, callback, priority, context) {
2512
- if (typeof action === 'string' && typeof callback === 'function') {
2513
- priority = parseInt(priority || 10, 10);
2514
-
2515
- _addHook('actions', action, callback, priority, context);
2516
- }
2517
-
2518
- return MethodsAvailable;
2519
- }
2520
- /**
2521
- * Performs an action if it exists. You can pass as many arguments as you want to this function; the only rule is
2522
- * that the first argument must always be the action.
2523
- */
2524
-
2525
-
2526
- function doAction()
2527
- /* action, arg1, arg2, ... */
2528
- {
2529
- var args = Array.prototype.slice.call(arguments);
2530
- var action = args.shift();
2531
-
2532
- if (typeof action === 'string') {
2533
- _runHook('actions', action, args);
2534
- }
2535
-
2536
- return MethodsAvailable;
2537
- }
2538
- /**
2539
- * Removes the specified action if it contains a namespace.identifier & exists.
2540
  *
2541
- * @param action The action to remove
2542
- * @param [callback] Callback function to remove
2543
- */
2544
-
2545
-
2546
- function removeAction(action, callback) {
2547
- if (typeof action === 'string') {
2548
- _removeHook('actions', action, callback);
2549
- }
2550
-
2551
- return MethodsAvailable;
2552
- }
2553
- /**
2554
- * Adds a filter to the event manager.
2555
  *
2556
- * @param filter Must contain namespace.identifier
2557
- * @param callback Must be a valid callback function before this action is added
2558
- * @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
2559
- * @param [context] Supply a value to be used for this
2560
- */
2561
-
2562
-
2563
- function addFilter(filter, callback, priority, context) {
2564
- if (typeof filter === 'string' && typeof callback === 'function') {
2565
- priority = parseInt(priority || 10, 10);
2566
-
2567
- _addHook('filters', filter, callback, priority, context);
2568
- }
2569
-
2570
- return MethodsAvailable;
2571
- }
2572
- /**
2573
- * Performs a filter if it exists. You should only ever pass 1 argument to be filtered. The only rule is that
2574
- * the first argument must always be the filter.
2575
  */
2576
-
2577
-
2578
- function applyFilters()
2579
- /* filter, filtered arg, arg2, ... */
2580
- {
2581
- var args = Array.prototype.slice.call(arguments);
2582
- var filter = args.shift();
2583
-
2584
- if (typeof filter === 'string') {
2585
- return _runHook('filters', filter, args);
2586
- }
2587
-
2588
- return MethodsAvailable;
2589
- }
2590
- /**
2591
- * Removes the specified filter if it contains a namespace.identifier & exists.
 
 
 
 
 
 
 
 
 
 
 
2592
  *
2593
- * @param filter The action to remove
2594
- * @param [callback] Callback function to remove
2595
- */
2596
-
2597
-
2598
- function removeFilter(filter, callback) {
2599
- if (typeof filter === 'string') {
2600
- _removeHook('filters', filter, callback);
2601
- }
2602
-
2603
- return MethodsAvailable;
2604
- }
2605
- /**
2606
- * Removes the specified hook by resetting the value of it.
2607
  *
2608
- * @param type Type of hook, either 'actions' or 'filters'
2609
- * @param hook The hook (namespace.identifier) to remove
2610
- * @private
2611
  */
2612
-
2613
-
2614
- function _removeHook(type, hook, callback, context) {
2615
- if (!STORAGE[type][hook]) {
2616
- return;
2617
- }
2618
-
2619
- if (!callback) {
2620
- STORAGE[type][hook] = [];
2621
- } else {
2622
- var handlers = STORAGE[type][hook];
2623
- var i;
2624
-
2625
- if (!context) {
2626
- for (i = handlers.length; i--;) {
2627
- if (handlers[i].callback === callback) {
2628
- handlers.splice(i, 1);
 
 
 
 
 
2629
  }
2630
- }
2631
- } else {
2632
- for (i = handlers.length; i--;) {
2633
- var handler = handlers[i];
2634
-
2635
- if (handler.callback === callback && handler.context === context) {
2636
- handlers.splice(i, 1);
 
 
 
 
 
 
 
2637
  }
2638
- }
2639
- }
2640
- }
2641
- }
2642
- /**
2643
- * Adds the hook to the appropriate storage container
2644
- *
2645
- * @param type 'actions' or 'filters'
2646
- * @param hook The hook (namespace.identifier) to add to our event manager
2647
- * @param callback The function that will be called when the hook is executed.
2648
- * @param priority The priority of this hook. Must be an integer.
2649
- * @param [context] A value to be used for this
2650
- * @private
2651
- */
2652
-
2653
-
2654
- function _addHook(type, hook, callback, priority, context) {
2655
- var hookObject = {
2656
- callback: callback,
2657
- priority: priority,
2658
- context: context
2659
- }; // Utilize 'prop itself' : http://jsperf.com/hasownproperty-vs-in-vs-undefined/19
2660
-
2661
- var hooks = STORAGE[type][hook];
2662
-
2663
- if (hooks) {
2664
- hooks.push(hookObject);
2665
- hooks = _hookInsertSort(hooks);
2666
- } else {
2667
- hooks = [hookObject];
2668
- }
2669
-
2670
- STORAGE[type][hook] = hooks;
2671
- }
2672
- /**
2673
- * Use an insert sort for keeping our hooks organized based on priority. This function is ridiculously faster
2674
- * than bubble sort, etc: http://jsperf.com/javascript-sort
2675
- *
2676
- * @param hooks The custom array containing all of the appropriate hooks to perform an insert sort on.
2677
- * @private
2678
- */
2679
-
2680
-
2681
- function _hookInsertSort(hooks) {
2682
- var tmpHook, j, prevHook;
2683
-
2684
- for (var i = 1, len = hooks.length; i < len; i++) {
2685
- tmpHook = hooks[i];
2686
- j = i;
2687
-
2688
- while ((prevHook = hooks[j - 1]) && prevHook.priority > tmpHook.priority) {
2689
- hooks[j] = hooks[j - 1];
2690
- --j;
2691
- }
2692
-
2693
- hooks[j] = tmpHook;
2694
- }
2695
-
2696
- return hooks;
2697
- }
2698
- /**
2699
- * Runs the specified hook. If it is an action, the value is not modified but if it is a filter, it is.
2700
- *
2701
- * @param type 'actions' or 'filters'
2702
- * @param hook The hook ( namespace.identifier ) to be ran.
2703
- * @param args Arguments to pass to the action/filter. If it's a filter, args is actually a single parameter.
2704
- * @private
2705
- */
2706
-
2707
-
2708
- function _runHook(type, hook, args) {
2709
- var handlers = STORAGE[type][hook];
2710
-
2711
- if (!handlers) {
2712
- return type === 'filters' ? args[0] : false;
2713
- }
2714
-
2715
- var i = 0,
2716
- len = handlers.length;
2717
-
2718
- if (type === 'filters') {
2719
- for (; i < len; i++) {
2720
- args[0] = handlers[i].callback.apply(handlers[i].context, args);
2721
- }
2722
- } else {
2723
- for (; i < len; i++) {
2724
- handlers[i].callback.apply(handlers[i].context, args);
2725
- }
2726
- }
2727
-
2728
- return type === 'filters' ? args[0] : true;
2729
- } // return all of the publicly available methods
2730
-
2731
-
2732
- return MethodsAvailable;
2733
- }; // instantiate
2734
-
2735
-
2736
- acf.hooks = new EventManager();
2737
- })(window);
2738
-
2739
- (function ($, undefined) {
2740
- // Cached regex to split keys for `addEvent`.
2741
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
2742
- /**
2743
- * extend
2744
- *
2745
- * Helper function to correctly set up the prototype chain for subclasses
2746
- * Heavily inspired by backbone.js
2747
- *
2748
- * @date 14/12/17
2749
- * @since 5.6.5
2750
- *
2751
- * @param object protoProps New properties for this object.
2752
- * @return function.
2753
- */
2754
-
2755
- var extend = function (protoProps) {
2756
- // vars
2757
- var Parent = this;
2758
- var Child; // The constructor function for the new subclass is either defined by you
2759
- // (the "constructor" property in your `extend` definition), or defaulted
2760
- // by us to simply call the parent constructor.
2761
-
2762
- if (protoProps && protoProps.hasOwnProperty('constructor')) {
2763
- Child = protoProps.constructor;
2764
- } else {
2765
- Child = function () {
2766
- return Parent.apply(this, arguments);
2767
- };
2768
- } // Add static properties to the constructor function, if supplied.
2769
-
2770
-
2771
- $.extend(Child, Parent); // Set the prototype chain to inherit from `parent`, without calling
2772
- // `parent`'s constructor function and add the prototype properties.
2773
-
2774
- Child.prototype = Object.create(Parent.prototype);
2775
- $.extend(Child.prototype, protoProps);
2776
- Child.prototype.constructor = Child; // Set a convenience property in case the parent's prototype is needed later.
2777
- //Child.prototype.__parent__ = Parent.prototype;
2778
- // return
2779
-
2780
- return Child;
2781
- };
2782
- /**
2783
- * Model
2784
- *
2785
- * Base class for all inheritence
2786
- *
2787
- * @date 14/12/17
2788
- * @since 5.6.5
2789
- *
2790
- * @param object props
2791
- * @return function.
2792
- */
2793
-
2794
-
2795
- var Model = acf.Model = function () {
2796
- // generate uique client id
2797
- this.cid = acf.uniqueId('acf'); // set vars to avoid modifying prototype
2798
-
2799
- this.data = $.extend(true, {}, this.data); // pass props to setup function
2800
-
2801
- this.setup.apply(this, arguments); // store on element (allow this.setup to create this.$el)
2802
-
2803
- if (this.$el && !this.$el.data('acf')) {
2804
- this.$el.data('acf', this);
2805
- } // initialize
2806
-
2807
-
2808
- var initialize = function () {
2809
- this.initialize();
2810
- this.addEvents();
2811
- this.addActions();
2812
- this.addFilters();
2813
- }; // initialize on action
2814
-
2815
-
2816
- if (this.wait && !acf.didAction(this.wait)) {
2817
- this.addAction(this.wait, initialize); // initialize now
2818
- } else {
2819
- initialize.apply(this);
2820
- }
2821
- }; // Attach all inheritable methods to the Model prototype.
2822
-
2823
-
2824
- $.extend(Model.prototype, {
2825
- // Unique model id
2826
- id: '',
2827
- // Unique client id
2828
- cid: '',
2829
- // jQuery element
2830
- $el: null,
2831
- // Data specific to this instance
2832
- data: {},
2833
- // toggle used when changing data
2834
- busy: false,
2835
- changed: false,
2836
- // Setup events hooks
2837
- events: {},
2838
- actions: {},
2839
- filters: {},
2840
- // class used to avoid nested event triggers
2841
- eventScope: '',
2842
- // action to wait until initialize
2843
- wait: false,
2844
- // action priority default
2845
- priority: 10,
2846
-
2847
- /**
2848
- * get
2849
- *
2850
- * Gets a specific data value
2851
- *
2852
- * @date 14/12/17
2853
- * @since 5.6.5
2854
- *
2855
- * @param string name
2856
- * @return mixed
2857
- */
2858
- get: function (name) {
2859
- return this.data[name];
2860
- },
2861
-
2862
- /**
2863
- * has
2864
- *
2865
- * Returns `true` if the data exists and is not null
2866
- *
2867
- * @date 14/12/17
2868
- * @since 5.6.5
2869
- *
2870
- * @param string name
2871
- * @return boolean
2872
- */
2873
- has: function (name) {
2874
- return this.get(name) != null;
2875
- },
2876
-
2877
- /**
2878
- * set
2879
- *
2880
- * Sets a specific data value
2881
- *
2882
- * @date 14/12/17
2883
- * @since 5.6.5
2884
- *
2885
- * @param string name
2886
- * @param mixed value
2887
- * @return this
2888
- */
2889
- set: function (name, value, silent) {
2890
- // bail if unchanged
2891
- var prevValue = this.get(name);
2892
-
2893
- if (prevValue == value) {
2894
- return this;
2895
- } // set data
2896
-
2897
-
2898
- this.data[name] = value; // trigger events
2899
-
2900
- if (!silent) {
2901
- this.changed = true;
2902
- this.trigger('changed:' + name, [value, prevValue]);
2903
- this.trigger('changed', [name, value, prevValue]);
2904
- } // return
2905
-
2906
-
2907
- return this;
2908
- },
2909
-
2910
- /**
2911
- * inherit
2912
- *
2913
- * Inherits the data from a jQuery element
2914
- *
2915
- * @date 14/12/17
2916
- * @since 5.6.5
2917
- *
2918
- * @param jQuery $el
2919
- * @return this
2920
- */
2921
- inherit: function (data) {
2922
- // allow jQuery
2923
- if (data instanceof jQuery) {
2924
- data = data.data();
2925
- } // extend
2926
-
2927
-
2928
- $.extend(this.data, data); // return
2929
-
2930
- return this;
2931
- },
2932
-
2933
- /**
2934
- * prop
2935
- *
2936
- * mimics the jQuery prop function
2937
- *
2938
- * @date 4/6/18
2939
- * @since 5.6.9
2940
- *
2941
- * @param type $var Description. Default.
2942
- * @return type Description.
2943
- */
2944
- prop: function () {
2945
- return this.$el.prop.apply(this.$el, arguments);
2946
- },
2947
-
2948
- /**
2949
- * setup
2950
- *
2951
- * Run during constructor function
2952
- *
2953
- * @date 14/12/17
2954
- * @since 5.6.5
2955
- *
2956
- * @param n/a
2957
- * @return n/a
2958
- */
2959
- setup: function (props) {
2960
- $.extend(this, props);
2961
- },
2962
-
2963
- /**
2964
- * initialize
2965
- *
2966
- * Also run during constructor function
2967
- *
2968
- * @date 14/12/17
2969
- * @since 5.6.5
2970
- *
2971
- * @param n/a
2972
- * @return n/a
2973
- */
2974
- initialize: function () {},
2975
-
2976
- /**
2977
- * addElements
2978
- *
2979
- * Adds multiple jQuery elements to this object
2980
- *
2981
- * @date 9/5/18
2982
- * @since 5.6.9
2983
- *
2984
- * @param type $var Description. Default.
2985
- * @return type Description.
2986
- */
2987
- addElements: function (elements) {
2988
- elements = elements || this.elements || null;
2989
- if (!elements || !Object.keys(elements).length) return false;
2990
-
2991
- for (var i in elements) {
2992
- this.addElement(i, elements[i]);
2993
- }
2994
- },
2995
-
2996
- /**
2997
- * addElement
2998
- *
2999
- * description
3000
- *
3001
- * @date 9/5/18
3002
- * @since 5.6.9
3003
- *
3004
- * @param type $var Description. Default.
3005
- * @return type Description.
3006
- */
3007
- addElement: function (name, selector) {
3008
- this['$' + name] = this.$(selector);
3009
- },
3010
-
3011
- /**
3012
- * addEvents
3013
- *
3014
- * Adds multiple event handlers
3015
- *
3016
- * @date 14/12/17
3017
- * @since 5.6.5
3018
- *
3019
- * @param object events {event1 : callback, event2 : callback, etc }
3020
- * @return n/a
3021
- */
3022
- addEvents: function (events) {
3023
- events = events || this.events || null;
3024
- if (!events) return false;
3025
-
3026
- for (var key in events) {
3027
- var match = key.match(delegateEventSplitter);
3028
- this.on(match[1], match[2], events[key]);
3029
- }
3030
- },
3031
-
3032
- /**
3033
- * removeEvents
3034
- *
3035
- * Removes multiple event handlers
3036
- *
3037
- * @date 14/12/17
3038
- * @since 5.6.5
3039
- *
3040
- * @param object events {event1 : callback, event2 : callback, etc }
3041
- * @return n/a
3042
- */
3043
- removeEvents: function (events) {
3044
- events = events || this.events || null;
3045
- if (!events) return false;
3046
-
3047
- for (var key in events) {
3048
- var match = key.match(delegateEventSplitter);
3049
- this.off(match[1], match[2], events[key]);
3050
- }
3051
- },
3052
-
3053
- /**
3054
- * getEventTarget
3055
- *
3056
- * Returns a jQUery element to tigger an event on
3057
- *
3058
- * @date 5/6/18
3059
- * @since 5.6.9
3060
- *
3061
- * @param jQuery $el The default jQuery element. Optional.
3062
- * @param string event The event name. Optional.
3063
- * @return jQuery
3064
- */
3065
- getEventTarget: function ($el, event) {
3066
- return $el || this.$el || $(document);
3067
- },
3068
-
3069
- /**
3070
- * validateEvent
3071
- *
3072
- * Returns true if the event target's closest $el is the same as this.$el
3073
- * Requires both this.el and this.$el to be defined
3074
- *
3075
- * @date 5/6/18
3076
- * @since 5.6.9
3077
- *
3078
- * @param type $var Description. Default.
3079
- * @return type Description.
3080
- */
3081
- validateEvent: function (e) {
3082
- if (this.eventScope) {
3083
- return $(e.target).closest(this.eventScope).is(this.$el);
3084
- } else {
3085
- return true;
3086
- }
3087
- },
3088
-
3089
- /**
3090
- * proxyEvent
3091
- *
3092
- * Returns a new event callback function scoped to this model
3093
- *
3094
- * @date 29/3/18
3095
- * @since 5.6.9
3096
- *
3097
- * @param function callback
3098
- * @return function
3099
- */
3100
- proxyEvent: function (callback) {
3101
- return this.proxy(function (e) {
3102
- // validate
3103
- if (!this.validateEvent(e)) {
3104
- return;
3105
- } // construct args
3106
-
3107
-
3108
- var args = acf.arrayArgs(arguments);
3109
- var extraArgs = args.slice(1);
3110
- var eventArgs = [e, $(e.currentTarget)].concat(extraArgs); // callback
3111
-
3112
- callback.apply(this, eventArgs);
3113
- });
3114
- },
3115
-
3116
- /**
3117
- * on
3118
- *
3119
- * Adds an event handler similar to jQuery
3120
- * Uses the instance 'cid' to namespace event
3121
- *
3122
- * @date 14/12/17
3123
- * @since 5.6.5
3124
- *
3125
- * @param string name
3126
- * @param string callback
3127
- * @return n/a
3128
- */
3129
- on: function (a1, a2, a3, a4) {
3130
- // vars
3131
- var $el, event, selector, callback, args; // find args
3132
-
3133
- if (a1 instanceof jQuery) {
3134
- // 1. args( $el, event, selector, callback )
3135
- if (a4) {
3136
- $el = a1;
3137
- event = a2;
3138
- selector = a3;
3139
- callback = a4; // 2. args( $el, event, callback )
3140
- } else {
3141
- $el = a1;
3142
- event = a2;
3143
- callback = a3;
3144
- }
3145
- } else {
3146
- // 3. args( event, selector, callback )
3147
- if (a3) {
3148
- event = a1;
3149
- selector = a2;
3150
- callback = a3; // 4. args( event, callback )
3151
- } else {
3152
- event = a1;
3153
- callback = a2;
3154
- }
3155
- } // element
3156
-
3157
-
3158
- $el = this.getEventTarget($el); // modify callback
3159
-
3160
- if (typeof callback === 'string') {
3161
- callback = this.proxyEvent(this[callback]);
3162
- } // modify event
3163
-
3164
-
3165
- event = event + '.' + this.cid; // args
3166
-
3167
- if (selector) {
3168
- args = [event, selector, callback];
3169
- } else {
3170
- args = [event, callback];
3171
- } // on()
3172
-
3173
-
3174
- $el.on.apply($el, args);
3175
- },
3176
-
3177
- /**
3178
- * off
3179
- *
3180
- * Removes an event handler similar to jQuery
3181
- *
3182
- * @date 14/12/17
3183
- * @since 5.6.5
3184
- *
3185
- * @param string name
3186
- * @param string callback
3187
- * @return n/a
3188
- */
3189
- off: function (a1, a2, a3) {
3190
- // vars
3191
- var $el, event, selector, args; // find args
3192
-
3193
- if (a1 instanceof jQuery) {
3194
- // 1. args( $el, event, selector )
3195
- if (a3) {
3196
- $el = a1;
3197
- event = a2;
3198
- selector = a3; // 2. args( $el, event )
3199
- } else {
3200
- $el = a1;
3201
- event = a2;
3202
- }
3203
- } else {
3204
- // 3. args( event, selector )
3205
- if (a2) {
3206
- event = a1;
3207
- selector = a2; // 4. args( event )
3208
- } else {
3209
- event = a1;
3210
- }
3211
- } // element
3212
-
3213
-
3214
- $el = this.getEventTarget($el); // modify event
3215
-
3216
- event = event + '.' + this.cid; // args
3217
-
3218
- if (selector) {
3219
- args = [event, selector];
3220
- } else {
3221
- args = [event];
3222
- } // off()
3223
-
3224
-
3225
- $el.off.apply($el, args);
3226
- },
3227
-
3228
- /**
3229
- * trigger
3230
- *
3231
- * Triggers an event similar to jQuery
3232
- *
3233
- * @date 14/12/17
3234
- * @since 5.6.5
3235
- *
3236
- * @param string name
3237
- * @param string callback
3238
- * @return n/a
3239
- */
3240
- trigger: function (name, args, bubbles) {
3241
- var $el = this.getEventTarget();
3242
-
3243
- if (bubbles) {
3244
- $el.trigger.apply($el, arguments);
3245
- } else {
3246
- $el.triggerHandler.apply($el, arguments);
3247
- }
3248
-
3249
- return this;
3250
- },
3251
-
3252
- /**
3253
- * addActions
3254
- *
3255
- * Adds multiple action handlers
3256
- *
3257
- * @date 14/12/17
3258
- * @since 5.6.5
3259
- *
3260
- * @param object actions {action1 : callback, action2 : callback, etc }
3261
- * @return n/a
3262
- */
3263
- addActions: function (actions) {
3264
- actions = actions || this.actions || null;
3265
- if (!actions) return false;
3266
-
3267
- for (var i in actions) {
3268
- this.addAction(i, actions[i]);
3269
- }
3270
- },
3271
-
3272
- /**
3273
- * removeActions
3274
- *
3275
- * Removes multiple action handlers
3276
- *
3277
- * @date 14/12/17
3278
- * @since 5.6.5
3279
- *
3280
- * @param object actions {action1 : callback, action2 : callback, etc }
3281
- * @return n/a
3282
- */
3283
- removeActions: function (actions) {
3284
- actions = actions || this.actions || null;
3285
- if (!actions) return false;
3286
-
3287
- for (var i in actions) {
3288
- this.removeAction(i, actions[i]);
3289
- }
3290
- },
3291
-
3292
- /**
3293
- * addAction
3294
- *
3295
- * Adds an action using the wp.hooks library
3296
- *
3297
- * @date 14/12/17
3298
- * @since 5.6.5
3299
- *
3300
- * @param string name
3301
- * @param string callback
3302
- * @return n/a
3303
- */
3304
- addAction: function (name, callback, priority) {
3305
- //console.log('addAction', name, priority);
3306
- // defaults
3307
- priority = priority || this.priority; // modify callback
3308
-
3309
- if (typeof callback === 'string') {
3310
- callback = this[callback];
3311
- } // add
3312
-
3313
-
3314
- acf.addAction(name, callback, priority, this);
3315
- },
3316
-
3317
- /**
3318
- * removeAction
3319
- *
3320
- * Remove an action using the wp.hooks library
3321
- *
3322
- * @date 14/12/17
3323
- * @since 5.6.5
3324
- *
3325
- * @param string name
3326
- * @param string callback
3327
- * @return n/a
3328
- */
3329
- removeAction: function (name, callback) {
3330
- acf.removeAction(name, this[callback]);
3331
- },
3332
-
3333
- /**
3334
- * addFilters
3335
- *
3336
- * Adds multiple filter handlers
3337
- *
3338
- * @date 14/12/17
3339
- * @since 5.6.5
3340
- *
3341
- * @param object filters {filter1 : callback, filter2 : callback, etc }
3342
- * @return n/a
3343
- */
3344
- addFilters: function (filters) {
3345
- filters = filters || this.filters || null;
3346
- if (!filters) return false;
3347
-
3348
- for (var i in filters) {
3349
- this.addFilter(i, filters[i]);
3350
- }
3351
- },
3352
-
3353
- /**
3354
- * addFilter
3355
- *
3356
- * Adds a filter using the wp.hooks library
3357
- *
3358
- * @date 14/12/17
3359
- * @since 5.6.5
3360
- *
3361
- * @param string name
3362
- * @param string callback
3363
- * @return n/a
3364
- */
3365
- addFilter: function (name, callback, priority) {
3366
- // defaults
3367
- priority = priority || this.priority; // modify callback
3368
-
3369
- if (typeof callback === 'string') {
3370
- callback = this[callback];
3371
- } // add
3372
-
3373
-
3374
- acf.addFilter(name, callback, priority, this);
3375
- },
3376
-
3377
- /**
3378
- * removeFilters
3379
- *
3380
- * Removes multiple filter handlers
3381
- *
3382
- * @date 14/12/17
3383
- * @since 5.6.5
3384
- *
3385
- * @param object filters {filter1 : callback, filter2 : callback, etc }
3386
- * @return n/a
3387
- */
3388
- removeFilters: function (filters) {
3389
- filters = filters || this.filters || null;
3390
- if (!filters) return false;
3391
-
3392
- for (var i in filters) {
3393
- this.removeFilter(i, filters[i]);
3394
- }
3395
- },
3396
-
3397
- /**
3398
- * removeFilter
3399
- *
3400
- * Remove a filter using the wp.hooks library
3401
- *
3402
- * @date 14/12/17
3403
- * @since 5.6.5
3404
- *
3405
- * @param string name
3406
- * @param string callback
3407
- * @return n/a
3408
- */
3409
- removeFilter: function (name, callback) {
3410
- acf.removeFilter(name, this[callback]);
3411
- },
3412
-
3413
- /**
3414
- * $
3415
- *
3416
- * description
3417
- *
3418
- * @date 16/12/17
3419
- * @since 5.6.5
3420
- *
3421
- * @param type $var Description. Default.
3422
- * @return type Description.
3423
- */
3424
- $: function (selector) {
3425
- return this.$el.find(selector);
3426
- },
3427
-
3428
- /**
3429
- * remove
3430
- *
3431
- * Removes the element and listenters
3432
- *
3433
- * @date 19/12/17
3434
- * @since 5.6.5
3435
- *
3436
- * @param type $var Description. Default.
3437
- * @return type Description.
3438
- */
3439
- remove: function () {
3440
- this.removeEvents();
3441
- this.removeActions();
3442
- this.removeFilters();
3443
- this.$el.remove();
3444
- },
3445
-
3446
- /**
3447
- * setTimeout
3448
- *
3449
- * description
3450
- *
3451
- * @date 16/1/18
3452
- * @since 5.6.5
3453
- *
3454
- * @param type $var Description. Default.
3455
- * @return type Description.
3456
- */
3457
- setTimeout: function (callback, milliseconds) {
3458
- return setTimeout(this.proxy(callback), milliseconds);
3459
- },
3460
-
3461
- /**
3462
- * time
3463
- *
3464
- * used for debugging
3465
- *
3466
- * @date 7/3/18
3467
- * @since 5.6.9
3468
- *
3469
- * @param type $var Description. Default.
3470
- * @return type Description.
3471
- */
3472
- time: function () {
3473
- console.time(this.id || this.cid);
3474
- },
3475
-
3476
- /**
3477
- * timeEnd
3478
- *
3479
- * used for debugging
3480
- *
3481
- * @date 7/3/18
3482
- * @since 5.6.9
3483
- *
3484
- * @param type $var Description. Default.
3485
- * @return type Description.
3486
- */
3487
- timeEnd: function () {
3488
- console.timeEnd(this.id || this.cid);
3489
- },
3490
-
3491
- /**
3492
- * show
3493
- *
3494
- * description
3495
- *
3496
- * @date 15/3/18
3497
- * @since 5.6.9
3498
- *
3499
- * @param type $var Description. Default.
3500
- * @return type Description.
3501
- */
3502
- show: function () {
3503
- acf.show(this.$el);
3504
- },
3505
-
3506
- /**
3507
- * hide
3508
- *
3509
- * description
3510
- *
3511
- * @date 15/3/18
3512
- * @since 5.6.9
3513
- *
3514
- * @param type $var Description. Default.
3515
- * @return type Description.
3516
- */
3517
- hide: function () {
3518
- acf.hide(this.$el);
3519
- },
3520
-
3521
- /**
3522
- * proxy
3523
- *
3524
- * Returns a new function scoped to this model
3525
- *
3526
- * @date 29/3/18
3527
- * @since 5.6.9
3528
- *
3529
- * @param function callback
3530
- * @return function
3531
- */
3532
- proxy: function (callback) {
3533
- return $.proxy(callback, this);
3534
- }
3535
- }); // Set up inheritance for the model
3536
-
3537
- Model.extend = extend; // Global model storage
3538
-
3539
- acf.models = {};
3540
- /**
3541
- * acf.getInstance
3542
- *
3543
- * This function will get an instance from an element
3544
- *
3545
- * @date 5/3/18
3546
- * @since 5.6.9
3547
- *
3548
- * @param type $var Description. Default.
3549
- * @return type Description.
3550
- */
3551
-
3552
- acf.getInstance = function ($el) {
3553
- return $el.data('acf');
3554
- };
3555
- /**
3556
- * acf.getInstances
3557
- *
3558
- * This function will get an array of instances from multiple elements
3559
- *
3560
- * @date 5/3/18
3561
- * @since 5.6.9
3562
- *
3563
- * @param type $var Description. Default.
3564
- * @return type Description.
3565
- */
3566
-
3567
-
3568
- acf.getInstances = function ($el) {
3569
- var instances = [];
3570
- $el.each(function () {
3571
- instances.push(acf.getInstance($(this)));
3572
- });
3573
- return instances;
3574
- };
3575
  })(jQuery);
3576
-
3577
- (function ($, undefined) {
3578
- acf.models.Popup = acf.Model.extend({
3579
- data: {
3580
- title: '',
3581
- content: '',
3582
- width: 0,
3583
- height: 0,
3584
- loading: false
3585
- },
3586
- events: {
3587
- 'click [data-event="close"]': 'onClickClose',
3588
- 'click .acf-close-popup': 'onClickClose'
3589
- },
3590
- setup: function (props) {
3591
- $.extend(this.data, props);
3592
- this.$el = $(this.tmpl());
3593
- },
3594
- initialize: function () {
3595
- this.render();
3596
- this.open();
3597
- },
3598
- tmpl: function () {
3599
- return ['<div id="acf-popup">', '<div class="acf-popup-box acf-box">', '<div class="title"><h3></h3><a href="#" class="acf-icon -cancel grey" data-event="close"></a></div>', '<div class="inner"></div>', '<div class="loading"><i class="acf-loading"></i></div>', '</div>', '<div class="bg" data-event="close"></div>', '</div>'].join('');
3600
- },
3601
- render: function () {
3602
- // Extract Vars.
3603
- var title = this.get('title');
3604
- var content = this.get('content');
3605
- var loading = this.get('loading');
3606
- var width = this.get('width');
3607
- var height = this.get('height'); // Update.
3608
-
3609
- this.title(title);
3610
- this.content(content);
3611
-
3612
- if (width) {
3613
- this.$('.acf-popup-box').css('width', width);
3614
- }
3615
-
3616
- if (height) {
3617
- this.$('.acf-popup-box').css('min-height', height);
3618
- }
3619
-
3620
- this.loading(loading); // Trigger action.
3621
-
3622
- acf.doAction('append', this.$el);
3623
- },
3624
- update: function (props) {
3625
- this.data = acf.parseArgs(props, this.data);
3626
- this.render();
3627
- },
3628
- title: function (title) {
3629
- this.$('.title:first h3').html(title);
3630
- },
3631
- content: function (content) {
3632
- this.$('.inner:first').html(content);
3633
- },
3634
- loading: function (show) {
3635
- var $loading = this.$('.loading:first');
3636
- show ? $loading.show() : $loading.hide();
3637
- },
3638
- open: function () {
3639
- $('body').append(this.$el);
3640
- },
3641
- close: function () {
3642
- this.remove();
3643
- },
3644
- onClickClose: function (e, $el) {
3645
- e.preventDefault();
3646
- this.close();
3647
- }
3648
- });
3649
- /**
3650
- * newPopup
3651
- *
3652
- * Creates a new Popup with the supplied props
3653
- *
3654
- * @date 17/12/17
3655
- * @since 5.6.5
3656
- *
3657
- * @param object props
3658
- * @return object
3659
- */
3660
-
3661
- acf.newPopup = function (props) {
3662
- return new acf.models.Popup(props);
3663
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3664
  })(jQuery);
3665
-
3666
- (function ($, undefined) {
3667
- acf.models.Modal = acf.Model.extend({
3668
- data: {
3669
- title: '',
3670
- content: '',
3671
- toolbar: ''
3672
- },
3673
- events: {
3674
- 'click .acf-modal-close': 'onClickClose'
3675
- },
3676
- setup: function (props) {
3677
- $.extend(this.data, props);
3678
- this.$el = $();
3679
- this.render();
3680
- },
3681
- initialize: function () {
3682
- this.open();
3683
- },
3684
- render: function () {
3685
- // Extract vars.
3686
- var title = this.get('title');
3687
- var content = this.get('content');
3688
- var toolbar = this.get('toolbar'); // Create element.
3689
-
3690
- var $el = $(['<div>', '<div class="acf-modal">', '<div class="acf-modal-title">', '<h2>' + title + '</h2>', '<button class="acf-modal-close" type="button"><span class="dashicons dashicons-no"></span></button>', '</div>', '<div class="acf-modal-content">' + content + '</div>', '<div class="acf-modal-toolbar">' + toolbar + '</div>', '</div>', '<div class="acf-modal-backdrop acf-modal-close"></div>', '</div>'].join('')); // Update DOM.
3691
-
3692
- if (this.$el) {
3693
- this.$el.replaceWith($el);
3694
- }
3695
-
3696
- this.$el = $el; // Trigger action.
3697
-
3698
- acf.doAction('append', $el);
3699
- },
3700
- update: function (props) {
3701
- this.data = acf.parseArgs(props, this.data);
3702
- this.render();
3703
- },
3704
- title: function (title) {
3705
- this.$('.acf-modal-title h2').html(title);
3706
- },
3707
- content: function (content) {
3708
- this.$('.acf-modal-content').html(content);
3709
- },
3710
- toolbar: function (toolbar) {
3711
- this.$('.acf-modal-toolbar').html(toolbar);
3712
- },
3713
- open: function () {
3714
- $('body').append(this.$el);
3715
- },
3716
- close: function () {
3717
- this.remove();
3718
- },
3719
- onClickClose: function (e, $el) {
3720
- e.preventDefault();
3721
- this.close();
3722
- }
3723
- });
3724
- /**
3725
- * Returns a new modal.
3726
- *
3727
- * @date 21/4/20
3728
- * @since 5.9.0
3729
- *
3730
- * @param object props The modal props.
3731
- * @return object
3732
- */
3733
-
3734
- acf.newModal = function (props) {
3735
- return new acf.models.Modal(props);
3736
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3737
  })(jQuery);
3738
-
3739
- (function ($, undefined) {
3740
- var panel = new acf.Model({
3741
- events: {
3742
- 'click .acf-panel-title': 'onClick'
3743
- },
3744
- onClick: function (e, $el) {
3745
- e.preventDefault();
3746
- this.toggle($el.parent());
3747
- },
3748
- isOpen: function ($el) {
3749
- return $el.hasClass('-open');
3750
- },
3751
- toggle: function ($el) {
3752
- this.isOpen($el) ? this.close($el) : this.open($el);
3753
- },
3754
- open: function ($el) {
3755
- $el.addClass('-open');
3756
- $el.find('.acf-panel-title i').attr('class', 'dashicons dashicons-arrow-down');
3757
- },
3758
- close: function ($el) {
3759
- $el.removeClass('-open');
3760
- $el.find('.acf-panel-title i').attr('class', 'dashicons dashicons-arrow-right');
3761
- }
3762
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3763
  })(jQuery);
3764
-
3765
- (function ($, undefined) {
3766
- var Notice = acf.Model.extend({
3767
- data: {
3768
- text: '',
3769
- type: '',
3770
- timeout: 0,
3771
- dismiss: true,
3772
- target: false,
3773
- close: function () {}
3774
- },
3775
- events: {
3776
- 'click .acf-notice-dismiss': 'onClickClose'
3777
- },
3778
- tmpl: function () {
3779
- return '<div class="acf-notice"></div>';
3780
- },
3781
- setup: function (props) {
3782
- $.extend(this.data, props);
3783
- this.$el = $(this.tmpl());
3784
- },
3785
- initialize: function () {
3786
- // render
3787
- this.render(); // show
3788
-
3789
- this.show();
3790
- },
3791
- render: function () {
3792
- // class
3793
- this.type(this.get('type')); // text
3794
-
3795
- this.html('<p>' + this.get('text') + '</p>'); // close
3796
-
3797
- if (this.get('dismiss')) {
3798
- this.$el.append('<a href="#" class="acf-notice-dismiss acf-icon -cancel small"></a>');
3799
- this.$el.addClass('-dismiss');
3800
- } // timeout
3801
-
3802
-
3803
- var timeout = this.get('timeout');
3804
-
3805
- if (timeout) {
3806
- this.away(timeout);
3807
- }
3808
- },
3809
- update: function (props) {
3810
- // update
3811
- $.extend(this.data, props); // re-initialize
3812
-
3813
- this.initialize(); // refresh events
3814
-
3815
- this.removeEvents();
3816
- this.addEvents();
3817
- },
3818
- show: function () {
3819
- var $target = this.get('target');
3820
-
3821
- if ($target) {
3822
- $target.prepend(this.$el);
3823
- }
3824
- },
3825
- hide: function () {
3826
- this.$el.remove();
3827
- },
3828
- away: function (timeout) {
3829
- this.setTimeout(function () {
3830
- acf.remove(this.$el);
3831
- }, timeout);
3832
- },
3833
- type: function (type) {
3834
- // remove prev type
3835
- var prevType = this.get('type');
3836
-
3837
- if (prevType) {
3838
- this.$el.removeClass('-' + prevType);
3839
- } // add new type
3840
-
3841
-
3842
- this.$el.addClass('-' + type); // backwards compatibility
3843
-
3844
- if (type == 'error') {
3845
- this.$el.addClass('acf-error-message');
3846
- }
3847
- },
3848
- html: function (html) {
3849
- this.$el.html(acf.escHtml(html));
3850
- },
3851
- text: function (text) {
3852
- this.$('p').html(acf.escHtml(text));
3853
- },
3854
- onClickClose: function (e, $el) {
3855
- e.preventDefault();
3856
- this.get('close').apply(this, arguments);
3857
- this.remove();
3858
- }
3859
- });
3860
-
3861
- acf.newNotice = function (props) {
3862
- // ensure object
3863
- if (typeof props !== 'object') {
3864
- props = {
3865
- text: props
3866
- };
3867
- } // instantiate
3868
-
3869
-
3870
- return new Notice(props);
3871
- };
3872
-
3873
- var noticeManager = new acf.Model({
3874
- wait: 'prepare',
3875
- priority: 1,
3876
- initialize: function () {
3877
- // vars
3878
- var $notice = $('.acf-admin-notice'); // move to avoid WP flicker
3879
-
3880
- if ($notice.length) {
3881
- $('h1:first').after($notice);
3882
- }
3883
- }
3884
- });
3885
  })(jQuery);
3886
-
3887
- (function ($, undefined) {
3888
- acf.newTooltip = function (props) {
3889
- // ensure object
3890
- if (typeof props !== 'object') {
3891
- props = {
3892
- text: props
3893
- };
3894
- } // confirmRemove
3895
-
3896
-
3897
- if (props.confirmRemove !== undefined) {
3898
- props.textConfirm = acf.__('Remove');
3899
- props.textCancel = acf.__('Cancel');
3900
- return new TooltipConfirm(props); // confirm
3901
- } else if (props.confirm !== undefined) {
3902
- return new TooltipConfirm(props); // default
3903
- } else {
3904
- return new Tooltip(props);
3905
- }
3906
- };
3907
-
3908
- var Tooltip = acf.Model.extend({
3909
- data: {
3910
- text: '',
3911
- timeout: 0,
3912
- target: null
3913
- },
3914
- tmpl: function () {
3915
- return '<div class="acf-tooltip"></div>';
3916
- },
3917
- setup: function (props) {
3918
- $.extend(this.data, props);
3919
- this.$el = $(this.tmpl());
3920
- },
3921
- initialize: function () {
3922
- // render
3923
- this.render(); // append
3924
-
3925
- this.show(); // position
3926
-
3927
- this.position(); // timeout
3928
-
3929
- var timeout = this.get('timeout');
3930
-
3931
- if (timeout) {
3932
- setTimeout($.proxy(this.fade, this), timeout);
3933
- }
3934
- },
3935
- update: function (props) {
3936
- $.extend(this.data, props);
3937
- this.initialize();
3938
- },
3939
- render: function () {
3940
- this.html(this.get('text'));
3941
- },
3942
- show: function () {
3943
- $('body').append(this.$el);
3944
- },
3945
- hide: function () {
3946
- this.$el.remove();
3947
- },
3948
- fade: function () {
3949
- // add class
3950
- this.$el.addClass('acf-fade-up'); // remove
3951
-
3952
- this.setTimeout(function () {
3953
- this.remove();
3954
- }, 250);
3955
- },
3956
- html: function (html) {
3957
- this.$el.html(html);
3958
- },
3959
- position: function () {
3960
- // vars
3961
- var $tooltip = this.$el;
3962
- var $target = this.get('target');
3963
- if (!$target) return; // Reset position.
3964
-
3965
- $tooltip.removeClass('right left bottom top').css({
3966
- top: 0,
3967
- left: 0
3968
- }); // Declare tollerance to edge of screen.
3969
-
3970
- var tolerance = 10; // Find target position.
3971
-
3972
- var targetWidth = $target.outerWidth();
3973
- var targetHeight = $target.outerHeight();
3974
- var targetTop = $target.offset().top;
3975
- var targetLeft = $target.offset().left; // Find tooltip position.
3976
-
3977
- var tooltipWidth = $tooltip.outerWidth();
3978
- var tooltipHeight = $tooltip.outerHeight();
3979
- var tooltipTop = $tooltip.offset().top; // Should be 0, but WP media grid causes this to be 32 (toolbar padding).
3980
- // Assume default top alignment.
3981
-
3982
- var top = targetTop - tooltipHeight - tooltipTop;
3983
- var left = targetLeft + targetWidth / 2 - tooltipWidth / 2; // Check if too far left.
3984
-
3985
- if (left < tolerance) {
3986
- $tooltip.addClass('right');
3987
- left = targetLeft + targetWidth;
3988
- top = targetTop + targetHeight / 2 - tooltipHeight / 2 - tooltipTop; // Check if too far right.
3989
- } else if (left + tooltipWidth + tolerance > $(window).width()) {
3990
- $tooltip.addClass('left');
3991
- left = targetLeft - tooltipWidth;
3992
- top = targetTop + targetHeight / 2 - tooltipHeight / 2 - tooltipTop; // Check if too far up.
3993
- } else if (top - $(window).scrollTop() < tolerance) {
3994
- $tooltip.addClass('bottom');
3995
- top = targetTop + targetHeight - tooltipTop; // No colision with edges.
3996
- } else {
3997
- $tooltip.addClass('top');
3998
- } // update css
3999
-
4000
-
4001
- $tooltip.css({
4002
- 'top': top,
4003
- 'left': left
4004
- });
4005
- }
4006
- });
4007
- var TooltipConfirm = Tooltip.extend({
4008
- data: {
4009
- text: '',
4010
- textConfirm: '',
4011
- textCancel: '',
4012
- target: null,
4013
- targetConfirm: true,
4014
- confirm: function () {},
4015
- cancel: function () {},
4016
- context: false
4017
- },
4018
- events: {
4019
- 'click [data-event="cancel"]': 'onCancel',
4020
- 'click [data-event="confirm"]': 'onConfirm'
4021
- },
4022
- addEvents: function () {
4023
- // add events
4024
- acf.Model.prototype.addEvents.apply(this); // vars
4025
-
4026
- var $document = $(document);
4027
- var $target = this.get('target'); // add global 'cancel' click event
4028
- // - use timeout to avoid the current 'click' event triggering the onCancel function
4029
-
4030
- this.setTimeout(function () {
4031
- this.on($document, 'click', 'onCancel');
4032
- }); // add target 'confirm' click event
4033
- // - allow setting to control this feature
4034
-
4035
- if (this.get('targetConfirm')) {
4036
- this.on($target, 'click', 'onConfirm');
4037
- }
4038
- },
4039
- removeEvents: function () {
4040
- // remove events
4041
- acf.Model.prototype.removeEvents.apply(this); // vars
4042
-
4043
- var $document = $(document);
4044
- var $target = this.get('target'); // remove custom events
4045
-
4046
- this.off($document, 'click');
4047
- this.off($target, 'click');
4048
- },
4049
- render: function () {
4050
- // defaults
4051
- var text = this.get('text') || acf.__('Are you sure?');
4052
-
4053
- var textConfirm = this.get('textConfirm') || acf.__('Yes');
4054
-
4055
- var textCancel = this.get('textCancel') || acf.__('No'); // html
4056
-
4057
-
4058
- var html = [text, '<a href="#" data-event="confirm">' + textConfirm + '</a>', '<a href="#" data-event="cancel">' + textCancel + '</a>'].join(' '); // html
4059
-
4060
- this.html(html); // class
4061
-
4062
- this.$el.addClass('-confirm');
4063
- },
4064
- onCancel: function (e, $el) {
4065
- // prevent default
4066
- e.preventDefault();
4067
- e.stopImmediatePropagation(); // callback
4068
-
4069
- var callback = this.get('cancel');
4070
- var context = this.get('context') || this;
4071
- callback.apply(context, arguments); //remove
4072
-
4073
- this.remove();
4074
- },
4075
- onConfirm: function (e, $el) {
4076
- // Prevent event from propagating completely to allow "targetConfirm" to be clicked.
4077
- e.preventDefault();
4078
- e.stopImmediatePropagation(); // callback
4079
-
4080
- var callback = this.get('confirm');
4081
- var context = this.get('context') || this;
4082
- callback.apply(context, arguments); //remove
4083
-
4084
- this.remove();
4085
- }
4086
- }); // storage
4087
-
4088
- acf.models.Tooltip = Tooltip;
4089
- acf.models.TooltipConfirm = TooltipConfirm;
4090
- /**
4091
- * tooltipManager
4092
- *
4093
- * description
4094
- *
4095
- * @date 17/4/18
4096
- * @since 5.6.9
4097
- *
4098
- * @param type $var Description. Default.
4099
- * @return type Description.
4100
- */
4101
-
4102
- var tooltipHoverHelper = new acf.Model({
4103
- tooltip: false,
4104
- events: {
4105
- 'mouseenter .acf-js-tooltip': 'showTitle',
4106
- 'mouseup .acf-js-tooltip': 'hideTitle',
4107
- 'mouseleave .acf-js-tooltip': 'hideTitle'
4108
- },
4109
- showTitle: function (e, $el) {
4110
- // vars
4111
- var title = $el.attr('title'); // bail ealry if no title
4112
-
4113
- if (!title) {
4114
- return;
4115
- } // clear title to avoid default browser tooltip
4116
-
4117
-
4118
- $el.attr('title', ''); // create
4119
-
4120
- if (!this.tooltip) {
4121
- this.tooltip = acf.newTooltip({
4122
- text: title,
4123
- target: $el
4124
- }); // update
4125
- } else {
4126
- this.tooltip.update({
4127
- text: title,
4128
- target: $el
4129
- });
4130
- }
4131
- },
4132
- hideTitle: function (e, $el) {
4133
- // hide tooltip
4134
- this.tooltip.hide(); // restore title
4135
-
4136
- $el.attr('title', this.tooltip.get('text'));
4137
- }
4138
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4139
  })(jQuery);
1
+ (function($, undefined){
2
+
3
+ /**
4
+ * acf
5
+ *
6
+ * description
7
+ *
8
+ * @date 14/12/17
9
+ * @since 5.6.5
10
+ *
11
+ * @param type $var Description. Default.
12
+ * @return type Description.
13
+ */
14
+
15
+ // The global acf object
16
+ var acf = {};
17
+
18
+ // Set as a browser global
19
+ window.acf = acf;
20
+
21
+ /** @var object Data sent from PHP */
22
+ acf.data = {};
23
+
24
+
25
+ /**
26
+ * get
27
+ *
28
+ * Gets a specific data value
29
+ *
30
+ * @date 14/12/17
31
+ * @since 5.6.5
32
+ *
33
+ * @param string name
34
+ * @return mixed
35
+ */
36
+
37
+ acf.get = function( name ){
38
+ return this.data[name] || null;
39
+ };
40
+
41
+
42
+ /**
43
+ * has
44
+ *
45
+ * Returns `true` if the data exists and is not null
46
+ *
47
+ * @date 14/12/17
48
+ * @since 5.6.5
49
+ *
50
+ * @param string name
51
+ * @return boolean
52
+ */
53
+
54
+ acf.has = function( name ){
55
+ return this.get(name) !== null;
56
+ };
57
+
58
+
59
+ /**
60
+ * set
61
+ *
62
+ * Sets a specific data value
63
+ *
64
+ * @date 14/12/17
65
+ * @since 5.6.5
66
+ *
67
+ * @param string name
68
+ * @param mixed value
69
+ * @return this
70
+ */
71
+
72
+ acf.set = function( name, value ){
73
+ this.data[ name ] = value;
74
+ return this;
75
+ };
76
+
77
+
78
+ /**
79
+ * uniqueId
80
+ *
81
+ * Returns a unique ID
82
+ *
83
+ * @date 9/11/17
84
+ * @since 5.6.3
85
+ *
86
+ * @param string prefix Optional prefix.
87
+ * @return string
88
+ */
89
+
90
+ var idCounter = 0;
91
+ acf.uniqueId = function(prefix){
92
+ var id = ++idCounter + '';
93
+ return prefix ? prefix + id : id;
94
+ };
95
+
96
+ /**
97
+ * acf.uniqueArray
98
+ *
99
+ * Returns a new array with only unique values
100
+ * Credit: https://stackoverflow.com/questions/1960473/get-all-unique-values-in-an-array-remove-duplicates
101
+ *
102
+ * @date 23/3/18
103
+ * @since 5.6.9
104
+ *
105
+ * @param type $var Description. Default.
106
+ * @return type Description.
107
+ */
108
+
109
+ acf.uniqueArray = function( array ){
110
+ function onlyUnique(value, index, self) {
111
+ return self.indexOf(value) === index;
112
+ }
113
+ return array.filter( onlyUnique );
114
+ };
115
+
116
+ /**
117
+ * uniqid
118
+ *
119
+ * Returns a unique ID (PHP version)
120
+ *
121
+ * @date 9/11/17
122
+ * @since 5.6.3
123
+ * @source http://locutus.io/php/misc/uniqid/
124
+ *
125
+ * @param string prefix Optional prefix.
126
+ * @return string
127
+ */
128
+
129
+ var uniqidSeed = '';
130
+ acf.uniqid = function(prefix, moreEntropy){
131
+ // discuss at: http://locutus.io/php/uniqid/
132
+ // original by: Kevin van Zonneveld (http://kvz.io)
133
+ // revised by: Kankrelune (http://www.webfaktory.info/)
134
+ // note 1: Uses an internal counter (in locutus global) to avoid collision
135
+ // example 1: var $id = uniqid()
136
+ // example 1: var $result = $id.length === 13
137
+ // returns 1: true
138
+ // example 2: var $id = uniqid('foo')
139
+ // example 2: var $result = $id.length === (13 + 'foo'.length)
140
+ // returns 2: true
141
+ // example 3: var $id = uniqid('bar', true)
142
+ // example 3: var $result = $id.length === (23 + 'bar'.length)
143
+ // returns 3: true
144
+ if (typeof prefix === 'undefined') {
145
+ prefix = '';
146
+ }
147
+
148
+ var retId;
149
+ var formatSeed = function(seed, reqWidth) {
150
+ seed = parseInt(seed, 10).toString(16); // to hex str
151
+ if (reqWidth < seed.length) { // so long we split
152
+ return seed.slice(seed.length - reqWidth);
153
+ }
154
+ if (reqWidth > seed.length) { // so short we pad
155
+ return Array(1 + (reqWidth - seed.length)).join('0') + seed;
156
+ }
157
+ return seed;
158
+ };
159
+
160
+ if (!uniqidSeed) { // init seed with big random int
161
+ uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
162
+ }
163
+ uniqidSeed++;
164
+
165
+ retId = prefix; // start with prefix, add current milliseconds hex string
166
+ retId += formatSeed(parseInt(new Date().getTime() / 1000, 10), 8);
167
+ retId += formatSeed(uniqidSeed, 5); // add seed hex string
168
+ if (moreEntropy) {
169
+ // for more entropy we add a float lower to 10
170
+ retId += (Math.random() * 10).toFixed(8).toString();
171
+ }
172
+
173
+ return retId;
174
+ };
175
+
176
+
177
+ /**
178
+ * strReplace
179
+ *
180
+ * Performs a string replace
181
+ *
182
+ * @date 14/12/17
183
+ * @since 5.6.5
184
+ *
185
+ * @param string search
186
+ * @param string replace
187
+ * @param string subject
188
+ * @return string
189
+ */
190
+
191
+ acf.strReplace = function( search, replace, subject ){
192
+ return subject.split(search).join(replace);
193
+ };
194
+
195
+
196
+ /**
197
+ * strCamelCase
198
+ *
199
+ * Converts a string into camelCase
200
+ * Thanks to https://stackoverflow.com/questions/2970525/converting-any-string-into-camel-case
201
+ *
202
+ * @date 14/12/17
203
+ * @since 5.6.5
204
+ *
205
+ * @param string str
206
+ * @return string
207
+ */
208
+
209
+ acf.strCamelCase = function( str ){
210
+ var matches = str.match( /([a-zA-Z0-9]+)/g );
211
+ return matches ? matches.map(function( s, i ){
212
+ var c = s.charAt(0);
213
+ return ( i === 0 ? c.toLowerCase() : c.toUpperCase() ) + s.slice(1);
214
+ }).join('') : '';
215
+ };
216
+
217
+ /**
218
+ * strPascalCase
219
+ *
220
+ * Converts a string into PascalCase
221
+ * Thanks to https://stackoverflow.com/questions/1026069/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript
222
+ *
223
+ * @date 14/12/17
224
+ * @since 5.6.5
225
+ *
226
+ * @param string str
227
+ * @return string
228
+ */
229
+
230
+ acf.strPascalCase = function( str ){
231
+ var camel = acf.strCamelCase( str );
232
+ return camel.charAt(0).toUpperCase() + camel.slice(1);
233
+ };
234
+
235
+ /**
236
+ * acf.strSlugify
237
+ *
238
+ * Converts a string into a HTML class friendly slug
239
+ *
240
+ * @date 21/3/18
241
+ * @since 5.6.9
242
+ *
243
+ * @param string str
244
+ * @return string
245
+ */
246
+
247
+ acf.strSlugify = function( str ){
248
+ return acf.strReplace( '_', '-', str.toLowerCase() );
249
+ };
250
+
251
+
252
+ acf.strSanitize = function( str ){
253
+
254
+ // chars (https://jsperf.com/replace-foreign-characters)
255
+ var map = {
256
+ "À": "A",
257
+ "Á": "A",
258
+ "Â": "A",
259
+ "Ã": "A",
260
+ "Ä": "A",
261
+ "Å": "A",
262
+ "Æ": "AE",
263
+ "Ç": "C",
264
+ "È": "E",
265
+ "É": "E",
266
+ "Ê": "E",
267
+ "Ë": "E",
268
+ "Ì": "I",
269
+ "Í": "I",
270
+ "Î": "I",
271
+ "Ï": "I",
272
+ "Ð": "D",
273
+ "Ñ": "N",
274
+ "Ò": "O",
275
+ "Ó": "O",
276
+ "Ô": "O",
277
+ "Õ": "O",
278
+ "Ö": "O",
279
+ "Ø": "O",
280
+ "Ù": "U",
281
+ "Ú": "U",
282
+ "Û": "U",
283
+ "Ü": "U",
284
+ "Ý": "Y",
285
+ "ß": "s",
286
+ "à": "a",
287
+ "á": "a",
288
+ "â": "a",
289
+ "ã": "a",
290
+ "ä": "a",
291
+ "å": "a",
292
+ "æ": "ae",
293
+ "ç": "c",
294
+ "è": "e",
295
+ "é": "e",
296
+ "ê": "e",
297
+ "ë": "e",
298
+ "ì": "i",
299
+ "í": "i",
300
+ "î": "i",
301
+ "ï": "i",
302
+ "ñ": "n",
303
+ "ò": "o",
304
+ "ó": "o",
305
+ "ô": "o",
306
+ "õ": "o",
307
+ "ö": "o",
308
+ "ø": "o",
309
+ "ù": "u",
310
+ "ú": "u",
311
+ "û": "u",
312
+ "ü": "u",
313
+ "ý": "y",
314
+ "ÿ": "y",
315
+ "Ā": "A",
316
+ "ā": "a",
317
+ "Ă": "A",
318
+ "ă": "a",
319
+ "Ą": "A",
320
+ "ą": "a",
321
+ "Ć": "C",
322
+ "ć": "c",
323
+ "Ĉ": "C",
324
+ "ĉ": "c",
325
+ "Ċ": "C",
326
+ "ċ": "c",
327
+ "Č": "C",
328
+ "č": "c",
329
+ "Ď": "D",
330
+ "ď": "d",
331
+ "Đ": "D",
332
+ "đ": "d",
333
+ "Ē": "E",
334
+ "ē": "e",
335
+ "Ĕ": "E",
336
+ "ĕ": "e",
337
+ "Ė": "E",
338
+ "ė": "e",
339
+ "Ę": "E",
340
+ "ę": "e",
341
+ "Ě": "E",
342
+ "ě": "e",
343
+ "Ĝ": "G",
344
+ "ĝ": "g",
345
+ "Ğ": "G",
346
+ "ğ": "g",
347
+ "Ġ": "G",
348
+ "ġ": "g",
349
+ "Ģ": "G",
350
+ "ģ": "g",
351
+ "Ĥ": "H",
352
+ "ĥ": "h",
353
+ "Ħ": "H",
354
+ "ħ": "h",
355
+ "Ĩ": "I",
356
+ "ĩ": "i",
357
+ "Ī": "I",
358
+ "ī": "i",
359
+ "Ĭ": "I",
360
+ "ĭ": "i",
361
+ "Į": "I",
362
+ "į": "i",
363
+ "İ": "I",
364
+ "ı": "i",
365
+ "IJ": "IJ",
366
+ "ij": "ij",
367
+ "Ĵ": "J",
368
+ "ĵ": "j",
369
+ "Ķ": "K",
370
+ "ķ": "k",
371
+ "Ĺ": "L",
372
+ "ĺ": "l",
373
+ "Ļ": "L",
374
+ "ļ": "l",
375
+ "Ľ": "L",
376
+ "ľ": "l",
377
+ "Ŀ": "L",
378
+ "ŀ": "l",
379
+ "Ł": "l",
380
+ "ł": "l",
381
+ "Ń": "N",
382
+ "ń": "n",
383
+ "Ņ": "N",
384
+ "ņ": "n",
385
+ "Ň": "N",
386
+ "ň": "n",
387
+ "ʼn": "n",
388
+ "Ō": "O",
389
+ "ō": "o",
390
+ "Ŏ": "O",
391
+ "ŏ": "o",
392
+ "Ő": "O",
393
+ "ő": "o",
394
+ "Œ": "OE",
395
+ "œ": "oe",
396
+ "Ŕ": "R",
397
+ "ŕ": "r",
398
+ "Ŗ": "R",
399
+ "ŗ": "r",
400
+ "Ř": "R",
401
+ "ř": "r",
402
+ "Ś": "S",
403
+ "ś": "s",
404
+ "Ŝ": "S",
405
+ "ŝ": "s",
406
+ "Ş": "S",
407
+ "ş": "s",
408
+ "Š": "S",
409
+ "š": "s",
410
+ "Ţ": "T",
411
+ "ţ": "t",
412
+ "Ť": "T",
413
+ "ť": "t",
414
+ "Ŧ": "T",
415
+ "ŧ": "t",
416
+ "Ũ": "U",
417
+ "ũ": "u",
418
+ "Ū": "U",
419
+ "ū": "u",
420
+ "Ŭ": "U",
421
+ "ŭ": "u",
422
+ "Ů": "U",
423
+ "ů": "u",
424
+ "Ű": "U",
425
+ "ű": "u",
426
+ "Ų": "U",
427
+ "ų": "u",
428
+ "Ŵ": "W",
429
+ "ŵ": "w",
430
+ "Ŷ": "Y",
431
+ "ŷ": "y",
432
+ "Ÿ": "Y",
433
+ "Ź": "Z",
434
+ "ź": "z",
435
+ "Ż": "Z",
436
+ "ż": "z",
437
+ "Ž": "Z",
438
+ "ž": "z",
439
+ "ſ": "s",
440
+ "ƒ": "f",
441
+ "Ơ": "O",
442
+ "ơ": "o",
443
+ "Ư": "U",
444
+ "ư": "u",
445
+ "Ǎ": "A",
446
+ "ǎ": "a",
447
+ "Ǐ": "I",
448
+ "ǐ": "i",
449
+ "Ǒ": "O",
450
+ "ǒ": "o",
451
+ "Ǔ": "U",
452
+ "ǔ": "u",
453
+ "Ǖ": "U",
454
+ "ǖ": "u",
455
+ "Ǘ": "U",
456
+ "ǘ": "u",
457
+ "Ǚ": "U",
458
+ "ǚ": "u",
459
+ "Ǜ": "U",
460
+ "ǜ": "u",
461
+ "Ǻ": "A",
462
+ "ǻ": "a",
463
+ "Ǽ": "AE",
464
+ "ǽ": "ae",
465
+ "Ǿ": "O",
466
+ "ǿ": "o",
467
+
468
+ // extra
469
+ ' ': '_',
470
+ "'": '',
471
+ '?': '',
472
+ '/': '',
473
+ '\\': '',
474
+ '.': '',
475
+ ',': '',
476
+ '`': '',
477
+ '>': '',
478
+ '<': '',
479
+ '"': '',
480
+ '[': '',
481
+ ']': '',
482
+ '|': '',
483
+ '{': '',
484
+ '}': '',
485
+ '(': '',
486
+ ')': ''
487
+ };
488
+
489
+ // vars
490
+ var nonWord = /\W/g;
491
+ var mapping = function (c) {
492
+ return (map[c] !== undefined) ? map[c] : c;
493
+ };
494
+
495
+ // replace
496
+ str = str.replace(nonWord, mapping);
497
+
498
+ // lowercase
499
+ str = str.toLowerCase();
500
+
501
+ // return
502
+ return str;
503
+ };
504
+
505
+ /**
506
+ * acf.strMatch
507
+ *
508
+ * Returns the number of characters that match between two strings
509
+ *
510
+ * @date 1/2/18
511
+ * @since 5.6.5
512
+ *
513
+ * @param type $var Description. Default.
514
+ * @return type Description.
515
+ */
516
+
517
+ acf.strMatch = function( s1, s2 ){
518
+
519
+ // vars
520
+ var val = 0;
521
+ var min = Math.min( s1.length, s2.length );
522
+
523
+ // loop
524
+ for( var i = 0; i < min; i++ ) {
525
+ if( s1[i] !== s2[i] ) {
526
+ break;
527
+ }
528
+ val++;
529
+ }
530
+
531
+ // return
532
+ return val;
533
+ };
534
+
535
+ /**
536
+ * Escapes HTML entities from a string.
537
+ *
538
+ * @date 08/06/2020
539
+ * @since 5.9.0
540
+ *
541
+ * @param string string The input string.
542
+ * @return string
543
+ */
544
+ acf.strEscape = function( string ){
545
+ var htmlEscapes = {
546
+ '&': '&amp;',
547
+ '<': '&lt;',
548
+ '>': '&gt;',
549
+ '"': '&quot;',
550
+ "'": '&#39;'
551
+ };
552
+ return ('' + string).replace(/[&<>"']/g, function( chr ) {
553
+ return htmlEscapes[ chr ];
554
+ });
555
+ };
556
+
557
+ // Tests.
558
+ //console.log( acf.strEscape('Test 1') );
559
+ //console.log( acf.strEscape('Test & 1') );
560
+ //console.log( acf.strEscape('Test\'s &amp; 1') );
561
+ //console.log( acf.strEscape('<script>js</script>') );
562
+
563
+ /**
564
+ * Unescapes HTML entities from a string.
565
+ *
566
+ * @date 08/06/2020
567
+ * @since 5.9.0
568
+ *
569
+ * @param string string The input string.
570
+ * @return string
571
+ */
572
+ acf.strUnescape = function( string ){
573
+ var htmlUnescapes = {
574
+ '&amp;': '&',
575
+ '&lt;': '<',
576
+ '&gt;': '>',
577
+ '&quot;': '"',
578
+ '&#39;': "'"
579
+ };
580
+ return ('' + string).replace(/&amp;|&lt;|&gt;|&quot;|&#39;/g, function( entity ) {
581
+ return htmlUnescapes[ entity ];
582
+ });
583
+ };
584
+
585
+ // Tests.
586
+ //console.log( acf.strUnescape( acf.strEscape('Test 1') ) );
587
+ //console.log( acf.strUnescape( acf.strEscape('Test & 1') ) );
588
+ //console.log( acf.strUnescape( acf.strEscape('Test\'s &amp; 1') ) );
589
+ //console.log( acf.strUnescape( acf.strEscape('<script>js</script>') ) );
590
+
591
+ /**
592
+ * Escapes HTML entities from a string.
593
+ *
594
+ * @date 08/06/2020
595
+ * @since 5.9.0
596
+ *
597
+ * @param string string The input string.
598
+ * @return string
599
+ */
600
+ acf.escAttr = acf.strEscape;
601
+
602
+ /**
603
+ * Encodes <script> tags for safe HTML output.
604
+ *
605
+ * @date 08/06/2020
606
+ * @since 5.9.0
607
+ *
608
+ * @param string string The input string.
609
+ * @return string
610
+ */
611
+ acf.escHtml = function( string ){
612
+ return ('' + string).replace(/<script|<\/script/g, function( html ) {
613
+ return acf.strEscape( html );
614
+ });
615
+ };
616
+
617
+ // Tests.
618
+ //console.log( acf.escHtml('<script>js</script>') );
619
+ //console.log( acf.escHtml( acf.strEscape('<script>js</script>') ) );
620
+ //console.log( acf.escHtml( '<script>js1</script><script>js2</script>' ) );
621
+
622
+ /**
623
+ * acf.decode
624
+ *
625
+ * description
626
+ *
627
+ * @date 13/1/18
628
+ * @since 5.6.5
629
+ *
630
+ * @param type $var Description. Default.
631
+ * @return type Description.
632
+ */
633
+
634
+ acf.decode = function( string ){
635
+ return $('<textarea/>').html( string ).text();
636
+ };
637
+
638
+
639
+
640
+ /**
641
+ * parseArgs
642
+ *
643
+ * Merges together defaults and args much like the WP wp_parse_args function
644
+ *
645
+ * @date 14/12/17
646
+ * @since 5.6.5
647
+ *
648
+ * @param object args
649
+ * @param object defaults
650
+ * @return object
651
+ */
652
+
653
+ acf.parseArgs = function( args, defaults ){
654
+ if( typeof args !== 'object' ) args = {};
655
+ if( typeof defaults !== 'object' ) defaults = {};
656
+ return $.extend({}, defaults, args);
657
+ }
658
+
659
+ /**
660
+ * __
661
+ *
662
+ * Retrieve the translation of $text.
663
+ *
664
+ * @date 16/4/18
665
+ * @since 5.6.9
666
+ *
667
+ * @param string text Text to translate.
668
+ * @return string Translated text.
669
+ */
670
+
671
+ if( window.acfL10n == undefined ) {
672
+ acfL10n = {};
673
+ }
674
+
675
+ acf.__ = function( text ){
676
+ return acfL10n[ text ] || text;
677
+ };
678
+
679
+ /**
680
+ * _x
681
+ *
682
+ * Retrieve translated string with gettext context.
683
+ *
684
+ * @date 16/4/18
685
+ * @since 5.6.9
686
+ *
687
+ * @param string text Text to translate.
688
+ * @param string context Context information for the translators.
689
+ * @return string Translated text.
690
+ */
691
+
692
+ acf._x = function( text, context ){
693
+ return acfL10n[ text + '.' + context ] || acfL10n[ text ] || text;
694
+ };
695
+
696
+ /**
697
+ * _n
698
+ *
699
+ * Retrieve the plural or single form based on the amount.
700
+ *
701
+ * @date 16/4/18
702
+ * @since 5.6.9
703
+ *
704
+ * @param string single Single text to translate.
705
+ * @param string plural Plural text to translate.
706
+ * @param int number The number to compare against.
707
+ * @return string Translated text.
708
+ */
709
+
710
+ acf._n = function( single, plural, number ){
711
+ if( number == 1 ) {
712
+ return acf.__(single);
713
+ } else {
714
+ return acf.__(plural);
715
+ }
716
+ };
717
+
718
+ acf.isArray = function( a ){
719
+ return Array.isArray(a);
720
+ };
721
+
722
+ acf.isObject = function( a ){
723
+ return ( typeof a === 'object' );
724
+ }
725
+
726
+ /**
727
+ * serialize
728
+ *
729
+ * description
730
+ *
731
+ * @date 24/12/17
732
+ * @since 5.6.5
733
+ *
734
+ * @param type $var Description. Default.
735
+ * @return type Description.
736
+ */
737
+
738
+ var buildObject = function( obj, name, value ){
739
+
740
+ // replace [] with placeholder
741
+ name = name.replace('[]', '[%%index%%]');
742
+
743
+ // vars
744
+ var keys = name.match(/([^\[\]])+/g);
745
+ if( !keys ) return;
746
+ var length = keys.length;
747
+ var ref = obj;
748
+
749
+ // loop
750
+ for( var i = 0; i < length; i++ ) {
751
+
752
+ // vars
753
+ var key = String( keys[i] );
754
+
755
+ // value
756
+ if( i == length - 1 ) {
757
+
758
+ // %%index%%
759
+ if( key === '%%index%%' ) {
760
+ ref.push( value );
761
+
762
+ // default
763
+ } else {
764
+ ref[ key ] = value;
765
+ }
766
+
767
+ // path
768
+ } else {
769
+
770
+ // array
771
+ if( keys[i+1] === '%%index%%' ) {
772
+ if( !acf.isArray(ref[ key ]) ) {
773
+ ref[ key ] = [];
774
+ }
775
+
776
+ // object
777
+ } else {
778
+ if( !acf.isObject(ref[ key ]) ) {
779
+ ref[ key ] = {};
780
+ }
781
+ }
782
+
783
+ // crawl
784
+ ref = ref[ key ];
785
+ }
786
+ }
787
+ };
788
+
789
+ acf.serialize = function( $el, prefix ){
790
+
791
+ // vars
792
+ var obj = {};
793
+ var inputs = acf.serializeArray( $el );
794
+
795
+ // prefix
796
+ if( prefix !== undefined ) {
797
+
798
+ // filter and modify
799
+ inputs = inputs.filter(function( item ){
800
+ return item.name.indexOf(prefix) === 0;
801
+ }).map(function( item ){
802
+ item.name = item.name.slice(prefix.length);
803
+ return item;
804
+ });
805
+ }
806
+
807
+ // loop
808
+ for( var i = 0; i < inputs.length; i++ ) {
809
+ buildObject( obj, inputs[i].name, inputs[i].value );
810
+ }
811
+
812
+ // return
813
+ return obj;
814
+ };
815
+
816
+ /**
817
+ * acf.serializeArray
818
+ *
819
+ * Similar to $.serializeArray() but works with a parent wrapping element.
820
+ *
821
+ * @date 19/8/18
822
+ * @since 5.7.3
823
+ *
824
+ * @param jQuery $el The element or form to serialize.
825
+ * @return array
826
+ */
827
+
828
+ acf.serializeArray = function( $el ){
829
+ return $el.find('select, textarea, input').serializeArray();
830
+ }
831
+
832
+ /**
833
+ * acf.serializeForAjax
834
+ *
835
+ * Returns an object containing name => value data ready to be encoded for Ajax.
836
+ *
837
+ * @date 17/12/18
838
+ * @since 5.8.0
839
+ *
840
+ * @param jQUery $el The element or form to serialize.
841
+ * @return object
842
+ */
843
+ acf.serializeForAjax = function( $el ){
844
+
845
+ // vars
846
+ var data = {};
847
+ var index = {};
848
+
849
+ // Serialize inputs.
850
+ var inputs = acf.serializeArray( $el );
851
+
852
+ // Loop over inputs and build data.
853
+ inputs.map(function( item ){
854
+
855
+ // Append to array.
856
+ if( item.name.slice(-2) === '[]' ) {
857
+ data[ item.name ] = data[ item.name ] || [];
858
+ data[ item.name ].push( item.value );
859
+ // Append
860
+ } else {
861
+ data[ item.name ] = item.value;
862
+ }
863
+ });
864
+
865
+ // return
866
+ return data;
867
+ };
868
+
869
+ /**
870
+ * addAction
871
+ *
872
+ * Wrapper for acf.hooks.addAction
873
+ *
874
+ * @date 14/12/17
875
+ * @since 5.6.5
876
+ *
877
+ * @param n/a
878
+ * @return this
879
+ */
880
+
881
+ /*
882
+ var prefixAction = function( action ){
883
+ return 'acf_' + action;
884
+ }
885
+ */
886
+
887
+ acf.addAction = function( action, callback, priority, context ){
888
+ //action = prefixAction(action);
889
+ acf.hooks.addAction.apply(this, arguments);
890
+ return this;
891
+ };
892
+
893
+
894
+ /**
895
+ * removeAction
896
+ *
897
+ * Wrapper for acf.hooks.removeAction
898
+ *
899
+ * @date 14/12/17
900
+ * @since 5.6.5
901
+ *
902
+ * @param n/a
903
+ * @return this
904
+ */
905
+
906
+ acf.removeAction = function( action, callback ){
907
+ //action = prefixAction(action);
908
+ acf.hooks.removeAction.apply(this, arguments);
909
+ return this;
910
+ };
911
+
912
+
913
+ /**
914
+ * doAction
915
+ *
916
+ * Wrapper for acf.hooks.doAction
917
+ *
918
+ * @date 14/12/17
919
+ * @since 5.6.5
920
+ *
921
+ * @param n/a
922
+ * @return this
923
+ */
924
+
925
+ var actionHistory = {};
926
+ //var currentAction = false;
927
+ acf.doAction = function( action ){
928
+ //action = prefixAction(action);
929
+ //currentAction = action;
930
+ actionHistory[ action ] = 1;
931
+ acf.hooks.doAction.apply(this, arguments);
932
+ actionHistory[ action ] = 0;
933
+ return this;
934
+ };
935
+
936
+
937
+ /**
938
+ * doingAction
939
+ *
940
+ * Return true if doing action
941
+ *
942
+ * @date 14/12/17
943
+ * @since 5.6.5
944
+ *
945
+ * @param n/a
946
+ * @return this
947
+ */
948
+
949
+ acf.doingAction = function( action ){
950
+ //action = prefixAction(action);
951
+ return (actionHistory[ action ] === 1);
952
+ };
953
+
954
+
955
+ /**
956
+ * didAction
957
+ *
958
+ * Wrapper for acf.hooks.doAction
959
+ *
960
+ * @date 14/12/17
961
+ * @since 5.6.5
962
+ *
963
+ * @param n/a
964
+ * @return this
965
+ */
966
+
967
+ acf.didAction = function( action ){
968
+ //action = prefixAction(action);
969
+ return (actionHistory[ action ] !== undefined);
970
+ };
971
+
972
+ /**
973
+ * currentAction
974
+ *
975
+ * Wrapper for acf.hooks.doAction
976
+ *
977
+ * @date 14/12/17
978
+ * @since 5.6.5
979
+ *
980
+ * @param n/a
981
+ * @return this
982
+ */
983
+
984
+ acf.currentAction = function(){
985
+ for( var k in actionHistory ) {
986
+ if( actionHistory[k] ) {
987
+ return k;
988
+ }
989
+ }
990
+ return false;
991
+ };
992
+
993
+ /**
994
+ * addFilter
995
+ *
996
+ * Wrapper for acf.hooks.addFilter
997
+ *
998
+ * @date 14/12/17
999
+ * @since 5.6.5
1000
+ *
1001
+ * @param n/a
1002
+ * @return this
1003
+ */
1004
+
1005
+ acf.addFilter = function( action ){
1006
+ //action = prefixAction(action);
1007
+ acf.hooks.addFilter.apply(this, arguments);
1008
+ return this;
1009
+ };
1010
+
1011
+
1012
+ /**
1013
+ * removeFilter
1014
+ *
1015
+ * Wrapper for acf.hooks.removeFilter
1016
+ *
1017
+ * @date 14/12/17
1018
+ * @since 5.6.5
1019
+ *
1020
+ * @param n/a
1021
+ * @return this
1022
+ */
1023
+
1024
+ acf.removeFilter = function( action ){
1025
+ //action = prefixAction(action);
1026
+ acf.hooks.removeFilter.apply(this, arguments);
1027
+ return this;
1028
+ };
1029
+
1030
+
1031
+ /**
1032
+ * applyFilters
1033
+ *
1034
+ * Wrapper for acf.hooks.applyFilters
1035
+ *
1036
+ * @date 14/12/17
1037
+ * @since 5.6.5
1038
+ *
1039
+ * @param n/a
1040
+ * @return this
1041
+ */
1042
+
1043
+ acf.applyFilters = function( action ){
1044
+ //action = prefixAction(action);
1045
+ return acf.hooks.applyFilters.apply(this, arguments);
1046
+ };
1047
+
1048
+
1049
+ /**
1050
+ * getArgs
1051
+ *
1052
+ * description
1053
+ *
1054
+ * @date 15/12/17
1055
+ * @since 5.6.5
1056
+ *
1057
+ * @param type $var Description. Default.
1058
+ * @return type Description.
1059
+ */
1060
+
1061
+ acf.arrayArgs = function( args ){
1062
+ return Array.prototype.slice.call( args );
1063
+ };
1064
+
1065
+
1066
+ /**
1067
+ * extendArgs
1068
+ *
1069
+ * description
1070
+ *
1071
+ * @date 15/12/17
1072
+ * @since 5.6.5
1073
+ *
1074
+ * @param type $var Description. Default.
1075
+ * @return type Description.
1076
+ */
1077
+
1078
+ /*
1079
+ acf.extendArgs = function( ){
1080
+ var args = Array.prototype.slice.call( arguments );
1081
+ var realArgs = args.shift();
1082
+
1083
+ Array.prototype.push.call(arguments, 'bar')
1084
+ return Array.prototype.push.apply( args, arguments );
1085
+ };
1086
+ */
1087
+
1088
+ // Preferences
1089
+ // - use try/catch to avoid JS error if cookies are disabled on front-end form
1090
+ try {
1091
+ var preferences = JSON.parse(localStorage.getItem('acf')) || {};
1092
+ } catch(e) {
1093
+ var preferences = {};
1094
+ }
1095
+
1096
+
1097
+ /**
1098
+ * getPreferenceName
1099
+ *
1100
+ * Gets the true preference name.
1101
+ * Converts "this.thing" to "thing-123" if editing post 123.
1102
+ *
1103
+ * @date 11/11/17
1104
+ * @since 5.6.5
1105
+ *
1106
+ * @param string name
1107
+ * @return string
1108
+ */
1109
+
1110
+ var getPreferenceName = function( name ){
1111
+ if( name.substr(0, 5) === 'this.' ) {
1112
+ name = name.substr(5) + '-' + acf.get('post_id');
1113
+ }
1114
+ return name;
1115
+ };
1116
+
1117
+
1118
+ /**
1119
+ * acf.getPreference
1120
+ *
1121
+ * Gets a preference setting or null if not set.
1122
+ *
1123
+ * @date 11/11/17
1124
+ * @since 5.6.5
1125
+ *
1126
+ * @param string name
1127
+ * @return mixed
1128
+ */
1129
+
1130
+ acf.getPreference = function( name ){
1131
+ name = getPreferenceName( name );
1132
+ return preferences[ name ] || null;
1133
+ }
1134
+
1135
+
1136
+ /**
1137
+ * acf.setPreference
1138
+ *
1139
+ * Sets a preference setting.
1140
+ *
1141
+ * @date 11/11/17
1142
+ * @since 5.6.5
1143
+ *
1144
+ * @param string name
1145
+ * @param mixed value
1146
+ * @return n/a
1147
+ */
1148
+
1149
+ acf.setPreference = function( name, value ){
1150
+ name = getPreferenceName( name );
1151
+ if( value === null ) {
1152
+ delete preferences[ name ];
1153
+ } else {
1154
+ preferences[ name ] = value;
1155
+ }
1156
+ localStorage.setItem('acf', JSON.stringify(preferences));
1157
+ }
1158
+
1159
+
1160
+ /**
1161
+ * acf.removePreference
1162
+ *
1163
+ * Removes a preference setting.
1164
+ *
1165
+ * @date 11/11/17
1166
+ * @since 5.6.5
1167
+ *
1168
+ * @param string name
1169
+ * @return n/a
1170
+ */
1171
+
1172
+ acf.removePreference = function( name ){
1173
+ acf.setPreference(name, null);
1174
+ };
1175
+
1176
+
1177
+ /**
1178
+ * remove
1179
+ *
1180
+ * Removes an element with fade effect
1181
+ *
1182
+ * @date 1/1/18
1183
+ * @since 5.6.5
1184
+ *
1185
+ * @param type $var Description. Default.
1186
+ * @return type Description.
1187
+ */
1188
+
1189
+ acf.remove = function( props ){
1190
+
1191
+ // allow jQuery
1192
+ if( props instanceof jQuery ) {
1193
+ props = {
1194
+ target: props
1195
+ };
1196
+ }
1197
+
1198
+ // defaults
1199
+ props = acf.parseArgs(props, {
1200
+ target: false,
1201
+ endHeight: 0,
1202
+ complete: function(){}
1203
+ });
1204
+
1205
+ // action
1206
+ acf.doAction('remove', props.target);
1207
+
1208
+ // tr
1209
+ if( props.target.is('tr') ) {
1210
+ removeTr( props );
1211
+
1212
+ // div
1213
+ } else {
1214
+ removeDiv( props );
1215
+ }
1216
+
1217
+ };
1218
+
1219
+ /**
1220
+ * removeDiv
1221
+ *
1222
+ * description
1223
+ *
1224
+ * @date 16/2/18
1225
+ * @since 5.6.9
1226
+ *
1227
+ * @param type $var Description. Default.
1228
+ * @return type Description.
1229
+ */
1230
+
1231
+ var removeDiv = function( props ){
1232
+
1233
+ // vars
1234
+ var $el = props.target;
1235
+ var height = $el.height();
1236
+ var width = $el.width();
1237
+ var margin = $el.css('margin');
1238
+ var outerHeight = $el.outerHeight(true);
1239
+ var style = $el.attr('style') + ''; // needed to copy
1240
+
1241
+ // wrap
1242
+ $el.wrap('<div class="acf-temp-remove" style="height:' + outerHeight + 'px"></div>');
1243
+ var $wrap = $el.parent();
1244
+
1245
+ // set pos
1246
+ $el.css({
1247
+ height: height,
1248
+ width: width,
1249
+ margin: margin,
1250
+ position: 'absolute'
1251
+ });
1252
+
1253
+ // fade wrap
1254
+ setTimeout(function(){
1255
+
1256
+ $wrap.css({
1257
+ opacity: 0,
1258
+ height: props.endHeight
1259
+ });
1260
+
1261
+ }, 50);
1262
+
1263
+ // remove
1264
+ setTimeout(function(){
1265
+
1266
+ $el.attr('style', style);
1267
+ $wrap.remove();
1268
+ props.complete();
1269
+
1270
+ }, 301);
1271
+ };
1272
+
1273
+ /**
1274
+ * removeTr
1275
+ *
1276
+ * description
1277
+ *
1278
+ * @date 16/2/18
1279
+ * @since 5.6.9
1280
+ *
1281
+ * @param type $var Description. Default.
1282
+ * @return type Description.
1283
+ */
1284
+
1285
+ var removeTr = function( props ){
1286
+
1287
+ // vars
1288
+ var $tr = props.target;
1289
+ var height = $tr.height();
1290
+ var children = $tr.children().length;
1291
+
1292
+ // create dummy td
1293
+ var $td = $('<td class="acf-temp-remove" style="padding:0; height:' + height + 'px" colspan="' + children + '"></td>');
1294
+
1295
+ // fade away tr
1296
+ $tr.addClass('acf-remove-element');
1297
+
1298
+ // update HTML after fade animation
1299
+ setTimeout(function(){
1300
+ $tr.html( $td );
1301
+ }, 251);
1302
+
1303
+ // allow .acf-temp-remove to exist before changing CSS
1304
+ setTimeout(function(){
1305
+
1306
+ // remove class
1307
+ $tr.removeClass('acf-remove-element');
1308
+
1309
+ // collapse
1310
+ $td.css({
1311
+ height: props.endHeight
1312
+ });
1313
+
1314
+ }, 300);
1315
+
1316
+ // remove
1317
+ setTimeout(function(){
1318
+
1319
+ $tr.remove();
1320
+ props.complete();
1321
+
1322
+ }, 451);
1323
+ };
1324
+
1325
+ /**
1326
+ * duplicate
1327
+ *
1328
+ * description
1329
+ *
1330
+ * @date 3/1/18
1331
+ * @since 5.6.5
1332
+ *
1333
+ * @param type $var Description. Default.
1334
+ * @return type Description.
1335
+ */
1336
+
1337
+ acf.duplicate = function( args ){
1338
+
1339
+ // allow jQuery
1340
+ if( args instanceof jQuery ) {
1341
+ args = {
1342
+ target: args
1343
+ };
1344
+ }
1345
+
1346
+ // defaults
1347
+ args = acf.parseArgs(args, {
1348
+ target: false,
1349
+ search: '',
1350
+ replace: '',
1351
+ rename: true,
1352
+ before: function( $el ){},
1353
+ after: function( $el, $el2 ){},
1354
+ append: function( $el, $el2 ){
1355
+ $el.after( $el2 );
1356
+ }
1357
+ });
1358
+
1359
+ // compatibility
1360
+ args.target = args.target || args.$el;
1361
+
1362
+ // vars
1363
+ var $el = args.target;
1364
+
1365
+ // search
1366
+ args.search = args.search || $el.attr('data-id');
1367
+ args.replace = args.replace || acf.uniqid();
1368
+
1369
+ // before
1370
+ // - allow acf to modify DOM
1371
+ // - fixes bug where select field option is not selected
1372
+ args.before( $el );
1373
+ acf.doAction('before_duplicate', $el);
1374
+
1375
+ // clone
1376
+ var $el2 = $el.clone();
1377
+
1378
+ // rename
1379
+ if( args.rename ) {
1380
+ acf.rename({
1381
+ target: $el2,
1382
+ search: args.search,
1383
+ replace: args.replace,
1384
+ replacer: ( typeof args.rename === 'function' ? args.rename : null )
1385
+ });
1386
+ }
1387
+
1388
+ // remove classes
1389
+ $el2.removeClass('acf-clone');
1390
+ $el2.find('.ui-sortable').removeClass('ui-sortable');
1391
+
1392
+ // after
1393
+ // - allow acf to modify DOM
1394
+ args.after( $el, $el2 );
1395
+ acf.doAction('after_duplicate', $el, $el2 );
1396
+
1397
+ // append
1398
+ args.append( $el, $el2 );
1399
+
1400
+ /**
1401
+ * Fires after an element has been duplicated and appended to the DOM.
1402
+ *
1403
+ * @date 30/10/19
1404
+ * @since 5.8.7
1405
+ *
1406
+ * @param jQuery $el The original element.
1407
+ * @param jQuery $el2 The duplicated element.
1408
+ */
1409
+ acf.doAction('duplicate', $el, $el2 );
1410
+
1411
+ // append
1412
+ acf.doAction('append', $el2);
1413
+
1414
+ // return
1415
+ return $el2;
1416
+ };
1417
+
1418
+ /**
1419
+ * rename
1420
+ *
1421
+ * description
1422
+ *
1423
+ * @date 7/1/18
1424
+ * @since 5.6.5
1425
+ *
1426
+ * @param type $var Description. Default.
1427
+ * @return type Description.
1428
+ */
1429
+
1430
+ acf.rename = function( args ){
1431
+
1432
+ // Allow jQuery param.
1433
+ if( args instanceof jQuery ) {
1434
+ args = {
1435
+ target: args
1436
+ };
1437
+ }
1438
+
1439
+ // Apply default args.
1440
+ args = acf.parseArgs(args, {
1441
+ target: false,
1442
+ destructive: false,
1443
+ search: '',
1444
+ replace: '',
1445
+ replacer: null
1446
+ });
1447
+
1448
+ // Extract args.
1449
+ var $el = args.target;
1450
+
1451
+ // Provide backup for empty args.
1452
+ if( !args.search ) {
1453
+ args.search = $el.attr('data-id');
1454
+ }
1455
+ if( !args.replace ) {
1456
+ args.replace = acf.uniqid('acf');
1457
+ }
1458
+ if( !args.replacer ) {
1459
+ args.replacer = function( name, value, search, replace ){
1460
+ return value.replace( search, replace );
1461
+ };
1462
+ }
1463
+
1464
+ // Callback function for jQuery replacing.
1465
+ var withReplacer = function( name ){
1466
+ return function( i, value ){
1467
+ return args.replacer( name, value, args.search, args.replace );
1468
+ }
1469
+ };
1470
+
1471
+ // Destructive Replace.
1472
+ if( args.destructive ) {
1473
+ var html = acf.strReplace( args.search, args.replace, $el.outerHTML() );
1474
+ $el.replaceWith( html );
1475
+
1476
+ // Standard Replace.
1477
+ } else {
1478
+ $el.attr('data-id', args.replace);
1479
+ $el.find('[id*="' + args.search + '"]').attr('id', withReplacer('id'));
1480
+ $el.find('[for*="' + args.search + '"]').attr('for', withReplacer('for'));
1481
+ $el.find('[name*="' + args.search + '"]').attr('name', withReplacer('name'));
1482
+ }
1483
+
1484
+ // return
1485
+ return $el;
1486
+ };
1487
+
1488
+
1489
+ /**
1490
+ * acf.prepareForAjax
1491
+ *
1492
+ * description
1493
+ *
1494
+ * @date 4/1/18
1495
+ * @since 5.6.5
1496
+ *
1497
+ * @param type $var Description. Default.
1498
+ * @return type Description.
1499
+ */
1500
+
1501
+ acf.prepareForAjax = function( data ){
1502
+
1503
+ // required
1504
+ data.nonce = acf.get('nonce');
1505
+ data.post_id = acf.get('post_id');
1506
+
1507
+ // language
1508
+ if( acf.has('language') ) {
1509
+ data.lang = acf.get('language');
1510
+ }
1511
+
1512
+ // filter for 3rd party customization
1513
+ data = acf.applyFilters('prepare_for_ajax', data);
1514
+
1515
+ // return
1516
+ return data;
1517
+ };
1518
+
1519
+
1520
+ /**
1521
+ * acf.startButtonLoading
1522
+ *
1523
+ * description
1524
+ *
1525
+ * @date 5/1/18
1526
+ * @since 5.6.5
1527
+ *
1528
+ * @param type $var Description. Default.
1529
+ * @return type Description.
1530
+ */
1531
+
1532
+ acf.startButtonLoading = function( $el ){
1533
+ $el.prop('disabled', true);
1534
+ $el.after(' <i class="acf-loading"></i>');
1535
+ }
1536
+
1537
+ acf.stopButtonLoading = function( $el ){
1538
+ $el.prop('disabled', false);
1539
+ $el.next('.acf-loading').remove();
1540
+ }
1541
+
1542
+
1543
+ /**
1544
+ * acf.showLoading
1545
+ *
1546
+ * description
1547
+ *
1548
+ * @date 12/1/18
1549
+ * @since 5.6.5
1550
+ *
1551
+ * @param type $var Description. Default.
1552
+ * @return type Description.
1553
+ */
1554
+
1555
+ acf.showLoading = function( $el ){
1556
+ $el.append('<div class="acf-loading-overlay"><i class="acf-loading"></i></div>');
1557
+ };
1558
+
1559
+ acf.hideLoading = function( $el ){
1560
+ $el.children('.acf-loading-overlay').remove();
1561
+ };
1562
+
1563
+
1564
+ /**
1565
+ * acf.updateUserSetting
1566
+ *
1567
+ * description
1568
+ *
1569
+ * @date 5/1/18
1570
+ * @since 5.6.5
1571
+ *
1572
+ * @param type $var Description. Default.
1573
+ * @return type Description.
1574
+ */
1575
+
1576
+ acf.updateUserSetting = function( name, value ){
1577
+
1578
+ var ajaxData = {
1579
+ action: 'acf/ajax/user_setting',
1580
+ name: name,
1581
+ value: value
1582
+ };
1583
+
1584
+ $.ajax({
1585
+ url: acf.get('ajaxurl'),
1586
+ data: acf.prepareForAjax(ajaxData),
1587
+ type: 'post',
1588
+ dataType: 'html'
1589
+ });
1590
+
1591
+ };
1592
+
1593
+
1594
+ /**
1595
+ * acf.val
1596
+ *
1597
+ * description
1598
+ *
1599
+ * @date 8/1/18
1600
+ * @since 5.6.5
1601
+ *
1602
+ * @param type $var Description. Default.
1603
+ * @return type Description.
1604
+ */
1605
+
1606
+ acf.val = function( $input, value, silent ){
1607
+
1608
+ // vars
1609
+ var prevValue = $input.val();
1610
+
1611
+ // bail if no change
1612
+ if( value === prevValue ) {
1613
+ return false
1614
+ }
1615
+
1616
+ // update value
1617
+ $input.val( value );
1618
+
1619
+ // prevent select elements displaying blank value if option doesn't exist
1620
+ if( $input.is('select') && $input.val() === null ) {
1621
+ $input.val( prevValue );
1622
+ return false;
1623
+ }
1624
+
1625
+ // update with trigger
1626
+ if( silent !== true ) {
1627
+ $input.trigger('change');
1628
+ }
1629
+
1630
+ // return
1631
+ return true;
1632
+ };
1633
+
1634
+ /**
1635
+ * acf.show
1636
+ *
1637
+ * description
1638
+ *
1639
+ * @date 9/2/18
1640
+ * @since 5.6.5
1641
+ *
1642
+ * @param type $var Description. Default.
1643
+ * @return type Description.
1644
+ */
1645
+
1646
+ acf.show = function( $el, lockKey ){
1647
+
1648
+ // unlock
1649
+ if( lockKey ) {
1650
+ acf.unlock($el, 'hidden', lockKey);
1651
+ }
1652
+
1653
+ // bail early if $el is still locked
1654
+ if( acf.isLocked($el, 'hidden') ) {
1655
+ //console.log( 'still locked', getLocks( $el, 'hidden' ));
1656
+ return false;
1657
+ }
1658
+
1659
+ // $el is hidden, remove class and return true due to change in visibility
1660
+ if( $el.hasClass('acf-hidden') ) {
1661
+ $el.removeClass('acf-hidden');
1662
+ return true;
1663
+
1664
+ // $el is visible, return false due to no change in visibility
1665
+ } else {
1666
+ return false;
1667
+ }
1668
+ };
1669
+
1670
+
1671
+ /**
1672
+ * acf.hide
1673
+ *
1674
+ * description
1675
+ *
1676
+ * @date 9/2/18
1677
+ * @since 5.6.5
1678
+ *
1679
+ * @param type $var Description. Default.
1680
+ * @return type Description.
1681
+ */
1682
+
1683
+ acf.hide = function( $el, lockKey ){
1684
+
1685
+ // lock
1686
+ if( lockKey ) {
1687
+ acf.lock($el, 'hidden', lockKey);
1688
+ }
1689
+
1690
+ // $el is hidden, return false due to no change in visibility
1691
+ if( $el.hasClass('acf-hidden') ) {
1692
+ return false;
1693
+
1694
+ // $el is visible, add class and return true due to change in visibility
1695
+ } else {
1696
+ $el.addClass('acf-hidden');
1697
+ return true;
1698
+ }
1699
+ };
1700
+
1701
+
1702
+ /**
1703
+ * acf.isHidden
1704
+ *
1705
+ * description
1706
+ *
1707
+ * @date 9/2/18
1708
+ * @since 5.6.5
1709
+ *
1710
+ * @param type $var Description. Default.
1711
+ * @return type Description.
1712
+ */
1713
+
1714
+ acf.isHidden = function( $el ){
1715
+ return $el.hasClass('acf-hidden');
1716
+ };
1717
+
1718
+
1719
+ /**
1720
+ * acf.isVisible
1721
+ *
1722
+ * description
1723
+ *
1724
+ * @date 9/2/18
1725
+ * @since 5.6.5
1726
+ *
1727
+ * @param type $var Description. Default.
1728
+ * @return type Description.
1729
+ */
1730
+
1731
+ acf.isVisible = function( $el ){
1732
+ return !acf.isHidden( $el );
1733
+ };
1734
+
1735
+
1736
+ /**
1737
+ * enable
1738
+ *
1739
+ * description
1740
+ *
1741
+ * @date 12/3/18
1742
+ * @since 5.6.9
1743
+ *
1744
+ * @param type $var Description. Default.
1745
+ * @return type Description.
1746
+ */
1747
+
1748
+ var enable = function( $el, lockKey ){
1749
+
1750
+ // check class. Allow .acf-disabled to overrule all JS
1751
+ if( $el.hasClass('acf-disabled') ) {
1752
+ return false;
1753
+ }
1754
+
1755
+ // unlock
1756
+ if( lockKey ) {
1757
+ acf.unlock($el, 'disabled', lockKey);
1758
+ }
1759
+
1760
+ // bail early if $el is still locked
1761
+ if( acf.isLocked($el, 'disabled') ) {
1762
+ return false;
1763
+ }
1764
+
1765
+ // $el is disabled, remove prop and return true due to change
1766
+ if( $el.prop('disabled') ) {
1767
+ $el.prop('disabled', false);
1768
+ return true;
1769
+
1770
+ // $el is enabled, return false due to no change
1771
+ } else {
1772
+ return false;
1773
+ }
1774
+ };
1775
+
1776
+ /**
1777
+ * acf.enable
1778
+ *
1779
+ * description
1780
+ *
1781
+ * @date 9/2/18
1782
+ * @since 5.6.5
1783
+ *
1784
+ * @param type $var Description. Default.
1785
+ * @return type Description.
1786
+ */
1787
+
1788
+ acf.enable = function( $el, lockKey ){
1789
+
1790
+ // enable single input
1791
+ if( $el.attr('name') ) {
1792
+ return enable( $el, lockKey );
1793
+ }
1794
+
1795
+ // find and enable child inputs
1796
+ // return true if any inputs have changed
1797
+ var results = false;
1798
+ $el.find('[name]').each(function(){
1799
+ var result = enable( $(this), lockKey );
1800
+ if( result ) {
1801
+ results = true;
1802
+ }
1803
+ });
1804
+ return results;
1805
+ };
1806
+
1807
+
1808
+ /**
1809
+ * disable
1810
+ *
1811
+ * description
1812
+ *
1813
+ * @date 12/3/18
1814
+ * @since 5.6.9
1815
+ *
1816
+ * @param type $var Description. Default.
1817
+ * @return type Description.
1818
+ */
1819
+
1820
+ var disable = function( $el, lockKey ){
1821
+
1822
+ // lock
1823
+ if( lockKey ) {
1824
+ acf.lock($el, 'disabled', lockKey);
1825
+ }
1826
+
1827
+ // $el is disabled, return false due to no change
1828
+ if( $el.prop('disabled') ) {
1829
+ return false;
1830
+
1831
+ // $el is enabled, add prop and return true due to change
1832
+ } else {
1833
+ $el.prop('disabled', true);
1834
+ return true;
1835
+ }
1836
+ };
1837
+
1838
+
1839
+ /**
1840
+ * acf.disable
1841
+ *
1842
+ * description
1843
+ *
1844
+ * @date 9/2/18
1845
+ * @since 5.6.5
1846
+ *
1847
+ * @param type $var Description. Default.
1848
+ * @return type Description.
1849
+ */
1850
+
1851
+ acf.disable = function( $el, lockKey ){
1852
+
1853
+ // disable single input
1854
+ if( $el.attr('name') ) {
1855
+ return disable( $el, lockKey );
1856
+ }
1857
+
1858
+ // find and enable child inputs
1859
+ // return true if any inputs have changed
1860
+ var results = false;
1861
+ $el.find('[name]').each(function(){
1862
+ var result = disable( $(this), lockKey );
1863
+ if( result ) {
1864
+ results = true;
1865
+ }
1866
+ });
1867
+ return results;
1868
+ };
1869
+
1870
+
1871
+ /**
1872
+ * acf.isset
1873
+ *
1874
+ * description
1875
+ *
1876
+ * @date 10/1/18
1877
+ * @since 5.6.5
1878
+ *
1879
+ * @param type $var Description. Default.
1880
+ * @return type Description.
1881
+ */
1882
+
1883
+ acf.isset = function( obj /*, level1, level2, ... */ ) {
1884
+ for( var i = 1; i < arguments.length; i++ ) {
1885
+ if( !obj || !obj.hasOwnProperty(arguments[i]) ) {
1886
+ return false;
1887
+ }
1888
+ obj = obj[ arguments[i] ];
1889
+ }
1890
+ return true;
1891
+ };
1892
+
1893
+ /**
1894
+ * acf.isget
1895
+ *
1896
+ * description
1897
+ *
1898
+ * @date 10/1/18
1899
+ * @since 5.6.5
1900
+ *
1901
+ * @param type $var Description. Default.
1902
+ * @return type Description.
1903
+ */
1904
+
1905
+ acf.isget = function( obj /*, level1, level2, ... */ ) {
1906
+ for( var i = 1; i < arguments.length; i++ ) {
1907
+ if( !obj || !obj.hasOwnProperty(arguments[i]) ) {
1908
+ return null;
1909
+ }
1910
+ obj = obj[ arguments[i] ];
1911
+ }
1912
+ return obj;
1913
+ };
1914
+
1915
+ /**
1916
+ * acf.getFileInputData
1917
+ *
1918
+ * description
1919
+ *
1920
+ * @date 10/1/18
1921
+ * @since 5.6.5
1922
+ *
1923
+ * @param type $var Description. Default.
1924
+ * @return type Description.
1925
+ */
1926
+
1927
+ acf.getFileInputData = function( $input, callback ){
1928
+
1929
+ // vars
1930
+ var value = $input.val();
1931
+
1932
+ // bail early if no value
1933
+ if( !value ) {
1934
+ return false;
1935
+ }
1936
+
1937
+ // data
1938
+ var data = {
1939
+ url: value
1940
+ };
1941
+
1942
+ // modern browsers
1943
+ var file = $input[0].files.length ? acf.isget($input[0].files, 0) : false;
1944
+ if( file ){
1945
+
1946
+ // update data
1947
+ data.size = file.size;
1948
+ data.type = file.type;
1949
+
1950
+ // image
1951
+ if( file.type.indexOf('image') > -1 ) {
1952
+
1953
+ // vars
1954
+ var windowURL = window.URL || window.webkitURL;
1955
+ var img = new Image();
1956
+
1957
+ img.onload = function() {
1958
+
1959
+ // update
1960
+ data.width = this.width;
1961
+ data.height = this.height;
1962
+
1963
+ callback( data );
1964
+ };
1965
+ img.src = windowURL.createObjectURL( file );
1966
+ } else {
1967
+ callback( data );
1968
+ }
1969
+ } else {
1970
+ callback( data );
1971
+ }
1972
+ };
1973
+
1974
+ /**
1975
+ * acf.isAjaxSuccess
1976
+ *
1977
+ * description
1978
+ *
1979
+ * @date 18/1/18
1980
+ * @since 5.6.5
1981
+ *
1982
+ * @param type $var Description. Default.
1983
+ * @return type Description.
1984
+ */
1985
+
1986
+ acf.isAjaxSuccess = function( json ){
1987
+ return ( json && json.success );
1988
+ };
1989
+
1990
+ /**
1991
+ * acf.getAjaxMessage
1992
+ *
1993
+ * description
1994
+ *
1995
+ * @date 18/1/18
1996
+ * @since 5.6.5
1997
+ *
1998
+ * @param type $var Description. Default.
1999
+ * @return type Description.
2000
+ */
2001
+
2002
+ acf.getAjaxMessage = function( json ){
2003
+ return acf.isget( json, 'data', 'message' );
2004
+ };
2005
+
2006
+ /**
2007
+ * acf.getAjaxError
2008
+ *
2009
+ * description
2010
+ *
2011
+ * @date 18/1/18
2012
+ * @since 5.6.5
2013
+ *
2014
+ * @param type $var Description. Default.
2015
+ * @return type Description.
2016
+ */
2017
+
2018
+ acf.getAjaxError = function( json ){
2019
+ return acf.isget( json, 'data', 'error' );
2020
+ };
2021
+
2022
+ /**
2023
+ * Returns the error message from an XHR object.
2024
+ *
2025
+ * @date 17/3/20
2026
+ * @since 5.8.9
2027
+ *
2028
+ * @param object xhr The XHR object.
2029
+ * @return (string)
2030
+ */
2031
+ acf.getXhrError = function( xhr ){
2032
+ if( xhr.responseJSON && xhr.responseJSON.message ) {
2033
+ return xhr.responseJSON.message;
2034
+ } else if( xhr.statusText ) {
2035
+ return xhr.statusText;
2036
+ }
2037
+ return "";
2038
+ };
2039
+
2040
+ /**
2041
+ * acf.renderSelect
2042
+ *
2043
+ * Renders the innter html for a select field.
2044
+ *
2045
+ * @date 19/2/18
2046
+ * @since 5.6.9
2047
+ *
2048
+ * @param jQuery $select The select element.
2049
+ * @param array choices An array of choices.
2050
+ * @return void
2051
+ */
2052
+
2053
+ acf.renderSelect = function( $select, choices ){
2054
+
2055
+ // vars
2056
+ var value = $select.val();
2057
+ var values = [];
2058
+
2059
+ // callback
2060
+ var crawl = function( items ){
2061
+
2062
+ // vars
2063
+ var itemsHtml = '';
2064
+
2065
+ // loop
2066
+ items.map(function( item ){
2067
+
2068
+ // vars
2069
+ var text = item.text || item.label || '';
2070
+ var id = item.id || item.value || '';
2071
+
2072
+ // append
2073
+ values.push(id);
2074
+
2075
+ // optgroup
2076
+ if( item.children ) {
2077
+ itemsHtml += '<optgroup label="' + acf.escAttr(text) + '">' + crawl( item.children ) + '</optgroup>';
2078
+
2079
+ // option
2080
+ } else {
2081
+ itemsHtml += '<option value="' + acf.escAttr(id) + '"' + (item.disabled ? ' disabled="disabled"' : '') + '>' + acf.strEscape(text) + '</option>';
2082
+ }
2083
+ });
2084
+
2085
+ // return
2086
+ return itemsHtml;
2087
+ };
2088
+
2089
+ // update HTML
2090
+ $select.html( crawl(choices) );
2091
+
2092
+ // update value
2093
+ if( values.indexOf(value) > -1 ){
2094
+ $select.val( value );
2095
+ }
2096
+
2097
+ // return selected value
2098
+ return $select.val();
2099
+ };
2100
+
2101
+ /**
2102
+ * acf.lock
2103
+ *
2104
+ * Creates a "lock" on an element for a given type and key
2105
+ *
2106
+ * @date 22/2/18
2107
+ * @since 5.6.9
2108
+ *
2109
+ * @param jQuery $el The element to lock.
2110
+ * @param string type The type of lock such as "condition" or "visibility".
2111
+ * @param string key The key that will be used to unlock.
2112
+ * @return void
2113
+ */
2114
+
2115
+ var getLocks = function( $el, type ){
2116
+ return $el.data('acf-lock-'+type) || [];
2117
+ };
2118
+
2119
+ var setLocks = function( $el, type, locks ){
2120
+ $el.data('acf-lock-'+type, locks);
2121
+ }
2122
+
2123
+ acf.lock = function( $el, type, key ){
2124
+ var locks = getLocks( $el, type );
2125
+ var i = locks.indexOf(key);
2126
+ if( i < 0 ) {
2127
+ locks.push( key );
2128
+ setLocks( $el, type, locks );
2129
+ }
2130
+ };
2131
+
2132
+ /**
2133
+ * acf.unlock
2134
+ *
2135
+ * Unlocks a "lock" on an element for a given type and key
2136
+ *
2137
+ * @date 22/2/18
2138
+ * @since 5.6.9
2139
+ *
2140
+ * @param jQuery $el The element to lock.
2141
+ * @param string type The type of lock such as "condition" or "visibility".
2142
+ * @param string key The key that will be used to unlock.
2143
+ * @return void
2144
+ */
2145
+
2146
+ acf.unlock = function( $el, type, key ){
2147
+ var locks = getLocks( $el, type );
2148
+ var i = locks.indexOf(key);
2149
+ if( i > -1 ) {
2150
+ locks.splice(i, 1);
2151
+ setLocks( $el, type, locks );
2152
+ }
2153
+
2154
+ // return true if is unlocked (no locks)
2155
+ return (locks.length === 0);
2156
+ };
2157
+
2158
+ /**
2159
+ * acf.isLocked
2160
+ *
2161
+ * Returns true if a lock exists for a given type
2162
+ *
2163
+ * @date 22/2/18
2164
+ * @since 5.6.9
2165
+ *
2166
+ * @param jQuery $el The element to lock.
2167
+ * @param string type The type of lock such as "condition" or "visibility".
2168
+ * @return void
2169
+ */
2170
+
2171
+ acf.isLocked = function( $el, type ){
2172
+ return ( getLocks( $el, type ).length > 0 );
2173
+ };
2174
+
2175
+ /**
2176
+ * acf.isGutenberg
2177
+ *
2178
+ * Returns true if the Gutenberg editor is being used.
2179
+ *
2180
+ * @date 14/11/18
2181
+ * @since 5.8.0
2182
+ *
2183
+ * @param vois
2184
+ * @return bool
2185
+ */
2186
+ acf.isGutenberg = function(){
2187
+ return !!( window.wp && wp.data && wp.data.select && wp.data.select( 'core/editor' ) );
2188
+ };
2189
+
2190
+ /**
2191
+ * acf.objectToArray
2192
+ *
2193
+ * Returns an array of items from the given object.
2194
+ *
2195
+ * @date 20/11/18
2196
+ * @since 5.8.0
2197
+ *
2198
+ * @param object obj The object of items.
2199
+ * @return array
2200
+ */
2201
+ acf.objectToArray = function( obj ){
2202
+ return Object.keys( obj ).map(function( key ){
2203
+ return obj[key];
2204
+ });
2205
+ };
2206
+
2207
+ /**
2208
+ * acf.debounce
2209
+ *
2210
+ * Returns a debounced version of the passed function which will postpone its execution until after `wait` milliseconds have elapsed since the last time it was invoked.
2211
+ *
2212
+ * @date 28/8/19
2213
+ * @since 5.8.1
2214
+ *
2215
+ * @param function callback The callback function.
2216
+ * @return int wait The number of milliseconds to wait.
2217
+ */
2218
+ acf.debounce = function( callback, wait ){
2219
+ var timeout;
2220
+ return function(){
2221
+ var context = this;
2222
+ var args = arguments;
2223
+ var later = function(){
2224
+ callback.apply( context, args );
2225
+ };
2226
+ clearTimeout( timeout );
2227
+ timeout = setTimeout( later, wait );
2228
+ };
2229
+ };
2230
+
2231
+ /**
2232
+ * acf.throttle
2233
+ *
2234
+ * Returns a throttled version of the passed function which will allow only one execution per `limit` time period.
2235
+ *
2236
+ * @date 28/8/19
2237
+ * @since 5.8.1
2238
+ *
2239
+ * @param function callback The callback function.
2240
+ * @return int wait The number of milliseconds to wait.
2241
+ */
2242
+ acf.throttle = function( callback, limit ){
2243
+ var busy = false;
2244
+ return function(){
2245
+ if( busy ) return;
2246
+ busy = true;
2247
+ setTimeout(function(){
2248
+ busy = false;
2249
+ }, limit);
2250
+ callback.apply( this, arguments );
2251
+ };
2252
+ };
2253
+
2254
+ /**
2255
+ * acf.isInView
2256
+ *
2257
+ * Returns true if the given element is in view.
2258
+ *
2259
+ * @date 29/8/19
2260
+ * @since 5.8.1
2261
+ *
2262
+ * @param elem el The dom element to inspect.
2263
+ * @return bool
2264
+ */
2265
+ acf.isInView = function( el ){
2266
+ if( el instanceof jQuery ) {
2267
+ el = el[0];
2268
+ }
2269
+ var rect = el.getBoundingClientRect();
2270
+ return (
2271
+ rect.top !== rect.bottom &&
2272
+ rect.top >= 0 &&
2273
+ rect.left >= 0 &&
2274
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
2275
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
2276
+ );
2277
+ };
2278
+
2279
+ /**
2280
+ * acf.onceInView
2281
+ *
2282
+ * Watches for a dom element to become visible in the browser and then excecutes the passed callback.
2283
+ *
2284
+ * @date 28/8/19
2285
+ * @since 5.8.1
2286
+ *
2287
+ * @param dom el The dom element to inspect.
2288
+ * @param function callback The callback function.
2289
+ */
2290
+ acf.onceInView = (function() {
2291
+
2292
+ // Define list.
2293
+ var items = [];
2294
+ var id = 0;
2295
+
2296
+ // Define check function.
2297
+ var check = function() {
2298
+ items.forEach(function( item ){
2299
+ if( acf.isInView(item.el) ) {
2300
+ item.callback.apply( this );
2301
+ pop( item.id );
2302
+ }
2303
+ });
2304
+ };
2305
+
2306
+ // And create a debounced version.
2307
+ var debounced = acf.debounce( check, 300 );
2308
+
2309
+ // Define add function.
2310
+ var push = function( el, callback ) {
2311
+
2312
+ // Add event listener.
2313
+ if( !items.length ) {
2314
+ $(window).on( 'scroll resize', debounced ).on( 'acfrefresh orientationchange', check );
2315
+ }
2316
+
2317
+ // Append to list.
2318
+ items.push({ id: id++, el: el, callback: callback });
2319
+ }
2320
+
2321
+ // Define remove function.
2322
+ var pop = function( id ) {
2323
+
2324
+ // Remove from list.
2325
+ items = items.filter(function(item) {
2326
+ return (item.id !== id);
2327
+ });
2328
+
2329
+ // Clean up listener.
2330
+ if( !items.length ) {
2331
+ $(window).off( 'scroll resize', debounced ).off( 'acfrefresh orientationchange', check );
2332
+ }
2333
+ }
2334
+
2335
+ // Define returned function.
2336
+ return function( el, callback ){
2337
+
2338
+ // Allow jQuery object.
2339
+ if( el instanceof jQuery )
2340
+ el = el[0];
2341
+
2342
+ // Execute callback if already in view or add to watch list.
2343
+ if( acf.isInView(el) ) {
2344
+ callback.apply( this );
2345
+ } else {
2346
+ push( el, callback );
2347
+ }
2348
+ }
2349
+ })();
2350
+
2351
+ /**
2352
+ * acf.once
2353
+ *
2354
+ * Creates a function that is restricted to invoking `func` once.
2355
+ *
2356
+ * @date 2/9/19
2357
+ * @since 5.8.1
2358
+ *
2359
+ * @param function func The function to restrict.
2360
+ * @return function
2361
+ */
2362
+ acf.once = function( func ){
2363
+ var i = 0;
2364
+ return function(){
2365
+ if( i++ > 0 ) {
2366
+ return (func = undefined);
2367
+ }
2368
+ return func.apply(this, arguments);
2369
+ }
2370
+ }
2371
+
2372
+ /**
2373
+ * Focuses attention to a specific element.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2374
  *
2375
+ * @date 05/05/2020
2376
+ * @since 5.9.0
 
 
 
 
 
 
 
 
 
 
 
 
2377
  *
2378
+ * @param jQuery $el The jQuery element to focus.
2379
+ * @return void
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2380
  */
2381
+ acf.focusAttention = function( $el ){
2382
+ var wait = 1000;
2383
+
2384
+ // Apply class to focus attention.
2385
+ $el.addClass( 'acf-attention -focused' );
2386
+
2387
+ // Scroll to element if needed.
2388
+ var scrollTime = 500;
2389
+ if( !acf.isInView( $el ) ) {
2390
+ $( 'body, html' ).animate({
2391
+ scrollTop: $el.offset().top - ( $(window).height() / 2 )
2392
+ }, scrollTime);
2393
+ wait += scrollTime;
2394
+ }
2395
+
2396
+ // Remove class after $wait amount of time.
2397
+ var fadeTime = 250;
2398
+ setTimeout(function(){
2399
+ $el.removeClass( '-focused' );
2400
+ setTimeout(function(){
2401
+ $el.removeClass( 'acf-attention' );
2402
+ }, fadeTime);
2403
+ }, wait);
2404
+ };
2405
+
2406
+ /**
2407
+ * Description
2408
  *
2409
+ * @date 05/05/2020
2410
+ * @since 5.9.0
 
 
 
 
 
 
 
 
 
 
 
 
2411
  *
2412
+ * @param type Var Description.
2413
+ * @return type Description.
 
2414
  */
2415
+ acf.onFocus = function( $el, callback ){
2416
+
2417
+ // Only run once per element.
2418
+ // if( $el.data('acf.onFocus') ) {
2419
+ // return false;
2420
+ // }
2421
+
2422
+ // Vars.
2423
+ var ignoreBlur = false;
2424
+ var focus = false;
2425
+
2426
+ // Functions.
2427
+ var onFocus = function(){
2428
+ ignoreBlur = true;
2429
+ setTimeout(function(){
2430
+ ignoreBlur = false;
2431
+ }, 1);
2432
+ setFocus( true );
2433
+ };
2434
+ var onBlur = function(){
2435
+ if( !ignoreBlur ) {
2436
+ setFocus( false );
2437
  }
2438
+ };
2439
+ var addEvents = function(){
2440
+ $(document).on('click', onBlur);
2441
+ //$el.on('acfBlur', onBlur);
2442
+ $el.on('blur', 'input, select, textarea', onBlur);
2443
+ };
2444
+ var removeEvents = function(){
2445
+ $(document).off('click', onBlur);
2446
+ //$el.off('acfBlur', onBlur);
2447
+ $el.off('blur', 'input, select, textarea', onBlur);
2448
+ };
2449
+ var setFocus = function( value ){
2450
+ if( focus === value ) {
2451
+ return;
2452
  }
2453
+ if( value ) {
2454
+ addEvents();
2455
+ } else {
2456
+ removeEvents();
2457
+ }
2458
+ focus = value;
2459
+ callback( value );
2460
+ };
2461
+
2462
+ // Add events and set data.
2463
+ $el.on('click', onFocus);
2464
+ //$el.on('acfFocus', onFocus);
2465
+ $el.on('focus', 'input, select, textarea', onFocus);
2466
+ //$el.data('acf.onFocus', true);
2467
+ };
2468
+
2469
+ /*
2470
+ * exists
2471
+ *
2472
+ * This function will return true if a jQuery selection exists
2473
+ *
2474
+ * @type function
2475
+ * @date 8/09/2014
2476
+ * @since 5.0.0
2477
+ *
2478
+ * @param n/a
2479
+ * @return (boolean)
2480
+ */
2481
+
2482
+ $.fn.exists = function() {
2483
+ return $(this).length>0;
2484
+ };
2485
+
2486
+
2487
+ /*
2488
+ * outerHTML
2489
+ *
2490
+ * This function will return a string containing the HTML of the selected element
2491
+ *
2492
+ * @type function
2493
+ * @date 19/11/2013
2494
+ * @since 5.0.0
2495
+ *
2496
+ * @param $.fn
2497
+ * @return (string)
2498
+ */
2499
+
2500
+ $.fn.outerHTML = function() {
2501
+ return $(this).get(0).outerHTML;
2502
+ };
2503
+
2504
+ /*
2505
+ * indexOf
2506
+ *
2507
+ * This function will provide compatibility for ie8
2508
+ *
2509
+ * @type function
2510
+ * @date 5/3/17
2511
+ * @since 5.5.10
2512
+ *
2513
+ * @param n/a
2514
+ * @return n/a
2515
+ */
2516
+
2517
+ if( !Array.prototype.indexOf ) {
2518
+
2519
+ Array.prototype.indexOf = function(val) {
2520
+ return $.inArray(val, this);
2521
+ };
2522
+
2523
+ }
2524
+
2525
+ /**
2526
+ * Returns true if value is a number or a numeric string.
2527
+ *
2528
+ * @date 30/11/20
2529
+ * @since 5.9.4
2530
+ * @link https://stackoverflow.com/questions/9716468/pure-javascript-a-function-like-jquerys-isnumeric/9716488#9716488
2531
+ *
2532
+ * @param mixed n The variable being evaluated.
2533
+ * @return bool.
2534
+ */
2535
+ acf.isNumeric = function( n ){
2536
+ return !isNaN(parseFloat(n)) && isFinite(n);
2537
+ }
2538
+
2539
+ /**
2540
+ * Triggers a "refresh" action used by various Components to redraw the DOM.
2541
+ *
2542
+ * @date 26/05/2020
2543
+ * @since 5.9.0
2544
+ *
2545
+ * @param void
2546
+ * @return void
2547
+ */
2548
+ acf.refresh = acf.debounce(function(){
2549
+ $( window ).trigger('acfrefresh');
2550
+ acf.doAction('refresh');
2551
+ }, 0);
2552
+
2553
+ // Set up actions from events
2554
+ $(document).ready(function(){
2555
+ acf.doAction('ready');
2556
+ });
2557
+
2558
+ $(window).on('load', function(){
2559
+
2560
+ // Use timeout to ensure action runs after Gutenberg has modified DOM elements during "DOMContentLoaded".
2561
+ setTimeout(function(){
2562
+ acf.doAction('load');
2563
+ });
2564
+ });
2565
+
2566
+ $(window).on('beforeunload', function(){
2567
+ acf.doAction('unload');
2568
+ });
2569
+
2570
+ $(window).on('resize', function(){
2571
+ acf.doAction('resize');
2572
+ });
2573
+
2574
+ $(document).on('sortstart', function( event, ui ) {
2575
+ acf.doAction('sortstart', ui.item, ui.placeholder);
2576
+ });
2577
+
2578
+ $(document).on('sortstop', function( event, ui ) {
2579
+ acf.doAction('sortstop', ui.item, ui.placeholder);
2580
+ });
2581
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2582
  })(jQuery);
2583
+ ( function( window, undefined ) {
2584
+ "use strict";
2585
+
2586
+ /**
2587
+ * Handles managing all events for whatever you plug it into. Priorities for hooks are based on lowest to highest in
2588
+ * that, lowest priority hooks are fired first.
2589
+ */
2590
+ var EventManager = function() {
2591
+ /**
2592
+ * Maintain a reference to the object scope so our public methods never get confusing.
2593
+ */
2594
+ var MethodsAvailable = {
2595
+ removeFilter : removeFilter,
2596
+ applyFilters : applyFilters,
2597
+ addFilter : addFilter,
2598
+ removeAction : removeAction,
2599
+ doAction : doAction,
2600
+ addAction : addAction,
2601
+ storage : getStorage
2602
+ };
2603
+
2604
+ /**
2605
+ * Contains the hooks that get registered with this EventManager. The array for storage utilizes a "flat"
2606
+ * object literal such that looking up the hook utilizes the native object literal hash.
2607
+ */
2608
+ var STORAGE = {
2609
+ actions : {},
2610
+ filters : {}
2611
+ };
2612
+
2613
+ function getStorage() {
2614
+
2615
+ return STORAGE;
2616
+
2617
+ };
2618
+
2619
+ /**
2620
+ * Adds an action to the event manager.
2621
+ *
2622
+ * @param action Must contain namespace.identifier
2623
+ * @param callback Must be a valid callback function before this action is added
2624
+ * @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
2625
+ * @param [context] Supply a value to be used for this
2626
+ */
2627
+ function addAction( action, callback, priority, context ) {
2628
+ if( typeof action === 'string' && typeof callback === 'function' ) {
2629
+ priority = parseInt( ( priority || 10 ), 10 );
2630
+ _addHook( 'actions', action, callback, priority, context );
2631
+ }
2632
+
2633
+ return MethodsAvailable;
2634
+ }
2635
+
2636
+ /**
2637
+ * Performs an action if it exists. You can pass as many arguments as you want to this function; the only rule is
2638
+ * that the first argument must always be the action.
2639
+ */
2640
+ function doAction( /* action, arg1, arg2, ... */ ) {
2641
+ var args = Array.prototype.slice.call( arguments );
2642
+ var action = args.shift();
2643
+
2644
+ if( typeof action === 'string' ) {
2645
+ _runHook( 'actions', action, args );
2646
+ }
2647
+
2648
+ return MethodsAvailable;
2649
+ }
2650
+
2651
+ /**
2652
+ * Removes the specified action if it contains a namespace.identifier & exists.
2653
+ *
2654
+ * @param action The action to remove
2655
+ * @param [callback] Callback function to remove
2656
+ */
2657
+ function removeAction( action, callback ) {
2658
+ if( typeof action === 'string' ) {
2659
+ _removeHook( 'actions', action, callback );
2660
+ }
2661
+
2662
+ return MethodsAvailable;
2663
+ }
2664
+
2665
+ /**
2666
+ * Adds a filter to the event manager.
2667
+ *
2668
+ * @param filter Must contain namespace.identifier
2669
+ * @param callback Must be a valid callback function before this action is added
2670
+ * @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
2671
+ * @param [context] Supply a value to be used for this
2672
+ */
2673
+ function addFilter( filter, callback, priority, context ) {
2674
+ if( typeof filter === 'string' && typeof callback === 'function' ) {
2675
+ priority = parseInt( ( priority || 10 ), 10 );
2676
+ _addHook( 'filters', filter, callback, priority, context );
2677
+ }
2678
+
2679
+ return MethodsAvailable;
2680
+ }
2681
+
2682
+ /**
2683
+ * Performs a filter if it exists. You should only ever pass 1 argument to be filtered. The only rule is that
2684
+ * the first argument must always be the filter.
2685
+ */
2686
+ function applyFilters( /* filter, filtered arg, arg2, ... */ ) {
2687
+ var args = Array.prototype.slice.call( arguments );
2688
+ var filter = args.shift();
2689
+
2690
+ if( typeof filter === 'string' ) {
2691
+ return _runHook( 'filters', filter, args );
2692
+ }
2693
+
2694
+ return MethodsAvailable;
2695
+ }
2696
+
2697
+ /**
2698
+ * Removes the specified filter if it contains a namespace.identifier & exists.
2699
+ *
2700
+ * @param filter The action to remove
2701
+ * @param [callback] Callback function to remove
2702
+ */
2703
+ function removeFilter( filter, callback ) {
2704
+ if( typeof filter === 'string') {
2705
+ _removeHook( 'filters', filter, callback );
2706
+ }
2707
+
2708
+ return MethodsAvailable;
2709
+ }
2710
+
2711
+ /**
2712
+ * Removes the specified hook by resetting the value of it.
2713
+ *
2714
+ * @param type Type of hook, either 'actions' or 'filters'
2715
+ * @param hook The hook (namespace.identifier) to remove
2716
+ * @private
2717
+ */
2718
+ function _removeHook( type, hook, callback, context ) {
2719
+ if ( !STORAGE[ type ][ hook ] ) {
2720
+ return;
2721
+ }
2722
+ if ( !callback ) {
2723
+ STORAGE[ type ][ hook ] = [];
2724
+ } else {
2725
+ var handlers = STORAGE[ type ][ hook ];
2726
+ var i;
2727
+ if ( !context ) {
2728
+ for ( i = handlers.length; i--; ) {
2729
+ if ( handlers[i].callback === callback ) {
2730
+ handlers.splice( i, 1 );
2731
+ }
2732
+ }
2733
+ }
2734
+ else {
2735
+ for ( i = handlers.length; i--; ) {
2736
+ var handler = handlers[i];
2737
+ if ( handler.callback === callback && handler.context === context) {
2738
+ handlers.splice( i, 1 );
2739
+ }
2740
+ }
2741
+ }
2742
+ }
2743
+ }
2744
+
2745
+ /**
2746
+ * Adds the hook to the appropriate storage container
2747
+ *
2748
+ * @param type 'actions' or 'filters'
2749
+ * @param hook The hook (namespace.identifier) to add to our event manager
2750
+ * @param callback The function that will be called when the hook is executed.
2751
+ * @param priority The priority of this hook. Must be an integer.
2752
+ * @param [context] A value to be used for this
2753
+ * @private
2754
+ */
2755
+ function _addHook( type, hook, callback, priority, context ) {
2756
+ var hookObject = {
2757
+ callback : callback,
2758
+ priority : priority,
2759
+ context : context
2760
+ };
2761
+
2762
+ // Utilize 'prop itself' : http://jsperf.com/hasownproperty-vs-in-vs-undefined/19
2763
+ var hooks = STORAGE[ type ][ hook ];
2764
+ if( hooks ) {
2765
+ hooks.push( hookObject );
2766
+ hooks = _hookInsertSort( hooks );
2767
+ }
2768
+ else {
2769
+ hooks = [ hookObject ];
2770
+ }
2771
+
2772
+ STORAGE[ type ][ hook ] = hooks;
2773
+ }
2774
+
2775
+ /**
2776
+ * Use an insert sort for keeping our hooks organized based on priority. This function is ridiculously faster
2777
+ * than bubble sort, etc: http://jsperf.com/javascript-sort
2778
+ *
2779
+ * @param hooks The custom array containing all of the appropriate hooks to perform an insert sort on.
2780
+ * @private
2781
+ */
2782
+ function _hookInsertSort( hooks ) {
2783
+ var tmpHook, j, prevHook;
2784
+ for( var i = 1, len = hooks.length; i < len; i++ ) {
2785
+ tmpHook = hooks[ i ];
2786
+ j = i;
2787
+ while( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) {
2788
+ hooks[ j ] = hooks[ j - 1 ];
2789
+ --j;
2790
+ }
2791
+ hooks[ j ] = tmpHook;
2792
+ }
2793
+
2794
+ return hooks;
2795
+ }
2796
+
2797
+ /**
2798
+ * Runs the specified hook. If it is an action, the value is not modified but if it is a filter, it is.
2799
+ *
2800
+ * @param type 'actions' or 'filters'
2801
+ * @param hook The hook ( namespace.identifier ) to be ran.
2802
+ * @param args Arguments to pass to the action/filter. If it's a filter, args is actually a single parameter.
2803
+ * @private
2804
+ */
2805
+ function _runHook( type, hook, args ) {
2806
+ var handlers = STORAGE[ type ][ hook ];
2807
+
2808
+ if ( !handlers ) {
2809
+ return (type === 'filters') ? args[0] : false;
2810
+ }
2811
+
2812
+ var i = 0, len = handlers.length;
2813
+ if ( type === 'filters' ) {
2814
+ for ( ; i < len; i++ ) {
2815
+ args[ 0 ] = handlers[ i ].callback.apply( handlers[ i ].context, args );
2816
+ }
2817
+ } else {
2818
+ for ( ; i < len; i++ ) {
2819
+ handlers[ i ].callback.apply( handlers[ i ].context, args );
2820
+ }
2821
+ }
2822
+
2823
+ return ( type === 'filters' ) ? args[ 0 ] : true;
2824
+ }
2825
+
2826
+ // return all of the publicly available methods
2827
+ return MethodsAvailable;
2828
+
2829
+ };
2830
+
2831
+ // instantiate
2832
+ acf.hooks = new EventManager();
2833
+
2834
+ } )( window );
2835
+ (function($, undefined){
2836
+
2837
+ // Cached regex to split keys for `addEvent`.
2838
+ var delegateEventSplitter = /^(\S+)\s*(.*)$/;
2839
+
2840
+ /**
2841
+ * extend
2842
+ *
2843
+ * Helper function to correctly set up the prototype chain for subclasses
2844
+ * Heavily inspired by backbone.js
2845
+ *
2846
+ * @date 14/12/17
2847
+ * @since 5.6.5
2848
+ *
2849
+ * @param object protoProps New properties for this object.
2850
+ * @return function.
2851
+ */
2852
+
2853
+ var extend = function( protoProps ) {
2854
+
2855
+ // vars
2856
+ var Parent = this;
2857
+ var Child;
2858
+
2859
+ // The constructor function for the new subclass is either defined by you
2860
+ // (the "constructor" property in your `extend` definition), or defaulted
2861
+ // by us to simply call the parent constructor.
2862
+ if( protoProps && protoProps.hasOwnProperty('constructor') ) {
2863
+ Child = protoProps.constructor;
2864
+ } else {
2865
+ Child = function(){ return Parent.apply(this, arguments); };
2866
+ }
2867
+
2868
+ // Add static properties to the constructor function, if supplied.
2869
+ $.extend(Child, Parent);
2870
+
2871
+ // Set the prototype chain to inherit from `parent`, without calling
2872
+ // `parent`'s constructor function and add the prototype properties.
2873
+ Child.prototype = Object.create(Parent.prototype);
2874
+ $.extend(Child.prototype, protoProps);
2875
+ Child.prototype.constructor = Child;
2876
+
2877
+ // Set a convenience property in case the parent's prototype is needed later.
2878
+ //Child.prototype.__parent__ = Parent.prototype;
2879
+
2880
+ // return
2881
+ return Child;
2882
+
2883
+ };
2884
+
2885
+
2886
+ /**
2887
+ * Model
2888
+ *
2889
+ * Base class for all inheritence
2890
+ *
2891
+ * @date 14/12/17
2892
+ * @since 5.6.5
2893
+ *
2894
+ * @param object props
2895
+ * @return function.
2896
+ */
2897
+
2898
+ var Model = acf.Model = function(){
2899
+
2900
+ // generate uique client id
2901
+ this.cid = acf.uniqueId('acf');
2902
+
2903
+ // set vars to avoid modifying prototype
2904
+ this.data = $.extend(true, {}, this.data);
2905
+
2906
+ // pass props to setup function
2907
+ this.setup.apply(this, arguments);
2908
+
2909
+ // store on element (allow this.setup to create this.$el)
2910
+ if( this.$el && !this.$el.data('acf') ) {
2911
+ this.$el.data('acf', this);
2912
+ }
2913
+
2914
+ // initialize
2915
+ var initialize = function(){
2916
+ this.initialize();
2917
+ this.addEvents();
2918
+ this.addActions();
2919
+ this.addFilters();
2920
+ };
2921
+
2922
+ // initialize on action
2923
+ if( this.wait && !acf.didAction(this.wait) ) {
2924
+ this.addAction(this.wait, initialize);
2925
+
2926
+ // initialize now
2927
+ } else {
2928
+ initialize.apply(this);
2929
+ }
2930
+ };
2931
+
2932
+ // Attach all inheritable methods to the Model prototype.
2933
+ $.extend(Model.prototype, {
2934
+
2935
+ // Unique model id
2936
+ id: '',
2937
+
2938
+ // Unique client id
2939
+ cid: '',
2940
+
2941
+ // jQuery element
2942
+ $el: null,
2943
+
2944
+ // Data specific to this instance
2945
+ data: {},
2946
+
2947
+ // toggle used when changing data
2948
+ busy: false,
2949
+ changed: false,
2950
+
2951
+ // Setup events hooks
2952
+ events: {},
2953
+ actions: {},
2954
+ filters: {},
2955
+
2956
+ // class used to avoid nested event triggers
2957
+ eventScope: '',
2958
+
2959
+ // action to wait until initialize
2960
+ wait: false,
2961
+
2962
+ // action priority default
2963
+ priority: 10,
2964
+
2965
+ /**
2966
+ * get
2967
+ *
2968
+ * Gets a specific data value
2969
+ *
2970
+ * @date 14/12/17
2971
+ * @since 5.6.5
2972
+ *
2973
+ * @param string name
2974
+ * @return mixed
2975
+ */
2976
+
2977
+ get: function( name ) {
2978
+ return this.data[name];
2979
+ },
2980
+
2981
+ /**
2982
+ * has
2983
+ *
2984
+ * Returns `true` if the data exists and is not null
2985
+ *
2986
+ * @date 14/12/17
2987
+ * @since 5.6.5
2988
+ *
2989
+ * @param string name
2990
+ * @return boolean
2991
+ */
2992
+
2993
+ has: function( name ) {
2994
+ return this.get(name) != null;
2995
+ },
2996
+
2997
+ /**
2998
+ * set
2999
+ *
3000
+ * Sets a specific data value
3001
+ *
3002
+ * @date 14/12/17
3003
+ * @since 5.6.5
3004
+ *
3005
+ * @param string name
3006
+ * @param mixed value
3007
+ * @return this
3008
+ */
3009
+
3010
+ set: function( name, value, silent ) {
3011
+
3012
+ // bail if unchanged
3013
+ var prevValue = this.get(name);
3014
+ if( prevValue == value ) {
3015
+ return this;
3016
+ }
3017
+
3018
+ // set data
3019
+ this.data[ name ] = value;
3020
+
3021
+ // trigger events
3022
+ if( !silent ) {
3023
+ this.changed = true;
3024
+ this.trigger('changed:' + name, [value, prevValue]);
3025
+ this.trigger('changed', [name, value, prevValue]);
3026
+ }
3027
+
3028
+ // return
3029
+ return this;
3030
+ },
3031
+
3032
+ /**
3033
+ * inherit
3034
+ *
3035
+ * Inherits the data from a jQuery element
3036
+ *
3037
+ * @date 14/12/17
3038
+ * @since 5.6.5
3039
+ *
3040
+ * @param jQuery $el
3041
+ * @return this
3042
+ */
3043
+
3044
+ inherit: function( data ){
3045
+
3046
+ // allow jQuery
3047
+ if( data instanceof jQuery ) {
3048
+ data = data.data();
3049
+ }
3050
+
3051
+ // extend
3052
+ $.extend(this.data, data);
3053
+
3054
+ // return
3055
+ return this;
3056
+ },
3057
+
3058
+ /**
3059
+ * prop
3060
+ *
3061
+ * mimics the jQuery prop function
3062
+ *
3063
+ * @date 4/6/18
3064
+ * @since 5.6.9
3065
+ *
3066
+ * @param type $var Description. Default.
3067
+ * @return type Description.
3068
+ */
3069
+
3070
+ prop: function(){
3071
+ return this.$el.prop.apply(this.$el, arguments);
3072
+ },
3073
+
3074
+ /**
3075
+ * setup
3076
+ *
3077
+ * Run during constructor function
3078
+ *
3079
+ * @date 14/12/17
3080
+ * @since 5.6.5
3081
+ *
3082
+ * @param n/a
3083
+ * @return n/a
3084
+ */
3085
+
3086
+ setup: function( props ){
3087
+ $.extend(this, props);
3088
+ },
3089
+
3090
+ /**
3091
+ * initialize
3092
+ *
3093
+ * Also run during constructor function
3094
+ *
3095
+ * @date 14/12/17
3096
+ * @since 5.6.5
3097
+ *
3098
+ * @param n/a
3099
+ * @return n/a
3100
+ */
3101
+
3102
+ initialize: function(){},
3103
+
3104
+ /**
3105
+ * addElements
3106
+ *
3107
+ * Adds multiple jQuery elements to this object
3108
+ *
3109
+ * @date 9/5/18
3110
+ * @since 5.6.9
3111
+ *
3112
+ * @param type $var Description. Default.
3113
+ * @return type Description.
3114
+ */
3115
+
3116
+ addElements: function( elements ){
3117
+ elements = elements || this.elements || null;
3118
+ if( !elements || !Object.keys(elements).length ) return false;
3119
+ for( var i in elements ) {
3120
+ this.addElement( i, elements[i] );
3121
+ }
3122
+ },
3123
+
3124
+ /**
3125
+ * addElement
3126
+ *
3127
+ * description
3128
+ *
3129
+ * @date 9/5/18
3130
+ * @since 5.6.9
3131
+ *
3132
+ * @param type $var Description. Default.
3133
+ * @return type Description.
3134
+ */
3135
+
3136
+ addElement: function( name, selector){
3137
+ this[ '$' + name ] = this.$( selector );
3138
+ },
3139
+
3140
+ /**
3141
+ * addEvents
3142
+ *
3143
+ * Adds multiple event handlers
3144
+ *
3145
+ * @date 14/12/17
3146
+ * @since 5.6.5
3147
+ *
3148
+ * @param object events {event1 : callback, event2 : callback, etc }
3149
+ * @return n/a
3150
+ */
3151
+
3152
+ addEvents: function( events ){
3153
+ events = events || this.events || null;
3154
+ if( !events ) return false;
3155
+ for( var key in events ) {
3156
+ var match = key.match(delegateEventSplitter);
3157
+ this.on(match[1], match[2], events[key]);
3158
+ }
3159
+ },
3160
+
3161
+ /**
3162
+ * removeEvents
3163
+ *
3164
+ * Removes multiple event handlers
3165
+ *
3166
+ * @date 14/12/17
3167
+ * @since 5.6.5
3168
+ *
3169
+ * @param object events {event1 : callback, event2 : callback, etc }
3170
+ * @return n/a
3171
+ */
3172
+
3173
+ removeEvents: function( events ){
3174
+ events = events || this.events || null;
3175
+ if( !events ) return false;
3176
+ for( var key in events ) {
3177
+ var match = key.match(delegateEventSplitter);
3178
+ this.off(match[1], match[2], events[key]);
3179
+ }
3180
+ },
3181
+
3182
+ /**
3183
+ * getEventTarget
3184
+ *
3185
+ * Returns a jQUery element to tigger an event on
3186
+ *
3187
+ * @date 5/6/18
3188
+ * @since 5.6.9
3189
+ *
3190
+ * @param jQuery $el The default jQuery element. Optional.
3191
+ * @param string event The event name. Optional.
3192
+ * @return jQuery
3193
+ */
3194
+
3195
+ getEventTarget: function( $el, event ){
3196
+ return $el || this.$el || $(document);
3197
+ },
3198
+
3199
+ /**
3200
+ * validateEvent
3201
+ *
3202
+ * Returns true if the event target's closest $el is the same as this.$el
3203
+ * Requires both this.el and this.$el to be defined
3204
+ *
3205
+ * @date 5/6/18
3206
+ * @since 5.6.9
3207
+ *
3208
+ * @param type $var Description. Default.
3209
+ * @return type Description.
3210
+ */
3211
+
3212
+ validateEvent: function( e ){
3213
+ if( this.eventScope ) {
3214
+ return $( e.target ).closest( this.eventScope ).is( this.$el );
3215
+ } else {
3216
+ return true;
3217
+ }
3218
+ },
3219
+
3220
+ /**
3221
+ * proxyEvent
3222
+ *
3223
+ * Returns a new event callback function scoped to this model
3224
+ *
3225
+ * @date 29/3/18
3226
+ * @since 5.6.9
3227
+ *
3228
+ * @param function callback
3229
+ * @return function
3230
+ */
3231
+
3232
+ proxyEvent: function( callback ){
3233
+ return this.proxy(function(e){
3234
+
3235
+ // validate
3236
+ if( !this.validateEvent(e) ) {
3237
+ return;
3238
+ }
3239
+
3240
+ // construct args
3241
+ var args = acf.arrayArgs( arguments );
3242
+ var extraArgs = args.slice(1);
3243
+ var eventArgs = [ e, $(e.currentTarget) ].concat( extraArgs );
3244
+
3245
+ // callback
3246
+ callback.apply(this, eventArgs);
3247
+ });
3248
+ },
3249
+
3250
+ /**
3251
+ * on
3252
+ *
3253
+ * Adds an event handler similar to jQuery
3254
+ * Uses the instance 'cid' to namespace event
3255
+ *
3256
+ * @date 14/12/17
3257
+ * @since 5.6.5
3258
+ *
3259
+ * @param string name
3260
+ * @param string callback
3261
+ * @return n/a
3262
+ */
3263
+
3264
+ on: function( a1, a2, a3, a4 ){
3265
+
3266
+ // vars
3267
+ var $el, event, selector, callback, args;
3268
+
3269
+ // find args
3270
+ if( a1 instanceof jQuery ) {
3271
+
3272
+ // 1. args( $el, event, selector, callback )
3273
+ if( a4 ) {
3274
+ $el = a1; event = a2; selector = a3; callback = a4;
3275
+
3276
+ // 2. args( $el, event, callback )
3277
+ } else {
3278
+ $el = a1; event = a2; callback = a3;
3279
+ }
3280
+ } else {
3281
+
3282
+ // 3. args( event, selector, callback )
3283
+ if( a3 ) {
3284
+ event = a1; selector = a2; callback = a3;
3285
+
3286
+ // 4. args( event, callback )
3287
+ } else {
3288
+ event = a1; callback = a2;
3289
+ }
3290
+ }
3291
+
3292
+ // element
3293
+ $el = this.getEventTarget( $el );
3294
+
3295
+ // modify callback
3296
+ if( typeof callback === 'string' ) {
3297
+ callback = this.proxyEvent( this[callback] );
3298
+ }
3299
+
3300
+ // modify event
3301
+ event = event + '.' + this.cid;
3302
+
3303
+ // args
3304
+ if( selector ) {
3305
+ args = [ event, selector, callback ];
3306
+ } else {
3307
+ args = [ event, callback ];
3308
+ }
3309
+
3310
+ // on()
3311
+ $el.on.apply($el, args);
3312
+ },
3313
+
3314
+ /**
3315
+ * off
3316
+ *
3317
+ * Removes an event handler similar to jQuery
3318
+ *
3319
+ * @date 14/12/17
3320
+ * @since 5.6.5
3321
+ *
3322
+ * @param string name
3323
+ * @param string callback
3324
+ * @return n/a
3325
+ */
3326
+
3327
+ off: function( a1, a2 ,a3 ){
3328
+
3329
+ // vars
3330
+ var $el, event, selector, args;
3331
+
3332
+ // find args
3333
+ if( a1 instanceof jQuery ) {
3334
+
3335
+ // 1. args( $el, event, selector )
3336
+ if( a3 ) {
3337
+ $el = a1; event = a2; selector = a3;
3338
+
3339
+ // 2. args( $el, event )
3340
+ } else {
3341
+ $el = a1; event = a2;
3342
+ }
3343
+ } else {
3344
+
3345
+ // 3. args( event, selector )
3346
+ if( a2 ) {
3347
+ event = a1; selector = a2;
3348
+
3349
+ // 4. args( event )
3350
+ } else {
3351
+ event = a1;
3352
+ }
3353
+ }
3354
+
3355
+ // element
3356
+ $el = this.getEventTarget( $el );
3357
+
3358
+ // modify event
3359
+ event = event + '.' + this.cid;
3360
+
3361
+ // args
3362
+ if( selector ) {
3363
+ args = [ event, selector ];
3364
+ } else {
3365
+ args = [ event ];
3366
+ }
3367
+
3368
+ // off()
3369
+ $el.off.apply($el, args);
3370
+ },
3371
+
3372
+ /**
3373
+ * trigger
3374
+ *
3375
+ * Triggers an event similar to jQuery
3376
+ *
3377
+ * @date 14/12/17
3378
+ * @since 5.6.5
3379
+ *
3380
+ * @param string name
3381
+ * @param string callback
3382
+ * @return n/a
3383
+ */
3384
+
3385
+ trigger: function( name, args, bubbles ){
3386
+ var $el = this.getEventTarget();
3387
+ if( bubbles ) {
3388
+ $el.trigger.apply( $el, arguments );
3389
+ } else {
3390
+ $el.triggerHandler.apply( $el, arguments );
3391
+ }
3392
+ return this;
3393
+ },
3394
+
3395
+ /**
3396
+ * addActions
3397
+ *
3398
+ * Adds multiple action handlers
3399
+ *
3400
+ * @date 14/12/17
3401
+ * @since 5.6.5
3402
+ *
3403
+ * @param object actions {action1 : callback, action2 : callback, etc }
3404
+ * @return n/a
3405
+ */
3406
+
3407
+ addActions: function( actions ){
3408
+ actions = actions || this.actions || null;
3409
+ if( !actions ) return false;
3410
+ for( var i in actions ) {
3411
+ this.addAction( i, actions[i] );
3412
+ }
3413
+ },
3414
+
3415
+ /**
3416
+ * removeActions
3417
+ *
3418
+ * Removes multiple action handlers
3419
+ *
3420
+ * @date 14/12/17
3421
+ * @since 5.6.5
3422
+ *
3423
+ * @param object actions {action1 : callback, action2 : callback, etc }
3424
+ * @return n/a
3425
+ */
3426
+
3427
+ removeActions: function( actions ){
3428
+ actions = actions || this.actions || null;
3429
+ if( !actions ) return false;
3430
+ for( var i in actions ) {
3431
+ this.removeAction( i, actions[i] );
3432
+ }
3433
+ },
3434
+
3435
+ /**
3436
+ * addAction
3437
+ *
3438
+ * Adds an action using the wp.hooks library
3439
+ *
3440
+ * @date 14/12/17
3441
+ * @since 5.6.5
3442
+ *
3443
+ * @param string name
3444
+ * @param string callback
3445
+ * @return n/a
3446
+ */
3447
+
3448
+ addAction: function( name, callback, priority ){
3449
+ //console.log('addAction', name, priority);
3450
+ // defaults
3451
+ priority = priority || this.priority;
3452
+
3453
+ // modify callback
3454
+ if( typeof callback === 'string' ) {
3455
+ callback = this[ callback ];
3456
+ }
3457
+
3458
+ // add
3459
+ acf.addAction(name, callback, priority, this);
3460
+
3461
+ },
3462
+
3463
+ /**
3464
+ * removeAction
3465
+ *
3466
+ * Remove an action using the wp.hooks library
3467
+ *
3468
+ * @date 14/12/17
3469
+ * @since 5.6.5
3470
+ *
3471
+ * @param string name
3472
+ * @param string callback
3473
+ * @return n/a
3474
+ */
3475
+
3476
+ removeAction: function( name, callback ){
3477
+ acf.removeAction(name, this[ callback ]);
3478
+ },
3479
+
3480
+ /**
3481
+ * addFilters
3482
+ *
3483
+ * Adds multiple filter handlers
3484
+ *
3485
+ * @date 14/12/17
3486
+ * @since 5.6.5
3487
+ *
3488
+ * @param object filters {filter1 : callback, filter2 : callback, etc }
3489
+ * @return n/a
3490
+ */
3491
+
3492
+ addFilters: function( filters ){
3493
+ filters = filters || this.filters || null;
3494
+ if( !filters ) return false;
3495
+ for( var i in filters ) {
3496
+ this.addFilter( i, filters[i] );
3497
+ }
3498
+ },
3499
+
3500
+ /**
3501
+ * addFilter
3502
+ *
3503
+ * Adds a filter using the wp.hooks library
3504
+ *
3505
+ * @date 14/12/17
3506
+ * @since 5.6.5
3507
+ *
3508
+ * @param string name
3509
+ * @param string callback
3510
+ * @return n/a
3511
+ */
3512
+
3513
+ addFilter: function( name, callback, priority ){
3514
+
3515
+ // defaults
3516
+ priority = priority || this.priority;
3517
+
3518
+ // modify callback
3519
+ if( typeof callback === 'string' ) {
3520
+ callback = this[ callback ];
3521
+ }
3522
+
3523
+ // add
3524
+ acf.addFilter(name, callback, priority, this);
3525
+
3526
+ },
3527
+
3528
+ /**
3529
+ * removeFilters
3530
+ *
3531
+ * Removes multiple filter handlers
3532
+ *
3533
+ * @date 14/12/17
3534
+ * @since 5.6.5
3535
+ *
3536
+ * @param object filters {filter1 : callback, filter2 : callback, etc }
3537
+ * @return n/a
3538
+ */
3539
+
3540
+ removeFilters: function( filters ){
3541
+ filters = filters || this.filters || null;
3542
+ if( !filters ) return false;
3543
+ for( var i in filters ) {
3544
+ this.removeFilter( i, filters[i] );
3545
+ }
3546
+ },
3547
+
3548
+ /**
3549
+ * removeFilter
3550
+ *
3551
+ * Remove a filter using the wp.hooks library
3552
+ *
3553
+ * @date 14/12/17
3554
+ * @since 5.6.5
3555
+ *
3556
+ * @param string name
3557
+ * @param string callback
3558
+ * @return n/a
3559
+ */
3560
+
3561
+ removeFilter: function( name, callback ){
3562
+ acf.removeFilter(name, this[ callback ]);
3563
+ },
3564
+
3565
+ /**
3566
+ * $
3567
+ *
3568
+ * description
3569
+ *
3570
+ * @date 16/12/17
3571
+ * @since 5.6.5
3572
+ *
3573
+ * @param type $var Description. Default.
3574
+ * @return type Description.
3575
+ */
3576
+
3577
+ $: function( selector ){
3578
+ return this.$el.find( selector );
3579
+ },
3580
+
3581
+ /**
3582
+ * remove
3583
+ *
3584
+ * Removes the element and listenters
3585
+ *
3586
+ * @date 19/12/17
3587
+ * @since 5.6.5
3588
+ *
3589
+ * @param type $var Description. Default.
3590
+ * @return type Description.
3591
+ */
3592
+
3593
+ remove: function(){
3594
+ this.removeEvents();
3595
+ this.removeActions();
3596
+ this.removeFilters();
3597
+ this.$el.remove();
3598
+ },
3599
+
3600
+ /**
3601
+ * setTimeout
3602
+ *
3603
+ * description
3604
+ *
3605
+ * @date 16/1/18
3606
+ * @since 5.6.5
3607
+ *
3608
+ * @param type $var Description. Default.
3609
+ * @return type Description.
3610
+ */
3611
+
3612
+ setTimeout: function( callback, milliseconds ){
3613
+ return setTimeout( this.proxy(callback), milliseconds );
3614
+ },
3615
+
3616
+ /**
3617
+ * time
3618
+ *
3619
+ * used for debugging
3620
+ *
3621
+ * @date 7/3/18
3622
+ * @since 5.6.9
3623
+ *
3624
+ * @param type $var Description. Default.
3625
+ * @return type Description.
3626
+ */
3627
+
3628
+ time: function(){
3629
+ console.time( this.id || this.cid );
3630
+ },
3631
+
3632
+ /**
3633
+ * timeEnd
3634
+ *
3635
+ * used for debugging
3636
+ *
3637
+ * @date 7/3/18
3638
+ * @since 5.6.9
3639
+ *
3640
+ * @param type $var Description. Default.
3641
+ * @return type Description.
3642
+ */
3643
+
3644
+ timeEnd: function(){
3645
+ console.timeEnd( this.id || this.cid );
3646
+ },
3647
+
3648
+ /**
3649
+ * show
3650
+ *
3651
+ * description
3652
+ *
3653
+ * @date 15/3/18
3654
+ * @since 5.6.9
3655
+ *
3656
+ * @param type $var Description. Default.
3657
+ * @return type Description.
3658
+ */
3659
+
3660
+ show: function(){
3661
+ acf.show( this.$el );
3662
+ },
3663
+
3664
+
3665
+ /**
3666
+ * hide
3667
+ *
3668
+ * description
3669
+ *
3670
+ * @date 15/3/18
3671
+ * @since 5.6.9
3672
+ *
3673
+ * @param type $var Description. Default.
3674
+ * @return type Description.
3675
+ */
3676
+
3677
+ hide: function(){
3678
+ acf.hide( this.$el );
3679
+ },
3680
+
3681
+ /**
3682
+ * proxy
3683
+ *
3684
+ * Returns a new function scoped to this model
3685
+ *
3686
+ * @date 29/3/18
3687
+ * @since 5.6.9
3688
+ *
3689
+ * @param function callback
3690
+ * @return function
3691
+ */
3692
+
3693
+ proxy: function( callback ){
3694
+ return $.proxy( callback, this );
3695
+ }
3696
+
3697
+
3698
+ });
3699
+
3700
+ // Set up inheritance for the model
3701
+ Model.extend = extend;
3702
+
3703
+ // Global model storage
3704
+ acf.models = {};
3705
+
3706
+ /**
3707
+ * acf.getInstance
3708
+ *
3709
+ * This function will get an instance from an element
3710
+ *
3711
+ * @date 5/3/18
3712
+ * @since 5.6.9
3713
+ *
3714
+ * @param type $var Description. Default.
3715
+ * @return type Description.
3716
+ */
3717
+
3718
+ acf.getInstance = function( $el ){
3719
+ return $el.data('acf');
3720
+ };
3721
+
3722
+ /**
3723
+ * acf.getInstances
3724
+ *
3725
+ * This function will get an array of instances from multiple elements
3726
+ *
3727
+ * @date 5/3/18
3728
+ * @since 5.6.9
3729
+ *
3730
+ * @param type $var Description. Default.
3731
+ * @return type Description.
3732
+ */
3733
+
3734
+ acf.getInstances = function( $el ){
3735
+ var instances = [];
3736
+ $el.each(function(){
3737
+ instances.push( acf.getInstance( $(this) ) );
3738
+ });
3739
+ return instances;
3740
+ };
3741
+
3742
  })(jQuery);
3743
+ (function($, undefined){
3744
+
3745
+ acf.models.Popup = acf.Model.extend({
3746
+
3747
+ data: {
3748
+ title: '',
3749
+ content: '',
3750
+ width: 0,
3751
+ height: 0,
3752
+ loading: false
3753
+ },
3754
+
3755
+ events: {
3756
+ 'click [data-event="close"]': 'onClickClose',
3757
+ 'click .acf-close-popup': 'onClickClose',
3758
+ },
3759
+
3760
+ setup: function( props ){
3761
+ $.extend(this.data, props);
3762
+ this.$el = $(this.tmpl());
3763
+ },
3764
+
3765
+ initialize: function(){
3766
+ this.render();
3767
+ this.open();
3768
+ },
3769
+
3770
+ tmpl: function(){
3771
+ return [
3772
+ '<div id="acf-popup">',
3773
+ '<div class="acf-popup-box acf-box">',
3774
+ '<div class="title"><h3></h3><a href="#" class="acf-icon -cancel grey" data-event="close"></a></div>',
3775
+ '<div class="inner"></div>',
3776
+ '<div class="loading"><i class="acf-loading"></i></div>',
3777
+ '</div>',
3778
+ '<div class="bg" data-event="close"></div>',
3779
+ '</div>'
3780
+ ].join('');
3781
+ },
3782
+
3783
+ render: function(){
3784
+
3785
+ // Extract Vars.
3786
+ var title = this.get('title');
3787
+ var content = this.get('content');
3788
+ var loading = this.get('loading');
3789
+ var width = this.get('width');
3790
+ var height = this.get('height');
3791
+
3792
+ // Update.
3793
+ this.title( title );
3794
+ this.content( content );
3795
+ if( width ) {
3796
+ this.$('.acf-popup-box').css('width', width);
3797
+ }
3798
+ if( height ) {
3799
+ this.$('.acf-popup-box').css('min-height', height);
3800
+ }
3801
+ this.loading( loading );
3802
+
3803
+ // Trigger action.
3804
+ acf.doAction('append', this.$el);
3805
+ },
3806
+
3807
+ update: function( props ){
3808
+ this.data = acf.parseArgs(props, this.data);
3809
+ this.render();
3810
+ },
3811
+
3812
+ title: function( title ){
3813
+ this.$('.title:first h3').html( title );
3814
+ },
3815
+
3816
+ content: function( content ){
3817
+ this.$('.inner:first').html( content );
3818
+ },
3819
+
3820
+ loading: function( show ){
3821
+ var $loading = this.$('.loading:first');
3822
+ show ? $loading.show() : $loading.hide();
3823
+ },
3824
+
3825
+ open: function(){
3826
+ $('body').append( this.$el );
3827
+ },
3828
+
3829
+ close: function(){
3830
+ this.remove();
3831
+ },
3832
+
3833
+ onClickClose: function( e, $el ){
3834
+ e.preventDefault();
3835
+ this.close();
3836
+ }
3837
+
3838
+ });
3839
+
3840
+ /**
3841
+ * newPopup
3842
+ *
3843
+ * Creates a new Popup with the supplied props
3844
+ *
3845
+ * @date 17/12/17
3846
+ * @since 5.6.5
3847
+ *
3848
+ * @param object props
3849
+ * @return object
3850
+ */
3851
+
3852
+ acf.newPopup = function( props ){
3853
+ return new acf.models.Popup( props );
3854
+ };
3855
+
3856
  })(jQuery);
3857
+ (function($, undefined){
3858
+
3859
+ acf.models.Modal = acf.Model.extend({
3860
+ data: {
3861
+ title: '',
3862
+ content: '',
3863
+ toolbar: '',
3864
+ },
3865
+ events: {
3866
+ 'click .acf-modal-close': 'onClickClose',
3867
+ },
3868
+ setup: function( props ){
3869
+ $.extend(this.data, props);
3870
+ this.$el = $();
3871
+ this.render();
3872
+ },
3873
+ initialize: function(){
3874
+ this.open();
3875
+ },
3876
+ render: function(){
3877
+
3878
+ // Extract vars.
3879
+ var title = this.get('title');
3880
+ var content = this.get('content');
3881
+ var toolbar = this.get('toolbar');
3882
+
3883
+ // Create element.
3884
+ var $el = $([
3885
+ '<div>',
3886
+ '<div class="acf-modal">',
3887
+ '<div class="acf-modal-title">',
3888
+ '<h2>' + title + '</h2>',
3889
+ '<button class="acf-modal-close" type="button"><span class="dashicons dashicons-no"></span></button>',
3890
+ '</div>',
3891
+ '<div class="acf-modal-content">' + content + '</div>',
3892
+ '<div class="acf-modal-toolbar">' + toolbar + '</div>',
3893
+ '</div>',
3894
+ '<div class="acf-modal-backdrop acf-modal-close"></div>',
3895
+ '</div>'
3896
+ ].join('') );
3897
+
3898
+ // Update DOM.
3899
+ if( this.$el ) {
3900
+ this.$el.replaceWith( $el );
3901
+ }
3902
+ this.$el = $el;
3903
+
3904
+ // Trigger action.
3905
+ acf.doAction('append', $el);
3906
+ },
3907
+ update: function( props ){
3908
+ this.data = acf.parseArgs(props, this.data);
3909
+ this.render();
3910
+ },
3911
+ title: function( title ){
3912
+ this.$('.acf-modal-title h2').html( title );
3913
+ },
3914
+ content: function( content ){
3915
+ this.$('.acf-modal-content').html( content );
3916
+ },
3917
+ toolbar: function( toolbar ){
3918
+ this.$('.acf-modal-toolbar').html( toolbar );
3919
+ },
3920
+ open: function(){
3921
+ $('body').append( this.$el );
3922
+ },
3923
+ close: function(){
3924
+ this.remove();
3925
+ },
3926
+ onClickClose: function( e, $el ){
3927
+ e.preventDefault();
3928
+ this.close();
3929
+ }
3930
+ });
3931
+
3932
+ /**
3933
+ * Returns a new modal.
3934
+ *
3935
+ * @date 21/4/20
3936
+ * @since 5.9.0
3937
+ *
3938
+ * @param object props The modal props.
3939
+ * @return object
3940
+ */
3941
+ acf.newModal = function( props ){
3942
+ return new acf.models.Modal( props );
3943
+ };
3944
+
3945
  })(jQuery);
3946
+ (function($, undefined){
3947
+
3948
+ var panel = new acf.Model({
3949
+
3950
+ events: {
3951
+ 'click .acf-panel-title': 'onClick',
3952
+ },
3953
+
3954
+ onClick: function( e, $el ){
3955
+ e.preventDefault();
3956
+ this.toggle( $el.parent() );
3957
+ },
3958
+
3959
+ isOpen: function( $el ) {
3960
+ return $el.hasClass('-open');
3961
+ },
3962
+
3963
+ toggle: function( $el ){
3964
+ this.isOpen($el) ? this.close( $el ) : this.open( $el );
3965
+ },
3966
+
3967
+ open: function( $el ){
3968
+ $el.addClass('-open');
3969
+ $el.find('.acf-panel-title i').attr('class', 'dashicons dashicons-arrow-down');
3970
+ },
3971
+
3972
+ close: function( $el ){
3973
+ $el.removeClass('-open');
3974
+ $el.find('.acf-panel-title i').attr('class', 'dashicons dashicons-arrow-right');
3975
+ }
3976
+
3977
+ });
3978
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3979
  })(jQuery);
3980
+ (function($, undefined){
3981
+
3982
+ var Notice = acf.Model.extend({
3983
+
3984
+ data: {
3985
+ text: '',
3986
+ type: '',
3987
+ timeout: 0,
3988
+ dismiss: true,
3989
+ target: false,
3990
+ close: function(){}
3991
+ },
3992
+
3993
+ events: {
3994
+ 'click .acf-notice-dismiss': 'onClickClose',
3995
+ },
3996
+
3997
+ tmpl: function(){
3998
+ return '<div class="acf-notice"></div>';
3999
+ },
4000
+
4001
+ setup: function( props ){
4002
+ $.extend(this.data, props);
4003
+ this.$el = $(this.tmpl());
4004
+ },
4005
+
4006
+ initialize: function(){
4007
+
4008
+ // render
4009
+ this.render();
4010
+
4011
+ // show
4012
+ this.show();
4013
+ },
4014
+
4015
+ render: function(){
4016
+
4017
+ // class
4018
+ this.type( this.get('type') );
4019
+
4020
+ // text
4021
+ this.html( '<p>' + this.get('text') + '</p>' );
4022
+
4023
+ // close
4024
+ if( this.get('dismiss') ) {
4025
+ this.$el.append('<a href="#" class="acf-notice-dismiss acf-icon -cancel small"></a>');
4026
+ this.$el.addClass('-dismiss');
4027
+ }
4028
+
4029
+ // timeout
4030
+ var timeout = this.get('timeout');
4031
+ if( timeout ) {
4032
+ this.away( timeout );
4033
+ }
4034
+ },
4035
+
4036
+ update: function( props ){
4037
+
4038
+ // update
4039
+ $.extend(this.data, props);
4040
+
4041
+ // re-initialize
4042
+ this.initialize();
4043
+
4044
+ // refresh events
4045
+ this.removeEvents();
4046
+ this.addEvents();
4047
+ },
4048
+
4049
+ show: function(){
4050
+ var $target = this.get('target');
4051
+ if( $target ) {
4052
+ $target.prepend( this.$el );
4053
+ }
4054
+ },
4055
+
4056
+ hide: function(){
4057
+ this.$el.remove();
4058
+ },
4059
+
4060
+ away: function( timeout ){
4061
+ this.setTimeout(function(){
4062
+ acf.remove( this.$el );
4063
+ }, timeout );
4064
+ },
4065
+
4066
+ type: function( type ){
4067
+
4068
+ // remove prev type
4069
+ var prevType = this.get('type');
4070
+ if( prevType ) {
4071
+ this.$el.removeClass('-' + prevType);
4072
+ }
4073
+
4074
+ // add new type
4075
+ this.$el.addClass('-' + type);
4076
+
4077
+ // backwards compatibility
4078
+ if( type == 'error' ) {
4079
+ this.$el.addClass('acf-error-message');
4080
+ }
4081
+ },
4082
+
4083
+ html: function( html ){
4084
+ this.$el.html( acf.escHtml( html ) );
4085
+ },
4086
+
4087
+ text: function( text ){
4088
+ this.$('p').html( acf.escHtml( text ) );
4089
+ },
4090
+
4091
+ onClickClose: function( e, $el ){
4092
+ e.preventDefault();
4093
+ this.get('close').apply(this, arguments);
4094
+ this.remove();
4095
+ }
4096
+ });
4097
+
4098
+ acf.newNotice = function( props ){
4099
+
4100
+ // ensure object
4101
+ if( typeof props !== 'object' ) {
4102
+ props = { text: props };
4103
+ }
4104
+
4105
+ // instantiate
4106
+ return new Notice( props );
4107
+ };
4108
+
4109
+ var noticeManager = new acf.Model({
4110
+ wait: 'prepare',
4111
+ priority: 1,
4112
+ initialize: function(){
4113
+
4114
+ // vars
4115
+ var $notice = $('.acf-admin-notice');
4116
+
4117
+ // move to avoid WP flicker
4118
+ if( $notice.length ) {
4119
+ $('h1:first').after( $notice );
4120
+ }
4121
+ }
4122
+ });
4123
+
4124
+
4125
+ })(jQuery);
4126
+ (function($, undefined){
4127
+
4128
+ acf.newTooltip = function( props ){
4129
+
4130
+ // ensure object
4131
+ if( typeof props !== 'object' ) {
4132
+ props = { text: props };
4133
+ }
4134
+
4135
+ // confirmRemove
4136
+ if( props.confirmRemove !== undefined ) {
4137
+
4138
+ props.textConfirm = acf.__('Remove');
4139
+ props.textCancel = acf.__('Cancel');
4140
+ return new TooltipConfirm( props );
4141
+
4142
+ // confirm
4143
+ } else if( props.confirm !== undefined ) {
4144
+
4145
+ return new TooltipConfirm( props );
4146
+
4147
+ // default
4148
+ } else {
4149
+ return new Tooltip( props );
4150
+ }
4151
+
4152
+ };
4153
+
4154
+ var Tooltip = acf.Model.extend({
4155
+
4156
+ data: {
4157
+ text: '',
4158
+ timeout: 0,
4159
+ target: null
4160
+ },
4161
+
4162
+ tmpl: function(){
4163
+ return '<div class="acf-tooltip"></div>';
4164
+ },
4165
+
4166
+ setup: function( props ){
4167
+ $.extend(this.data, props);
4168
+ this.$el = $(this.tmpl());
4169
+ },
4170
+
4171
+ initialize: function(){
4172
+
4173
+ // render
4174
+ this.render();
4175
+
4176
+ // append
4177
+ this.show();
4178
+
4179
+ // position
4180
+ this.position();
4181
+
4182
+ // timeout
4183
+ var timeout = this.get('timeout');
4184
+ if( timeout ) {
4185
+ setTimeout( $.proxy(this.fade, this), timeout );
4186
+ }
4187
+ },
4188
+
4189
+ update: function( props ){
4190
+ $.extend(this.data, props);
4191
+ this.initialize();
4192
+ },
4193
+
4194
+ render: function(){
4195
+ this.html( this.get('text') );
4196
+ },
4197
+
4198
+ show: function(){
4199
+ $('body').append( this.$el );
4200
+ },
4201
+
4202
+ hide: function(){
4203
+ this.$el.remove();
4204
+ },
4205
+
4206
+ fade: function(){
4207
+
4208
+ // add class
4209
+ this.$el.addClass('acf-fade-up');
4210
+
4211
+ // remove
4212
+ this.setTimeout(function(){
4213
+ this.remove();
4214
+ }, 250);
4215
+ },
4216
+
4217
+ html: function( html ){
4218
+ this.$el.html( html );
4219
+ },
4220
+
4221
+ position: function(){
4222
+
4223
+ // vars
4224
+ var $tooltip = this.$el;
4225
+ var $target = this.get('target');
4226
+ if( !$target ) return;
4227
+
4228
+ // Reset position.
4229
+ $tooltip.removeClass('right left bottom top').css({ top: 0, left: 0 });
4230
+
4231
+ // Declare tollerance to edge of screen.
4232
+ var tolerance = 10;
4233
+
4234
+ // Find target position.
4235
+ var targetWidth = $target.outerWidth();
4236
+ var targetHeight = $target.outerHeight();
4237
+ var targetTop = $target.offset().top;
4238
+ var targetLeft = $target.offset().left;
4239
+
4240
+ // Find tooltip position.
4241
+ var tooltipWidth = $tooltip.outerWidth();
4242
+ var tooltipHeight = $tooltip.outerHeight();
4243
+ var tooltipTop = $tooltip.offset().top; // Should be 0, but WP media grid causes this to be 32 (toolbar padding).
4244
+
4245
+ // Assume default top alignment.
4246
+ var top = targetTop - tooltipHeight - tooltipTop;
4247
+ var left = targetLeft + (targetWidth / 2) - (tooltipWidth / 2);
4248
+
4249
+ // Check if too far left.
4250
+ if( left < tolerance ) {
4251
+ $tooltip.addClass('right');
4252
+ left = targetLeft + targetWidth;
4253
+ top = targetTop + (targetHeight / 2) - (tooltipHeight / 2) - tooltipTop;
4254
+
4255
+ // Check if too far right.
4256
+ } else if( (left + tooltipWidth + tolerance) > $(window).width() ) {
4257
+ $tooltip.addClass('left');
4258
+ left = targetLeft - tooltipWidth;
4259
+ top = targetTop + (targetHeight / 2) - (tooltipHeight / 2) - tooltipTop;
4260
+
4261
+ // Check if too far up.
4262
+ } else if( top - $(window).scrollTop() < tolerance ) {
4263
+ $tooltip.addClass('bottom');
4264
+ top = targetTop + targetHeight - tooltipTop;
4265
+
4266
+ // No colision with edges.
4267
+ } else {
4268
+ $tooltip.addClass('top');
4269
+ }
4270
+
4271
+ // update css
4272
+ $tooltip.css({ 'top': top, 'left': left });
4273
+ }
4274
+ });
4275
+
4276
+ var TooltipConfirm = Tooltip.extend({
4277
+
4278
+ data: {
4279
+ text: '',
4280
+ textConfirm: '',
4281
+ textCancel: '',
4282
+ target: null,
4283
+ targetConfirm: true,
4284
+ confirm: function(){},
4285
+ cancel: function(){},
4286
+ context: false
4287
+ },
4288
+
4289
+ events: {
4290
+ 'click [data-event="cancel"]': 'onCancel',
4291
+ 'click [data-event="confirm"]': 'onConfirm',
4292
+ },
4293
+
4294
+ addEvents: function(){
4295
+
4296
+ // add events
4297
+ acf.Model.prototype.addEvents.apply(this);
4298
+
4299
+ // vars
4300
+ var $document = $(document);
4301
+ var $target = this.get('target');
4302
+
4303
+ // add global 'cancel' click event
4304
+ // - use timeout to avoid the current 'click' event triggering the onCancel function
4305
+ this.setTimeout(function(){
4306
+ this.on( $document, 'click', 'onCancel' );
4307
+ });
4308
+
4309
+ // add target 'confirm' click event
4310
+ // - allow setting to control this feature
4311
+ if( this.get('targetConfirm') ) {
4312
+ this.on( $target, 'click', 'onConfirm' );
4313
+ }
4314
+ },
4315
+
4316
+ removeEvents: function(){
4317
+
4318
+ // remove events
4319
+ acf.Model.prototype.removeEvents.apply(this);
4320
+
4321
+ // vars
4322
+ var $document = $(document);
4323
+ var $target = this.get('target');
4324
+
4325
+ // remove custom events
4326
+ this.off( $document, 'click' );
4327
+ this.off( $target, 'click' );
4328
+ },
4329
+
4330
+ render: function(){
4331
+
4332
+ // defaults
4333
+ var text = this.get('text') || acf.__('Are you sure?');
4334
+ var textConfirm = this.get('textConfirm') || acf.__('Yes');
4335
+ var textCancel = this.get('textCancel') || acf.__('No');
4336
+
4337
+ // html
4338
+ var html = [
4339
+ text,
4340
+ '<a href="#" data-event="confirm">' + textConfirm + '</a>',
4341
+ '<a href="#" data-event="cancel">' + textCancel + '</a>'
4342
+ ].join(' ');
4343
+
4344
+ // html
4345
+ this.html( html );
4346
+
4347
+ // class
4348
+ this.$el.addClass('-confirm');
4349
+ },
4350
+
4351
+ onCancel: function( e, $el ){
4352
+
4353
+ // prevent default
4354
+ e.preventDefault();
4355
+ e.stopImmediatePropagation();
4356
+
4357
+ // callback
4358
+ var callback = this.get('cancel');
4359
+ var context = this.get('context') || this;
4360
+ callback.apply( context, arguments );
4361
+
4362
+ //remove
4363
+ this.remove();
4364
+ },
4365
+
4366
+ onConfirm: function( e, $el ){
4367
+
4368
+ // Prevent event from propagating completely to allow "targetConfirm" to be clicked.
4369
+ e.preventDefault();
4370
+ e.stopImmediatePropagation();
4371
+
4372
+ // callback
4373
+ var callback = this.get('confirm');
4374
+ var context = this.get('context') || this;
4375
+ callback.apply( context, arguments );
4376
+
4377
+ //remove
4378
+ this.remove();
4379
+ }
4380
+ });
4381
+
4382
+ // storage
4383
+ acf.models.Tooltip = Tooltip;
4384
+ acf.models.TooltipConfirm = TooltipConfirm;
4385
+
4386
+
4387
+ /**
4388
+ * tooltipManager
4389
+ *
4390
+ * description
4391
+ *
4392
+ * @date 17/4/18
4393
+ * @since 5.6.9
4394
+ *
4395
+ * @param type $var Description. Default.
4396
+ * @return type Description.
4397
+ */
4398
+
4399
+ var tooltipHoverHelper = new acf.Model({
4400
+
4401
+ tooltip: false,
4402
+
4403
+ events: {
4404
+ 'mouseenter .acf-js-tooltip': 'showTitle',
4405
+ 'mouseup .acf-js-tooltip': 'hideTitle',
4406
+ 'mouseleave .acf-js-tooltip': 'hideTitle'
4407
+ },
4408
+
4409
+ showTitle: function( e, $el ){
4410
+
4411
+ // vars
4412
+ var title = $el.attr('title');
4413
+
4414
+ // bail ealry if no title
4415
+ if( !title ) {
4416
+ return;
4417
+ }
4418
+
4419
+ // clear title to avoid default browser tooltip
4420
+ $el.attr('title', '');
4421
+
4422
+ // create
4423
+ if( !this.tooltip ) {
4424
+ this.tooltip = acf.newTooltip({
4425
+ text: title,
4426
+ target: $el
4427
+ });
4428
+
4429
+ // update
4430
+ } else {
4431
+ this.tooltip.update({
4432
+ text: title,
4433
+ target: $el
4434
+ });
4435
+ }
4436
+
4437
+ },
4438
+
4439
+ hideTitle: function( e, $el ){
4440
+
4441
+ // hide tooltip
4442
+ this.tooltip.hide();
4443
+
4444
+ // restore title
4445
+ $el.attr('title', this.tooltip.get('text'));
4446
+ }
4447
+ });
4448
+
4449
  })(jQuery);
assets/build/js/acf.min.js CHANGED
@@ -1 +1 @@
1
- !function(s,r){var c={};(window.acf=c).data={},c.get=function(t){return this.data[t]||null},c.has=function(t){return null!==this.get(t)},c.set=function(t,e){return this.data[t]=e,this};var n=0;c.uniqueId=function(t){var e=++n+"";return t?t+e:e},c.uniqueArray=function(t){return t.filter(function(t,e,n){return n.indexOf(t)===e})};var i="";c.uniqid=function(t,e){void 0===t&&(t="");function n(t,e){return e<(t=parseInt(t,10).toString(16)).length?t.slice(t.length-e):e>t.length?Array(e-t.length+1).join("0")+t:t}return i=i||Math.floor(123456789*Math.random()),i++,t=t,t+=n(parseInt((new Date).getTime()/1e3,10),8),t+=n(i,5),e&&(t+=(10*Math.random()).toFixed(8).toString()),t},c.strReplace=function(t,e,n){return n.split(t).join(e)},c.strCamelCase=function(t){t=t.match(/([a-zA-Z0-9]+)/g);return t?t.map(function(t,e){var n=t.charAt(0);return(0===e?n.toLowerCase():n.toUpperCase())+t.slice(1)}).join(""):""},c.strPascalCase=function(t){t=c.strCamelCase(t);return t.charAt(0).toUpperCase()+t.slice(1)},c.strSlugify=function(t){return c.strReplace("_","-",t.toLowerCase())},c.strSanitize=function(t){var e={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","ß":"s","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Ĉ":"C","ĉ":"c","Ċ":"C","ċ":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"D","đ":"d","Ē":"E","ē":"e","Ĕ":"E","ĕ":"e","Ė":"E","ė":"e","Ę":"E","ę":"e","Ě":"E","ě":"e","Ĝ":"G","ĝ":"g","Ğ":"G","ğ":"g","Ġ":"G","ġ":"g","Ģ":"G","ģ":"g","Ĥ":"H","ĥ":"h","Ħ":"H","ħ":"h","Ĩ":"I","ĩ":"i","Ī":"I","ī":"i","Ĭ":"I","ĭ":"i","Į":"I","į":"i","İ":"I","ı":"i","IJ":"IJ","ij":"ij","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","Ĺ":"L","ĺ":"l","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ŀ":"L","ŀ":"l","Ł":"l","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","ʼn":"n","Ō":"O","ō":"o","Ŏ":"O","ŏ":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ŗ":"R","ŗ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ŝ":"S","ŝ":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ŧ":"T","ŧ":"t","Ũ":"U","ũ":"u","Ū":"U","ū":"u","Ŭ":"U","ŭ":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","ſ":"s","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Ǎ":"A","ǎ":"a","Ǐ":"I","ǐ":"i","Ǒ":"O","ǒ":"o","Ǔ":"U","ǔ":"u","Ǖ":"U","ǖ":"u","Ǘ":"U","ǘ":"u","Ǚ":"U","ǚ":"u","Ǜ":"U","ǜ":"u","Ǻ":"A","ǻ":"a","Ǽ":"AE","ǽ":"ae","Ǿ":"O","ǿ":"o"," ":"_","'":"","?":"","/":"","\\":"",".":"",",":"","`":"",">":"","<":"",'"':"","[":"","]":"","|":"","{":"","}":"","(":"",")":""};return t=(t=t.replace(/\W/g,function(t){return e[t]!==r?e[t]:t})).toLowerCase()},c.strMatch=function(t,e){for(var n=0,i=Math.min(t.length,e.length),o=0;o<i&&t[o]===e[o];o++)n++;return n},c.strEscape=function(t){var e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return(""+t).replace(/[&<>"']/g,function(t){return e[t]})},c.strUnescape=function(t){var e={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"};return(""+t).replace(/&amp;|&lt;|&gt;|&quot;|&#39;/g,function(t){return e[t]})},c.escAttr=c.strEscape,c.escHtml=function(t){return(""+t).replace(/<script|<\/script/g,function(t){return c.strEscape(t)})},c.decode=function(t){return s("<textarea/>").html(t).text()},c.parseArgs=function(t,e){return s.extend({},e="object"!=typeof e?{}:e,t="object"!=typeof t?{}:t)},window.acfL10n==r&&(acfL10n={}),c.__=function(t){return acfL10n[t]||t},c._x=function(t,e){return acfL10n[t+"."+e]||acfL10n[t]||t},c._n=function(t,e,n){return 1==n?c.__(t):c.__(e)},c.isArray=function(t){return Array.isArray(t)},c.isObject=function(t){return"object"==typeof t};c.serialize=function(t,e){var n={},i=c.serializeArray(t);e!==r&&(i=i.filter(function(t){return 0===t.name.indexOf(e)}).map(function(t){return t.name=t.name.slice(e.length),t}));for(var o=0;o<i.length;o++)!function(t,e,n){var i=(e=e.replace("[]","[%%index%%]")).match(/([^\[\]])+/g);if(i)for(var o=i.length,r=t,a=0;a<o;a++){var s=String(i[a]);a==o-1?"%%index%%"===s?r.push(n):r[s]=n:("%%index%%"===i[a+1]?c.isArray(r[s])||(r[s]=[]):c.isObject(r[s])||(r[s]={}),r=r[s])}}(n,i[o].name,i[o].value);return n},c.serializeArray=function(t){return t.find("select, textarea, input").serializeArray()},c.serializeForAjax=function(t){var e={};return c.serializeArray(t).map(function(t){"[]"===t.name.slice(-2)?(e[t.name]=e[t.name]||[],e[t.name].push(t.value)):e[t.name]=t.value}),e},c.addAction=function(t,e,n,i){return c.hooks.addAction.apply(this,arguments),this},c.removeAction=function(t,e){return c.hooks.removeAction.apply(this,arguments),this};var e={};c.doAction=function(t){return e[t]=1,c.hooks.doAction.apply(this,arguments),e[t]=0,this},c.doingAction=function(t){return 1===e[t]},c.didAction=function(t){return e[t]!==r},c.currentAction=function(){for(var t in e)if(e[t])return t;return!1},c.addFilter=function(t){return c.hooks.addFilter.apply(this,arguments),this},c.removeFilter=function(t){return c.hooks.removeFilter.apply(this,arguments),this},c.applyFilters=function(t){return c.hooks.applyFilters.apply(this,arguments)},c.arrayArgs=function(t){return Array.prototype.slice.call(t)};try{var o=JSON.parse(localStorage.getItem("acf"))||{}}catch(t){o={}}function a(t){return t="this."===t.substr(0,5)?t.substr(5)+"-"+c.get("post_id"):t}c.getPreference=function(t){return t=a(t),o[t]||null},c.setPreference=function(t,e){t=a(t),null===e?delete o[t]:o[t]=e,localStorage.setItem("acf",JSON.stringify(o))},c.removePreference=function(t){c.setPreference(t,null)},c.remove=function(t){t instanceof jQuery&&(t={target:t}),t=c.parseArgs(t,{target:!1,endHeight:0,complete:function(){}}),c.doAction("remove",t.target),(t.target.is("tr")?u:l)(t)};var l=function(t){var e=t.target,n=e.height(),i=e.width(),o=e.css("margin"),r=e.outerHeight(!0),a=e.attr("style")+"";e.wrap('<div class="acf-temp-remove" style="height:'+r+'px"></div>');var s=e.parent();e.css({height:n,width:i,margin:o,position:"absolute"}),setTimeout(function(){s.css({opacity:0,height:t.endHeight})},50),setTimeout(function(){e.attr("style",a),s.remove(),t.complete()},301)},u=function(t){var e=t.target,n=e.height(),i=e.children().length,o=s('<td class="acf-temp-remove" style="padding:0; height:'+n+'px" colspan="'+i+'"></td>');e.addClass("acf-remove-element"),setTimeout(function(){e.html(o)},251),setTimeout(function(){e.removeClass("acf-remove-element"),o.css({height:t.endHeight})},300),setTimeout(function(){e.remove(),t.complete()},451)};c.duplicate=function(t){t instanceof jQuery&&(t={target:t}),(t=c.parseArgs(t,{target:!1,search:"",replace:"",rename:!0,before:function(t){},after:function(t,e){},append:function(t,e){t.after(e)}})).target=t.target||t.$el;var e=t.target;t.search=t.search||e.attr("data-id"),t.replace=t.replace||c.uniqid(),t.before(e),c.doAction("before_duplicate",e);var n=e.clone();return t.rename&&c.rename({target:n,search:t.search,replace:t.replace,replacer:"function"==typeof t.rename?t.rename:null}),n.removeClass("acf-clone"),n.find(".ui-sortable").removeClass("ui-sortable"),t.after(e,n),c.doAction("after_duplicate",e,n),t.append(e,n),c.doAction("duplicate",e,n),c.doAction("append",n),n},c.rename=function(i){i instanceof jQuery&&(i={target:i});var t=(i=c.parseArgs(i,{target:!1,destructive:!1,search:"",replace:"",replacer:null})).target;i.search||(i.search=t.attr("data-id")),i.replace||(i.replace=c.uniqid("acf")),i.replacer||(i.replacer=function(t,e,n,i){return e.replace(n,i)});function e(n){return function(t,e){return i.replacer(n,e,i.search,i.replace)}}var n;return i.destructive?(n=c.strReplace(i.search,i.replace,t.outerHTML()),t.replaceWith(n)):(t.attr("data-id",i.replace),t.find('[id*="'+i.search+'"]').attr("id",e("id")),t.find('[for*="'+i.search+'"]').attr("for",e("for")),t.find('[name*="'+i.search+'"]').attr("name",e("name"))),t},c.prepareForAjax=function(t){return t.nonce=c.get("nonce"),t.post_id=c.get("post_id"),c.has("language")&&(t.lang=c.get("language")),t=c.applyFilters("prepare_for_ajax",t)},c.startButtonLoading=function(t){t.prop("disabled",!0),t.after(' <i class="acf-loading"></i>')},c.stopButtonLoading=function(t){t.prop("disabled",!1),t.next(".acf-loading").remove()},c.showLoading=function(t){t.append('<div class="acf-loading-overlay"><i class="acf-loading"></i></div>')},c.hideLoading=function(t){t.children(".acf-loading-overlay").remove()},c.updateUserSetting=function(t,e){e={action:"acf/ajax/user_setting",name:t,value:e};s.ajax({url:c.get("ajaxurl"),data:c.prepareForAjax(e),type:"post",dataType:"html"})},c.val=function(t,e,n){var i=t.val();return e!==i&&(t.val(e),t.is("select")&&null===t.val()?(t.val(i),!1):(!0!==n&&t.trigger("change"),!0))},c.show=function(t,e){return e&&c.unlock(t,"hidden",e),!c.isLocked(t,"hidden")&&(!!t.hasClass("acf-hidden")&&(t.removeClass("acf-hidden"),!0))},c.hide=function(t,e){return e&&c.lock(t,"hidden",e),!t.hasClass("acf-hidden")&&(t.addClass("acf-hidden"),!0)},c.isHidden=function(t){return t.hasClass("acf-hidden")},c.isVisible=function(t){return!c.isHidden(t)};function f(t,e){return!t.hasClass("acf-disabled")&&(e&&c.unlock(t,"disabled",e),!c.isLocked(t,"disabled")&&(!!t.prop("disabled")&&(t.prop("disabled",!1),!0)))}c.enable=function(t,e){if(t.attr("name"))return f(t,e);var n=!1;return t.find("[name]").each(function(){f(s(this),e)&&(n=!0)}),n};function d(t,e){return e&&c.lock(t,"disabled",e),!t.prop("disabled")&&(t.prop("disabled",!0),!0)}c.disable=function(t,e){if(t.attr("name"))return d(t,e);var n=!1;return t.find("[name]").each(function(){d(s(this),e)&&(n=!0)}),n},c.isset=function(t){for(var e=1;e<arguments.length;e++){if(!t||!t.hasOwnProperty(arguments[e]))return!1;t=t[arguments[e]]}return!0},c.isget=function(t){for(var e=1;e<arguments.length;e++){if(!t||!t.hasOwnProperty(arguments[e]))return null;t=t[arguments[e]]}return t},c.getFileInputData=function(t,e){var n=t.val();if(!n)return!1;var i={url:n},o=c.isget(t[0],"files",0);o?(i.size=o.size,i.type=o.type,-1<o.type.indexOf("image")?(n=window.URL||window.webkitURL,(t=new Image).onload=function(){i.width=this.width,i.height=this.height,e(i)},t.src=n.createObjectURL(o)):e(i)):e(i)},c.isAjaxSuccess=function(t){return t&&t.success},c.getAjaxMessage=function(t){return c.isget(t,"data","message")},c.getAjaxError=function(t){return c.isget(t,"data","error")},c.getXhrError=function(t){return t.responseJSON&&t.responseJSON.message?t.responseJSON.message:t.statusText||""},c.renderSelect=function(t,e){var n=t.val(),o=[],r=function(t){var i="";return t.map(function(t){var e=t.text||t.label||"",n=t.id||t.value||"";o.push(n),t.children?i+='<optgroup label="'+c.escAttr(e)+'">'+r(t.children)+"</optgroup>":i+='<option value="'+c.escAttr(n)+'"'+(t.disabled?' disabled="disabled"':"")+">"+c.strEscape(e)+"</option>"}),i};return t.html(r(e)),-1<o.indexOf(n)&&t.val(n),t.val()};function h(t,e){return t.data("acf-lock-"+e)||[]}function p(t,e,n){t.data("acf-lock-"+e,n)}var g,v,m,y;function w(){g.forEach(function(t){c.isInView(t.el)&&(t.callback.apply(this),y(t.id))})}c.lock=function(t,e,n){var i=h(t,e);i.indexOf(n)<0&&(i.push(n),p(t,e,i))},c.unlock=function(t,e,n){var i=h(t,e),n=i.indexOf(n);return-1<n&&(i.splice(n,1),p(t,e,i)),0===i.length},c.isLocked=function(t,e){return 0<h(t,e).length},c.isGutenberg=function(){return!!(window.wp&&wp.data&&wp.data.select&&wp.data.select("core/editor"))},c.objectToArray=function(e){return Object.keys(e).map(function(t){return e[t]})},c.debounce=function(n,i){var o;return function(){var t=this,e=arguments;clearTimeout(o),o=setTimeout(function(){n.apply(t,e)},i)}},c.throttle=function(t,e){var n=!1;return function(){n||(n=!0,setTimeout(function(){n=!1},e),t.apply(this,arguments))}},c.isInView=function(t){t=(t=t instanceof jQuery?t[0]:t).getBoundingClientRect();return t.top!==t.bottom&&0<=t.top&&0<=t.left&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)},c.onceInView=(g=[],v=0,m=c.debounce(w,300),y=function(e){(g=g.filter(function(t){return t.id!==e})).length||s(window).off("scroll resize",m).off("acfrefresh orientationchange",w)},function(t,e){t instanceof jQuery&&(t=t[0]),c.isInView(t)?e.apply(this):(t=t,e=e,g.length||s(window).on("scroll resize",m).on("acfrefresh orientationchange",w),g.push({id:v++,el:t,callback:e}))}),c.once=function(t){var e=0;return function(){return 0<e++?t=r:t.apply(this,arguments)}},c.focusAttention=function(t){var e=1e3;t.addClass("acf-attention -focused");c.isInView(t)||(s("body, html").animate({scrollTop:t.offset().top-s(window).height()/2},500),e+=500);setTimeout(function(){t.removeClass("-focused"),setTimeout(function(){t.removeClass("acf-attention")},250)},e)},c.onFocus=function(e,n){function t(){o=!0,setTimeout(function(){o=!1},1),a(!0)}function i(){o||a(!1)}var o=!1,r=!1,a=function(t){r!==t&&(t?(s(document).on("click",i),e.on("blur","input, select, textarea",i)):(s(document).off("click",i),e.off("blur","input, select, textarea",i)),n(r=t))};e.on("click",t),e.on("focus","input, select, textarea",t)},s.fn.exists=function(){return 0<s(this).length},s.fn.outerHTML=function(){return s(this).get(0).outerHTML},Array.prototype.indexOf||(Array.prototype.indexOf=function(t){return s.inArray(t,this)}),c.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},c.refresh=c.debounce(function(){s(window).trigger("acfrefresh"),c.doAction("refresh")},0),s(document).ready(function(){c.doAction("ready")}),s(window).on("load",function(){setTimeout(function(){c.doAction("load")})}),s(window).on("beforeunload",function(){c.doAction("unload")}),s(window).on("resize",function(){c.doAction("resize")}),s(document).on("sortstart",function(t,e){c.doAction("sortstart",e.item,e.placeholder)}),s(document).on("sortstop",function(t,e){c.doAction("sortstop",e.item,e.placeholder)})}(jQuery),function(){"use strict";acf.hooks=new function(){var o={removeFilter:function(t,e){"string"==typeof t&&n("filters",t,e);return o},applyFilters:function(){var t=Array.prototype.slice.call(arguments),e=t.shift();return"string"!=typeof e?o:i("filters",e,t)},addFilter:function(t,e,n,i){"string"==typeof t&&"function"==typeof e&&(n=parseInt(n||10,10),r("filters",t,e,n,i));return o},removeAction:function(t,e){"string"==typeof t&&n("actions",t,e);return o},doAction:function(){var t=Array.prototype.slice.call(arguments),e=t.shift();"string"==typeof e&&i("actions",e,t);return o},addAction:function(t,e,n,i){"string"==typeof t&&"function"==typeof e&&(n=parseInt(n||10,10),r("actions",t,e,n,i));return o},storage:function(){return s}},s={actions:{},filters:{}};function n(t,e,n,i){if(s[t][e])if(n){var o,r=s[t][e];if(i)for(o=r.length;o--;){var a=r[o];a.callback===n&&a.context===i&&r.splice(o,1)}else for(o=r.length;o--;)r[o].callback===n&&r.splice(o,1)}else s[t][e]=[]}function r(t,e,n,i,o){i={callback:n,priority:i,context:o},o=(o=s[t][e])?(o.push(i),function(t){for(var e,n,i,o=1,r=t.length;o<r;o++){for(e=t[o],n=o;(i=t[n-1])&&i.priority>e.priority;)t[n]=t[n-1],--n;t[n]=e}return t}(o)):[i];s[t][e]=o}function i(t,e,n){var i=s[t][e];if(!i)return"filters"===t&&n[0];var o=0,r=i.length;if("filters"===t)for(;o<r;o++)n[0]=i[o].callback.apply(i[o].context,n);else for(;o<r;o++)i[o].callback.apply(i[o].context,n);return"filters"!==t||n[0]}return o}}(window),function(i){var o=/^(\S+)\s*(.*)$/,t=acf.Model=function(){this.cid=acf.uniqueId("acf"),this.data=i.extend(!0,{},this.data),this.setup.apply(this,arguments),this.$el&&!this.$el.data("acf")&&this.$el.data("acf",this);function t(){this.initialize(),this.addEvents(),this.addActions(),this.addFilters()}this.wait&&!acf.didAction(this.wait)?this.addAction(this.wait,t):t.apply(this)};i.extend(t.prototype,{id:"",cid:"",$el:null,data:{},busy:!1,changed:!1,events:{},actions:{},filters:{},eventScope:"",wait:!1,priority:10,get:function(t){return this.data[t]},has:function(t){return null!=this.get(t)},set:function(t,e,n){var i=this.get(t);return i==e||(this.data[t]=e,n||(this.changed=!0,this.trigger("changed:"+t,[e,i]),this.trigger("changed",[t,e,i]))),this},inherit:function(t){return t instanceof jQuery&&(t=t.data()),i.extend(this.data,t),this},prop:function(){return this.$el.prop.apply(this.$el,arguments)},setup:function(t){i.extend(this,t)},initialize:function(){},addElements:function(t){if(!(t=t||this.elements||null)||!Object.keys(t).length)return!1;for(var e in t)this.addElement(e,t[e])},addElement:function(t,e){this["$"+t]=this.$(e)},addEvents:function(t){if(!(t=t||this.events||null))return!1;for(var e in t){var n=e.match(o);this.on(n[1],n[2],t[e])}},removeEvents:function(t){if(!(t=t||this.events||null))return!1;for(var e in t){var n=e.match(o);this.off(n[1],n[2],t[e])}},getEventTarget:function(t,e){return t||this.$el||i(document)},validateEvent:function(t){return!this.eventScope||i(t.target).closest(this.eventScope).is(this.$el)},proxyEvent:function(n){return this.proxy(function(t){var e;this.validateEvent(t)&&(e=acf.arrayArgs(arguments).slice(1),e=[t,i(t.currentTarget)].concat(e),n.apply(this,e))})},on:function(t,e,n,i){var o,r,e=t instanceof jQuery?i?(a=t,o=e,r=n,i):(a=t,o=e,n):n?(o=t,r=e,n):(o=t,e),a=this.getEventTarget(a);"string"==typeof e&&(e=this.proxyEvent(this[e])),o=o+"."+this.cid,a.on.apply(a,r?[o,r,e]:[o,e])},off:function(t,e,n){var i,o,r;t instanceof jQuery?n?(i=t,o=e,r=n):(i=t,o=e):e?(o=t,r=e):o=t,i=this.getEventTarget(i),o=o+"."+this.cid,i.off.apply(i,r?[o,r]:[o])},trigger:function(t,e,n){var i=this.getEventTarget();return(n?i.trigger:i.triggerHandler).apply(i,arguments),this},addActions:function(t){if(!(t=t||this.actions||null))return!1;for(var e in t)this.addAction(e,t[e])},removeActions:function(t){if(!(t=t||this.actions||null))return!1;for(var e in t)this.removeAction(e,t[e])},addAction:function(t,e,n){n=n||this.priority,"string"==typeof e&&(e=this[e]),acf.addAction(t,e,n,this)},removeAction:function(t,e){acf.removeAction(t,this[e])},addFilters:function(t){if(!(t=t||this.filters||null))return!1;for(var e in t)this.addFilter(e,t[e])},addFilter:function(t,e,n){n=n||this.priority,"string"==typeof e&&(e=this[e]),acf.addFilter(t,e,n,this)},removeFilters:function(t){if(!(t=t||this.filters||null))return!1;for(var e in t)this.removeFilter(e,t[e])},removeFilter:function(t,e){acf.removeFilter(t,this[e])},$:function(t){return this.$el.find(t)},remove:function(){this.removeEvents(),this.removeActions(),this.removeFilters(),this.$el.remove()},setTimeout:function(t,e){return setTimeout(this.proxy(t),e)},time:function(){console.time(this.id||this.cid)},timeEnd:function(){console.timeEnd(this.id||this.cid)},show:function(){acf.show(this.$el)},hide:function(){acf.hide(this.$el)},proxy:function(t){return i.proxy(t,this)}}),t.extend=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)};return i.extend(n,e),n.prototype=Object.create(e.prototype),i.extend(n.prototype,t),n.prototype.constructor=n},acf.models={},acf.getInstance=function(t){return t.data("acf")},acf.getInstances=function(t){var e=[];return t.each(function(){e.push(acf.getInstance(i(this)))}),e}}(jQuery),function(e){acf.models.Popup=acf.Model.extend({data:{title:"",content:"",width:0,height:0,loading:!1},events:{'click [data-event="close"]':"onClickClose","click .acf-close-popup":"onClickClose"},setup:function(t){e.extend(this.data,t),this.$el=e(this.tmpl())},initialize:function(){this.render(),this.open()},tmpl:function(){return['<div id="acf-popup">','<div class="acf-popup-box acf-box">','<div class="title"><h3></h3><a href="#" class="acf-icon -cancel grey" data-event="close"></a></div>','<div class="inner"></div>','<div class="loading"><i class="acf-loading"></i></div>',"</div>",'<div class="bg" data-event="close"></div>',"</div>"].join("")},render:function(){var t=this.get("title"),e=this.get("content"),n=this.get("loading"),i=this.get("width"),o=this.get("height");this.title(t),this.content(e),i&&this.$(".acf-popup-box").css("width",i),o&&this.$(".acf-popup-box").css("min-height",o),this.loading(n),acf.doAction("append",this.$el)},update:function(t){this.data=acf.parseArgs(t,this.data),this.render()},title:function(t){this.$(".title:first h3").html(t)},content:function(t){this.$(".inner:first").html(t)},loading:function(t){var e=this.$(".loading:first");t?e.show():e.hide()},open:function(){e("body").append(this.$el)},close:function(){this.remove()},onClickClose:function(t,e){t.preventDefault(),this.close()}}),acf.newPopup=function(t){return new acf.models.Popup(t)}}(jQuery),function(i){acf.models.Modal=acf.Model.extend({data:{title:"",content:"",toolbar:""},events:{"click .acf-modal-close":"onClickClose"},setup:function(t){i.extend(this.data,t),this.$el=i(),this.render()},initialize:function(){this.open()},render:function(){var t=this.get("title"),e=this.get("content"),n=this.get("toolbar"),n=i(["<div>",'<div class="acf-modal">','<div class="acf-modal-title">',"<h2>"+t+"</h2>",'<button class="acf-modal-close" type="button"><span class="dashicons dashicons-no"></span></button>',"</div>",'<div class="acf-modal-content">'+e+"</div>",'<div class="acf-modal-toolbar">'+n+"</div>","</div>",'<div class="acf-modal-backdrop acf-modal-close"></div>',"</div>"].join(""));this.$el&&this.$el.replaceWith(n),this.$el=n,acf.doAction("append",n)},update:function(t){this.data=acf.parseArgs(t,this.data),this.render()},title:function(t){this.$(".acf-modal-title h2").html(t)},content:function(t){this.$(".acf-modal-content").html(t)},toolbar:function(t){this.$(".acf-modal-toolbar").html(t)},open:function(){i("body").append(this.$el)},close:function(){this.remove()},onClickClose:function(t,e){t.preventDefault(),this.close()}}),acf.newModal=function(t){return new acf.models.Modal(t)}}(jQuery),jQuery,new acf.Model({events:{"click .acf-panel-title":"onClick"},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},open:function(t){t.addClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-down")},close:function(t){t.removeClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-right")}}),function(e){var n=acf.Model.extend({data:{text:"",type:"",timeout:0,dismiss:!0,target:!1,close:function(){}},events:{"click .acf-notice-dismiss":"onClickClose"},tmpl:function(){return'<div class="acf-notice"></div>'},setup:function(t){e.extend(this.data,t),this.$el=e(this.tmpl())},initialize:function(){this.render(),this.show()},render:function(){this.type(this.get("type")),this.html("<p>"+this.get("text")+"</p>"),this.get("dismiss")&&(this.$el.append('<a href="#" class="acf-notice-dismiss acf-icon -cancel small"></a>'),this.$el.addClass("-dismiss"));var t=this.get("timeout");t&&this.away(t)},update:function(t){e.extend(this.data,t),this.initialize(),this.removeEvents(),this.addEvents()},show:function(){var t=this.get("target");t&&t.prepend(this.$el)},hide:function(){this.$el.remove()},away:function(t){this.setTimeout(function(){acf.remove(this.$el)},t)},type:function(t){var e=this.get("type");e&&this.$el.removeClass("-"+e),this.$el.addClass("-"+t),"error"==t&&this.$el.addClass("acf-error-message")},html:function(t){this.$el.html(acf.escHtml(t))},text:function(t){this.$("p").html(acf.escHtml(t))},onClickClose:function(t,e){t.preventDefault(),this.get("close").apply(this,arguments),this.remove()}});acf.newNotice=function(t){return new n(t="object"!=typeof t?{text:t}:t)};new acf.Model({wait:"prepare",priority:1,initialize:function(){var t=e(".acf-admin-notice");t.length&&e("h1:first").after(t)}})}(jQuery),function(u){acf.newTooltip=function(t){return void 0!==(t="object"!=typeof t?{text:t}:t).confirmRemove?(t.textConfirm=acf.__("Remove"),t.textCancel=acf.__("Cancel"),new n(t)):new(void 0!==t.confirm?n:e)(t)};var e=acf.Model.extend({data:{text:"",timeout:0,target:null},tmpl:function(){return'<div class="acf-tooltip"></div>'},setup:function(t){u.extend(this.data,t),this.$el=u(this.tmpl())},initialize:function(){this.render(),this.show(),this.position();var t=this.get("timeout");t&&setTimeout(u.proxy(this.fade,this),t)},update:function(t){u.extend(this.data,t),this.initialize()},render:function(){this.html(this.get("text"))},show:function(){u("body").append(this.$el)},hide:function(){this.$el.remove()},fade:function(){this.$el.addClass("acf-fade-up"),this.setTimeout(function(){this.remove()},250)},html:function(t){this.$el.html(t)},position:function(){var t,e,n,i,o,r,a,s,c=this.$el,l=this.get("target");l&&(c.removeClass("right left bottom top").css({top:0,left:0}),t=l.outerWidth(),e=l.outerHeight(),n=l.offset().top,i=l.offset().left,o=c.outerWidth(),s=n-(r=c.outerHeight())-(a=c.offset().top),(l=i+t/2-o/2)<10?(c.addClass("right"),l=i+t,s=n+e/2-r/2-a):l+o+10>u(window).width()?(c.addClass("left"),l=i-o,s=n+e/2-r/2-a):s-u(window).scrollTop()<10?(c.addClass("bottom"),s=n+e-a):c.addClass("top"),c.css({top:s,left:l}))}}),n=e.extend({data:{text:"",textConfirm:"",textCancel:"",target:null,targetConfirm:!0,confirm:function(){},cancel:function(){},context:!1},events:{'click [data-event="cancel"]':"onCancel",'click [data-event="confirm"]':"onConfirm"},addEvents:function(){acf.Model.prototype.addEvents.apply(this);var t=u(document),e=this.get("target");this.setTimeout(function(){this.on(t,"click","onCancel")}),this.get("targetConfirm")&&this.on(e,"click","onConfirm")},removeEvents:function(){acf.Model.prototype.removeEvents.apply(this);var t=u(document),e=this.get("target");this.off(t,"click"),this.off(e,"click")},render:function(){var t=[this.get("text")||acf.__("Are you sure?"),'<a href="#" data-event="confirm">'+(this.get("textConfirm")||acf.__("Yes"))+"</a>",'<a href="#" data-event="cancel">'+(this.get("textCancel")||acf.__("No"))+"</a>"].join(" ");this.html(t),this.$el.addClass("-confirm")},onCancel:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var n=this.get("cancel"),i=this.get("context")||this;n.apply(i,arguments),this.remove()},onConfirm:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var n=this.get("confirm"),i=this.get("context")||this;n.apply(i,arguments),this.remove()}});acf.models.Tooltip=e,acf.models.TooltipConfirm=n;new acf.Model({tooltip:!1,events:{"mouseenter .acf-js-tooltip":"showTitle","mouseup .acf-js-tooltip":"hideTitle","mouseleave .acf-js-tooltip":"hideTitle"},showTitle:function(t,e){var n=e.attr("title");n&&(e.attr("title",""),this.tooltip?this.tooltip.update({text:n,target:e}):this.tooltip=acf.newTooltip({text:n,target:e}))},hideTitle:function(t,e){this.tooltip.hide(),e.attr("title",this.tooltip.get("text"))}})}(jQuery);
1
+ !function(s,r){var c={};(window.acf=c).data={},c.get=function(t){return this.data[t]||null},c.has=function(t){return null!==this.get(t)},c.set=function(t,e){return this.data[t]=e,this};var n=0;c.uniqueId=function(t){var e=++n+"";return t?t+e:e},c.uniqueArray=function(t){return t.filter(function(t,e,n){return n.indexOf(t)===e})};var i="";c.uniqid=function(t,e){void 0===t&&(t="");function n(t,e){return e<(t=parseInt(t,10).toString(16)).length?t.slice(t.length-e):e>t.length?Array(e-t.length+1).join("0")+t:t}return i=i||Math.floor(123456789*Math.random()),i++,t=t,t+=n(parseInt((new Date).getTime()/1e3,10),8),t+=n(i,5),e&&(t+=(10*Math.random()).toFixed(8).toString()),t},c.strReplace=function(t,e,n){return n.split(t).join(e)},c.strCamelCase=function(t){t=t.match(/([a-zA-Z0-9]+)/g);return t?t.map(function(t,e){var n=t.charAt(0);return(0===e?n.toLowerCase():n.toUpperCase())+t.slice(1)}).join(""):""},c.strPascalCase=function(t){t=c.strCamelCase(t);return t.charAt(0).toUpperCase()+t.slice(1)},c.strSlugify=function(t){return c.strReplace("_","-",t.toLowerCase())},c.strSanitize=function(t){var e={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","ß":"s","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Ĉ":"C","ĉ":"c","Ċ":"C","ċ":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"D","đ":"d","Ē":"E","ē":"e","Ĕ":"E","ĕ":"e","Ė":"E","ė":"e","Ę":"E","ę":"e","Ě":"E","ě":"e","Ĝ":"G","ĝ":"g","Ğ":"G","ğ":"g","Ġ":"G","ġ":"g","Ģ":"G","ģ":"g","Ĥ":"H","ĥ":"h","Ħ":"H","ħ":"h","Ĩ":"I","ĩ":"i","Ī":"I","ī":"i","Ĭ":"I","ĭ":"i","Į":"I","į":"i","İ":"I","ı":"i","IJ":"IJ","ij":"ij","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","Ĺ":"L","ĺ":"l","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ŀ":"L","ŀ":"l","Ł":"l","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","ʼn":"n","Ō":"O","ō":"o","Ŏ":"O","ŏ":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ŗ":"R","ŗ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ŝ":"S","ŝ":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ŧ":"T","ŧ":"t","Ũ":"U","ũ":"u","Ū":"U","ū":"u","Ŭ":"U","ŭ":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","ſ":"s","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Ǎ":"A","ǎ":"a","Ǐ":"I","ǐ":"i","Ǒ":"O","ǒ":"o","Ǔ":"U","ǔ":"u","Ǖ":"U","ǖ":"u","Ǘ":"U","ǘ":"u","Ǚ":"U","ǚ":"u","Ǜ":"U","ǜ":"u","Ǻ":"A","ǻ":"a","Ǽ":"AE","ǽ":"ae","Ǿ":"O","ǿ":"o"," ":"_","'":"","?":"","/":"","\\":"",".":"",",":"","`":"",">":"","<":"",'"':"","[":"","]":"","|":"","{":"","}":"","(":"",")":""};return t=(t=t.replace(/\W/g,function(t){return e[t]!==r?e[t]:t})).toLowerCase()},c.strMatch=function(t,e){for(var n=0,i=Math.min(t.length,e.length),o=0;o<i&&t[o]===e[o];o++)n++;return n},c.strEscape=function(t){var e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return(""+t).replace(/[&<>"']/g,function(t){return e[t]})},c.strUnescape=function(t){var e={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"};return(""+t).replace(/&amp;|&lt;|&gt;|&quot;|&#39;/g,function(t){return e[t]})},c.escAttr=c.strEscape,c.escHtml=function(t){return(""+t).replace(/<script|<\/script/g,function(t){return c.strEscape(t)})},c.decode=function(t){return s("<textarea/>").html(t).text()},c.parseArgs=function(t,e){return s.extend({},e="object"!=typeof e?{}:e,t="object"!=typeof t?{}:t)},window.acfL10n==r&&(acfL10n={}),c.__=function(t){return acfL10n[t]||t},c._x=function(t,e){return acfL10n[t+"."+e]||acfL10n[t]||t},c._n=function(t,e,n){return 1==n?c.__(t):c.__(e)},c.isArray=function(t){return Array.isArray(t)},c.isObject=function(t){return"object"==typeof t};c.serialize=function(t,e){var n={},i=c.serializeArray(t);e!==r&&(i=i.filter(function(t){return 0===t.name.indexOf(e)}).map(function(t){return t.name=t.name.slice(e.length),t}));for(var o=0;o<i.length;o++)!function(t,e,n){var i=(e=e.replace("[]","[%%index%%]")).match(/([^\[\]])+/g);if(i)for(var o=i.length,r=t,a=0;a<o;a++){var s=String(i[a]);a==o-1?"%%index%%"===s?r.push(n):r[s]=n:("%%index%%"===i[a+1]?c.isArray(r[s])||(r[s]=[]):c.isObject(r[s])||(r[s]={}),r=r[s])}}(n,i[o].name,i[o].value);return n},c.serializeArray=function(t){return t.find("select, textarea, input").serializeArray()},c.serializeForAjax=function(t){var e={};return c.serializeArray(t).map(function(t){"[]"===t.name.slice(-2)?(e[t.name]=e[t.name]||[],e[t.name].push(t.value)):e[t.name]=t.value}),e},c.addAction=function(t,e,n,i){return c.hooks.addAction.apply(this,arguments),this},c.removeAction=function(t,e){return c.hooks.removeAction.apply(this,arguments),this};var e={};c.doAction=function(t){return e[t]=1,c.hooks.doAction.apply(this,arguments),e[t]=0,this},c.doingAction=function(t){return 1===e[t]},c.didAction=function(t){return e[t]!==r},c.currentAction=function(){for(var t in e)if(e[t])return t;return!1},c.addFilter=function(t){return c.hooks.addFilter.apply(this,arguments),this},c.removeFilter=function(t){return c.hooks.removeFilter.apply(this,arguments),this},c.applyFilters=function(t){return c.hooks.applyFilters.apply(this,arguments)},c.arrayArgs=function(t){return Array.prototype.slice.call(t)};try{var o=JSON.parse(localStorage.getItem("acf"))||{}}catch(t){o={}}function a(t){return t="this."===t.substr(0,5)?t.substr(5)+"-"+c.get("post_id"):t}c.getPreference=function(t){return t=a(t),o[t]||null},c.setPreference=function(t,e){t=a(t),null===e?delete o[t]:o[t]=e,localStorage.setItem("acf",JSON.stringify(o))},c.removePreference=function(t){c.setPreference(t,null)},c.remove=function(t){t instanceof jQuery&&(t={target:t}),t=c.parseArgs(t,{target:!1,endHeight:0,complete:function(){}}),c.doAction("remove",t.target),(t.target.is("tr")?u:l)(t)};var l=function(t){var e=t.target,n=e.height(),i=e.width(),o=e.css("margin"),r=e.outerHeight(!0),a=e.attr("style")+"";e.wrap('<div class="acf-temp-remove" style="height:'+r+'px"></div>');var s=e.parent();e.css({height:n,width:i,margin:o,position:"absolute"}),setTimeout(function(){s.css({opacity:0,height:t.endHeight})},50),setTimeout(function(){e.attr("style",a),s.remove(),t.complete()},301)},u=function(t){var e=t.target,n=e.height(),i=e.children().length,o=s('<td class="acf-temp-remove" style="padding:0; height:'+n+'px" colspan="'+i+'"></td>');e.addClass("acf-remove-element"),setTimeout(function(){e.html(o)},251),setTimeout(function(){e.removeClass("acf-remove-element"),o.css({height:t.endHeight})},300),setTimeout(function(){e.remove(),t.complete()},451)};c.duplicate=function(t){t instanceof jQuery&&(t={target:t}),(t=c.parseArgs(t,{target:!1,search:"",replace:"",rename:!0,before:function(t){},after:function(t,e){},append:function(t,e){t.after(e)}})).target=t.target||t.$el;var e=t.target;t.search=t.search||e.attr("data-id"),t.replace=t.replace||c.uniqid(),t.before(e),c.doAction("before_duplicate",e);var n=e.clone();return t.rename&&c.rename({target:n,search:t.search,replace:t.replace,replacer:"function"==typeof t.rename?t.rename:null}),n.removeClass("acf-clone"),n.find(".ui-sortable").removeClass("ui-sortable"),t.after(e,n),c.doAction("after_duplicate",e,n),t.append(e,n),c.doAction("duplicate",e,n),c.doAction("append",n),n},c.rename=function(i){i instanceof jQuery&&(i={target:i});var t=(i=c.parseArgs(i,{target:!1,destructive:!1,search:"",replace:"",replacer:null})).target;i.search||(i.search=t.attr("data-id")),i.replace||(i.replace=c.uniqid("acf")),i.replacer||(i.replacer=function(t,e,n,i){return e.replace(n,i)});function e(n){return function(t,e){return i.replacer(n,e,i.search,i.replace)}}var n;return i.destructive?(n=c.strReplace(i.search,i.replace,t.outerHTML()),t.replaceWith(n)):(t.attr("data-id",i.replace),t.find('[id*="'+i.search+'"]').attr("id",e("id")),t.find('[for*="'+i.search+'"]').attr("for",e("for")),t.find('[name*="'+i.search+'"]').attr("name",e("name"))),t},c.prepareForAjax=function(t){return t.nonce=c.get("nonce"),t.post_id=c.get("post_id"),c.has("language")&&(t.lang=c.get("language")),t=c.applyFilters("prepare_for_ajax",t)},c.startButtonLoading=function(t){t.prop("disabled",!0),t.after(' <i class="acf-loading"></i>')},c.stopButtonLoading=function(t){t.prop("disabled",!1),t.next(".acf-loading").remove()},c.showLoading=function(t){t.append('<div class="acf-loading-overlay"><i class="acf-loading"></i></div>')},c.hideLoading=function(t){t.children(".acf-loading-overlay").remove()},c.updateUserSetting=function(t,e){e={action:"acf/ajax/user_setting",name:t,value:e};s.ajax({url:c.get("ajaxurl"),data:c.prepareForAjax(e),type:"post",dataType:"html"})},c.val=function(t,e,n){var i=t.val();return e!==i&&(t.val(e),t.is("select")&&null===t.val()?(t.val(i),!1):(!0!==n&&t.trigger("change"),!0))},c.show=function(t,e){return e&&c.unlock(t,"hidden",e),!c.isLocked(t,"hidden")&&(!!t.hasClass("acf-hidden")&&(t.removeClass("acf-hidden"),!0))},c.hide=function(t,e){return e&&c.lock(t,"hidden",e),!t.hasClass("acf-hidden")&&(t.addClass("acf-hidden"),!0)},c.isHidden=function(t){return t.hasClass("acf-hidden")},c.isVisible=function(t){return!c.isHidden(t)};function f(t,e){return!t.hasClass("acf-disabled")&&(e&&c.unlock(t,"disabled",e),!c.isLocked(t,"disabled")&&(!!t.prop("disabled")&&(t.prop("disabled",!1),!0)))}c.enable=function(t,e){if(t.attr("name"))return f(t,e);var n=!1;return t.find("[name]").each(function(){f(s(this),e)&&(n=!0)}),n};function d(t,e){return e&&c.lock(t,"disabled",e),!t.prop("disabled")&&(t.prop("disabled",!0),!0)}c.disable=function(t,e){if(t.attr("name"))return d(t,e);var n=!1;return t.find("[name]").each(function(){d(s(this),e)&&(n=!0)}),n},c.isset=function(t){for(var e=1;e<arguments.length;e++){if(!t||!t.hasOwnProperty(arguments[e]))return!1;t=t[arguments[e]]}return!0},c.isget=function(t){for(var e=1;e<arguments.length;e++){if(!t||!t.hasOwnProperty(arguments[e]))return null;t=t[arguments[e]]}return t},c.getFileInputData=function(t,e){var n=t.val();if(!n)return!1;var i={url:n},o=!!t[0].files.length&&c.isget(t[0].files,0);o?(i.size=o.size,i.type=o.type,-1<o.type.indexOf("image")?(n=window.URL||window.webkitURL,(t=new Image).onload=function(){i.width=this.width,i.height=this.height,e(i)},t.src=n.createObjectURL(o)):e(i)):e(i)},c.isAjaxSuccess=function(t){return t&&t.success},c.getAjaxMessage=function(t){return c.isget(t,"data","message")},c.getAjaxError=function(t){return c.isget(t,"data","error")},c.getXhrError=function(t){return t.responseJSON&&t.responseJSON.message?t.responseJSON.message:t.statusText||""},c.renderSelect=function(t,e){var n=t.val(),o=[],r=function(t){var i="";return t.map(function(t){var e=t.text||t.label||"",n=t.id||t.value||"";o.push(n),t.children?i+='<optgroup label="'+c.escAttr(e)+'">'+r(t.children)+"</optgroup>":i+='<option value="'+c.escAttr(n)+'"'+(t.disabled?' disabled="disabled"':"")+">"+c.strEscape(e)+"</option>"}),i};return t.html(r(e)),-1<o.indexOf(n)&&t.val(n),t.val()};function h(t,e){return t.data("acf-lock-"+e)||[]}function p(t,e,n){t.data("acf-lock-"+e,n)}var g,v,m,y;function w(){g.forEach(function(t){c.isInView(t.el)&&(t.callback.apply(this),y(t.id))})}c.lock=function(t,e,n){var i=h(t,e);i.indexOf(n)<0&&(i.push(n),p(t,e,i))},c.unlock=function(t,e,n){var i=h(t,e),n=i.indexOf(n);return-1<n&&(i.splice(n,1),p(t,e,i)),0===i.length},c.isLocked=function(t,e){return 0<h(t,e).length},c.isGutenberg=function(){return!!(window.wp&&wp.data&&wp.data.select&&wp.data.select("core/editor"))},c.objectToArray=function(e){return Object.keys(e).map(function(t){return e[t]})},c.debounce=function(n,i){var o;return function(){var t=this,e=arguments;clearTimeout(o),o=setTimeout(function(){n.apply(t,e)},i)}},c.throttle=function(t,e){var n=!1;return function(){n||(n=!0,setTimeout(function(){n=!1},e),t.apply(this,arguments))}},c.isInView=function(t){t=(t=t instanceof jQuery?t[0]:t).getBoundingClientRect();return t.top!==t.bottom&&0<=t.top&&0<=t.left&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)},c.onceInView=(g=[],v=0,m=c.debounce(w,300),y=function(e){(g=g.filter(function(t){return t.id!==e})).length||s(window).off("scroll resize",m).off("acfrefresh orientationchange",w)},function(t,e){t instanceof jQuery&&(t=t[0]),c.isInView(t)?e.apply(this):(t=t,e=e,g.length||s(window).on("scroll resize",m).on("acfrefresh orientationchange",w),g.push({id:v++,el:t,callback:e}))}),c.once=function(t){var e=0;return function(){return 0<e++?t=r:t.apply(this,arguments)}},c.focusAttention=function(t){var e=1e3;t.addClass("acf-attention -focused");c.isInView(t)||(s("body, html").animate({scrollTop:t.offset().top-s(window).height()/2},500),e+=500);setTimeout(function(){t.removeClass("-focused"),setTimeout(function(){t.removeClass("acf-attention")},250)},e)},c.onFocus=function(e,n){function t(){o=!0,setTimeout(function(){o=!1},1),a(!0)}function i(){o||a(!1)}var o=!1,r=!1,a=function(t){r!==t&&(t?(s(document).on("click",i),e.on("blur","input, select, textarea",i)):(s(document).off("click",i),e.off("blur","input, select, textarea",i)),n(r=t))};e.on("click",t),e.on("focus","input, select, textarea",t)},s.fn.exists=function(){return 0<s(this).length},s.fn.outerHTML=function(){return s(this).get(0).outerHTML},Array.prototype.indexOf||(Array.prototype.indexOf=function(t){return s.inArray(t,this)}),c.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},c.refresh=c.debounce(function(){s(window).trigger("acfrefresh"),c.doAction("refresh")},0),s(document).ready(function(){c.doAction("ready")}),s(window).on("load",function(){setTimeout(function(){c.doAction("load")})}),s(window).on("beforeunload",function(){c.doAction("unload")}),s(window).on("resize",function(){c.doAction("resize")}),s(document).on("sortstart",function(t,e){c.doAction("sortstart",e.item,e.placeholder)}),s(document).on("sortstop",function(t,e){c.doAction("sortstop",e.item,e.placeholder)})}(jQuery),function(){"use strict";acf.hooks=new function(){var o={removeFilter:function(t,e){"string"==typeof t&&n("filters",t,e);return o},applyFilters:function(){var t=Array.prototype.slice.call(arguments),e=t.shift();return"string"!=typeof e?o:i("filters",e,t)},addFilter:function(t,e,n,i){"string"==typeof t&&"function"==typeof e&&(n=parseInt(n||10,10),r("filters",t,e,n,i));return o},removeAction:function(t,e){"string"==typeof t&&n("actions",t,e);return o},doAction:function(){var t=Array.prototype.slice.call(arguments),e=t.shift();"string"==typeof e&&i("actions",e,t);return o},addAction:function(t,e,n,i){"string"==typeof t&&"function"==typeof e&&(n=parseInt(n||10,10),r("actions",t,e,n,i));return o},storage:function(){return s}},s={actions:{},filters:{}};function n(t,e,n,i){if(s[t][e])if(n){var o,r=s[t][e];if(i)for(o=r.length;o--;){var a=r[o];a.callback===n&&a.context===i&&r.splice(o,1)}else for(o=r.length;o--;)r[o].callback===n&&r.splice(o,1)}else s[t][e]=[]}function r(t,e,n,i,o){i={callback:n,priority:i,context:o},o=(o=s[t][e])?(o.push(i),function(t){for(var e,n,i,o=1,r=t.length;o<r;o++){for(e=t[o],n=o;(i=t[n-1])&&i.priority>e.priority;)t[n]=t[n-1],--n;t[n]=e}return t}(o)):[i];s[t][e]=o}function i(t,e,n){var i=s[t][e];if(!i)return"filters"===t&&n[0];var o=0,r=i.length;if("filters"===t)for(;o<r;o++)n[0]=i[o].callback.apply(i[o].context,n);else for(;o<r;o++)i[o].callback.apply(i[o].context,n);return"filters"!==t||n[0]}return o}}(window),function(i){var o=/^(\S+)\s*(.*)$/,t=acf.Model=function(){this.cid=acf.uniqueId("acf"),this.data=i.extend(!0,{},this.data),this.setup.apply(this,arguments),this.$el&&!this.$el.data("acf")&&this.$el.data("acf",this);function t(){this.initialize(),this.addEvents(),this.addActions(),this.addFilters()}this.wait&&!acf.didAction(this.wait)?this.addAction(this.wait,t):t.apply(this)};i.extend(t.prototype,{id:"",cid:"",$el:null,data:{},busy:!1,changed:!1,events:{},actions:{},filters:{},eventScope:"",wait:!1,priority:10,get:function(t){return this.data[t]},has:function(t){return null!=this.get(t)},set:function(t,e,n){var i=this.get(t);return i==e||(this.data[t]=e,n||(this.changed=!0,this.trigger("changed:"+t,[e,i]),this.trigger("changed",[t,e,i]))),this},inherit:function(t){return t instanceof jQuery&&(t=t.data()),i.extend(this.data,t),this},prop:function(){return this.$el.prop.apply(this.$el,arguments)},setup:function(t){i.extend(this,t)},initialize:function(){},addElements:function(t){if(!(t=t||this.elements||null)||!Object.keys(t).length)return!1;for(var e in t)this.addElement(e,t[e])},addElement:function(t,e){this["$"+t]=this.$(e)},addEvents:function(t){if(!(t=t||this.events||null))return!1;for(var e in t){var n=e.match(o);this.on(n[1],n[2],t[e])}},removeEvents:function(t){if(!(t=t||this.events||null))return!1;for(var e in t){var n=e.match(o);this.off(n[1],n[2],t[e])}},getEventTarget:function(t,e){return t||this.$el||i(document)},validateEvent:function(t){return!this.eventScope||i(t.target).closest(this.eventScope).is(this.$el)},proxyEvent:function(n){return this.proxy(function(t){var e;this.validateEvent(t)&&(e=acf.arrayArgs(arguments).slice(1),e=[t,i(t.currentTarget)].concat(e),n.apply(this,e))})},on:function(t,e,n,i){var o,r,e=t instanceof jQuery?i?(a=t,o=e,r=n,i):(a=t,o=e,n):n?(o=t,r=e,n):(o=t,e),a=this.getEventTarget(a);"string"==typeof e&&(e=this.proxyEvent(this[e])),o=o+"."+this.cid,a.on.apply(a,r?[o,r,e]:[o,e])},off:function(t,e,n){var i,o,r;t instanceof jQuery?n?(i=t,o=e,r=n):(i=t,o=e):e?(o=t,r=e):o=t,i=this.getEventTarget(i),o=o+"."+this.cid,i.off.apply(i,r?[o,r]:[o])},trigger:function(t,e,n){var i=this.getEventTarget();return(n?i.trigger:i.triggerHandler).apply(i,arguments),this},addActions:function(t){if(!(t=t||this.actions||null))return!1;for(var e in t)this.addAction(e,t[e])},removeActions:function(t){if(!(t=t||this.actions||null))return!1;for(var e in t)this.removeAction(e,t[e])},addAction:function(t,e,n){n=n||this.priority,"string"==typeof e&&(e=this[e]),acf.addAction(t,e,n,this)},removeAction:function(t,e){acf.removeAction(t,this[e])},addFilters:function(t){if(!(t=t||this.filters||null))return!1;for(var e in t)this.addFilter(e,t[e])},addFilter:function(t,e,n){n=n||this.priority,"string"==typeof e&&(e=this[e]),acf.addFilter(t,e,n,this)},removeFilters:function(t){if(!(t=t||this.filters||null))return!1;for(var e in t)this.removeFilter(e,t[e])},removeFilter:function(t,e){acf.removeFilter(t,this[e])},$:function(t){return this.$el.find(t)},remove:function(){this.removeEvents(),this.removeActions(),this.removeFilters(),this.$el.remove()},setTimeout:function(t,e){return setTimeout(this.proxy(t),e)},time:function(){console.time(this.id||this.cid)},timeEnd:function(){console.timeEnd(this.id||this.cid)},show:function(){acf.show(this.$el)},hide:function(){acf.hide(this.$el)},proxy:function(t){return i.proxy(t,this)}}),t.extend=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)};return i.extend(n,e),n.prototype=Object.create(e.prototype),i.extend(n.prototype,t),n.prototype.constructor=n},acf.models={},acf.getInstance=function(t){return t.data("acf")},acf.getInstances=function(t){var e=[];return t.each(function(){e.push(acf.getInstance(i(this)))}),e}}(jQuery),function(e){acf.models.Popup=acf.Model.extend({data:{title:"",content:"",width:0,height:0,loading:!1},events:{'click [data-event="close"]':"onClickClose","click .acf-close-popup":"onClickClose"},setup:function(t){e.extend(this.data,t),this.$el=e(this.tmpl())},initialize:function(){this.render(),this.open()},tmpl:function(){return['<div id="acf-popup">','<div class="acf-popup-box acf-box">','<div class="title"><h3></h3><a href="#" class="acf-icon -cancel grey" data-event="close"></a></div>','<div class="inner"></div>','<div class="loading"><i class="acf-loading"></i></div>',"</div>",'<div class="bg" data-event="close"></div>',"</div>"].join("")},render:function(){var t=this.get("title"),e=this.get("content"),n=this.get("loading"),i=this.get("width"),o=this.get("height");this.title(t),this.content(e),i&&this.$(".acf-popup-box").css("width",i),o&&this.$(".acf-popup-box").css("min-height",o),this.loading(n),acf.doAction("append",this.$el)},update:function(t){this.data=acf.parseArgs(t,this.data),this.render()},title:function(t){this.$(".title:first h3").html(t)},content:function(t){this.$(".inner:first").html(t)},loading:function(t){var e=this.$(".loading:first");t?e.show():e.hide()},open:function(){e("body").append(this.$el)},close:function(){this.remove()},onClickClose:function(t,e){t.preventDefault(),this.close()}}),acf.newPopup=function(t){return new acf.models.Popup(t)}}(jQuery),function(i){acf.models.Modal=acf.Model.extend({data:{title:"",content:"",toolbar:""},events:{"click .acf-modal-close":"onClickClose"},setup:function(t){i.extend(this.data,t),this.$el=i(),this.render()},initialize:function(){this.open()},render:function(){var t=this.get("title"),e=this.get("content"),n=this.get("toolbar"),n=i(["<div>",'<div class="acf-modal">','<div class="acf-modal-title">',"<h2>"+t+"</h2>",'<button class="acf-modal-close" type="button"><span class="dashicons dashicons-no"></span></button>',"</div>",'<div class="acf-modal-content">'+e+"</div>",'<div class="acf-modal-toolbar">'+n+"</div>","</div>",'<div class="acf-modal-backdrop acf-modal-close"></div>',"</div>"].join(""));this.$el&&this.$el.replaceWith(n),this.$el=n,acf.doAction("append",n)},update:function(t){this.data=acf.parseArgs(t,this.data),this.render()},title:function(t){this.$(".acf-modal-title h2").html(t)},content:function(t){this.$(".acf-modal-content").html(t)},toolbar:function(t){this.$(".acf-modal-toolbar").html(t)},open:function(){i("body").append(this.$el)},close:function(){this.remove()},onClickClose:function(t,e){t.preventDefault(),this.close()}}),acf.newModal=function(t){return new acf.models.Modal(t)}}(jQuery),jQuery,new acf.Model({events:{"click .acf-panel-title":"onClick"},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},open:function(t){t.addClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-down")},close:function(t){t.removeClass("-open"),t.find(".acf-panel-title i").attr("class","dashicons dashicons-arrow-right")}}),function(e){var n=acf.Model.extend({data:{text:"",type:"",timeout:0,dismiss:!0,target:!1,close:function(){}},events:{"click .acf-notice-dismiss":"onClickClose"},tmpl:function(){return'<div class="acf-notice"></div>'},setup:function(t){e.extend(this.data,t),this.$el=e(this.tmpl())},initialize:function(){this.render(),this.show()},render:function(){this.type(this.get("type")),this.html("<p>"+this.get("text")+"</p>"),this.get("dismiss")&&(this.$el.append('<a href="#" class="acf-notice-dismiss acf-icon -cancel small"></a>'),this.$el.addClass("-dismiss"));var t=this.get("timeout");t&&this.away(t)},update:function(t){e.extend(this.data,t),this.initialize(),this.removeEvents(),this.addEvents()},show:function(){var t=this.get("target");t&&t.prepend(this.$el)},hide:function(){this.$el.remove()},away:function(t){this.setTimeout(function(){acf.remove(this.$el)},t)},type:function(t){var e=this.get("type");e&&this.$el.removeClass("-"+e),this.$el.addClass("-"+t),"error"==t&&this.$el.addClass("acf-error-message")},html:function(t){this.$el.html(acf.escHtml(t))},text:function(t){this.$("p").html(acf.escHtml(t))},onClickClose:function(t,e){t.preventDefault(),this.get("close").apply(this,arguments),this.remove()}});acf.newNotice=function(t){return new n(t="object"!=typeof t?{text:t}:t)};new acf.Model({wait:"prepare",priority:1,initialize:function(){var t=e(".acf-admin-notice");t.length&&e("h1:first").after(t)}})}(jQuery),function(u){acf.newTooltip=function(t){return void 0!==(t="object"!=typeof t?{text:t}:t).confirmRemove?(t.textConfirm=acf.__("Remove"),t.textCancel=acf.__("Cancel"),new n(t)):new(void 0!==t.confirm?n:e)(t)};var e=acf.Model.extend({data:{text:"",timeout:0,target:null},tmpl:function(){return'<div class="acf-tooltip"></div>'},setup:function(t){u.extend(this.data,t),this.$el=u(this.tmpl())},initialize:function(){this.render(),this.show(),this.position();var t=this.get("timeout");t&&setTimeout(u.proxy(this.fade,this),t)},update:function(t){u.extend(this.data,t),this.initialize()},render:function(){this.html(this.get("text"))},show:function(){u("body").append(this.$el)},hide:function(){this.$el.remove()},fade:function(){this.$el.addClass("acf-fade-up"),this.setTimeout(function(){this.remove()},250)},html:function(t){this.$el.html(t)},position:function(){var t,e,n,i,o,r,a,s,c=this.$el,l=this.get("target");l&&(c.removeClass("right left bottom top").css({top:0,left:0}),t=l.outerWidth(),e=l.outerHeight(),n=l.offset().top,i=l.offset().left,o=c.outerWidth(),s=n-(r=c.outerHeight())-(a=c.offset().top),(l=i+t/2-o/2)<10?(c.addClass("right"),l=i+t,s=n+e/2-r/2-a):l+o+10>u(window).width()?(c.addClass("left"),l=i-o,s=n+e/2-r/2-a):s-u(window).scrollTop()<10?(c.addClass("bottom"),s=n+e-a):c.addClass("top"),c.css({top:s,left:l}))}}),n=e.extend({data:{text:"",textConfirm:"",textCancel:"",target:null,targetConfirm:!0,confirm:function(){},cancel:function(){},context:!1},events:{'click [data-event="cancel"]':"onCancel",'click [data-event="confirm"]':"onConfirm"},addEvents:function(){acf.Model.prototype.addEvents.apply(this);var t=u(document),e=this.get("target");this.setTimeout(function(){this.on(t,"click","onCancel")}),this.get("targetConfirm")&&this.on(e,"click","onConfirm")},removeEvents:function(){acf.Model.prototype.removeEvents.apply(this);var t=u(document),e=this.get("target");this.off(t,"click"),this.off(e,"click")},render:function(){var t=[this.get("text")||acf.__("Are you sure?"),'<a href="#" data-event="confirm">'+(this.get("textConfirm")||acf.__("Yes"))+"</a>",'<a href="#" data-event="cancel">'+(this.get("textCancel")||acf.__("No"))+"</a>"].join(" ");this.html(t),this.$el.addClass("-confirm")},onCancel:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var n=this.get("cancel"),i=this.get("context")||this;n.apply(i,arguments),this.remove()},onConfirm:function(t,e){t.preventDefault(),t.stopImmediatePropagation();var n=this.get("confirm"),i=this.get("context")||this;n.apply(i,arguments),this.remove()}});acf.models.Tooltip=e,acf.models.TooltipConfirm=n;new acf.Model({tooltip:!1,events:{"mouseenter .acf-js-tooltip":"showTitle","mouseup .acf-js-tooltip":"hideTitle","mouseleave .acf-js-tooltip":"hideTitle"},showTitle:function(t,e){var n=e.attr("title");n&&(e.attr("title",""),this.tooltip?this.tooltip.update({text:n,target:e}):this.tooltip=acf.newTooltip({text:n,target:e}))},hideTitle:function(t,e){this.tooltip.hide(),e.attr("title",this.tooltip.get("text"))}})}(jQuery);
includes/admin/views/html-admin-navigation.php CHANGED
@@ -80,7 +80,7 @@ if( $tabs === false ) {
80
  } ?>
81
 
82
  <?php if ( ! defined( 'ACF_PRO' ) || ! ACF_PRO ) : ?>
83
- <a href="https://www.advancedcustomfields.com/pro/?utm_source=ACF%2BFree&utm_medium=insideplugin&utm_campaign=ACF%2Bupgrade" class="btn-upgrade">
84
  <img src="<?php echo acf_get_url('assets/images/icon-upgrade-pro.svg' ); ?>" />
85
  <p><?php _e('Upgrade to Pro', 'acf'); ?></p>
86
  </a>
80
  } ?>
81
 
82
  <?php if ( ! defined( 'ACF_PRO' ) || ! ACF_PRO ) : ?>
83
+ <a target="_blank" href="https://www.advancedcustomfields.com/pro/?utm_source=ACF%2BFree&utm_medium=insideplugin&utm_campaign=ACF%2Bupgrade" class="btn-upgrade">
84
  <img src="<?php echo acf_get_url('assets/images/icon-upgrade-pro.svg' ); ?>" />
85
  <p><?php _e('Upgrade to Pro', 'acf'); ?></p>
86
  </a>
includes/api/api-helpers.php CHANGED
@@ -3478,7 +3478,8 @@ function acf_validate_attachment( $attachment, $field, $context = 'prepare' ) {
3478
  // prepare
3479
  } elseif( $context == 'prepare' ) {
3480
 
3481
- $file['type'] = pathinfo($attachment['filename'], PATHINFO_EXTENSION);
 
3482
  $file['size'] = acf_maybe_get($attachment, 'filesizeInBytes', 0);
3483
  $file['width'] = acf_maybe_get($attachment, 'width', 0);
3484
  $file['height'] = acf_maybe_get($attachment, 'height', 0);
@@ -3487,7 +3488,8 @@ function acf_validate_attachment( $attachment, $field, $context = 'prepare' ) {
3487
  } else {
3488
 
3489
  $file = array_merge($file, $attachment);
3490
- $file['type'] = pathinfo($attachment['filename'], PATHINFO_EXTENSION);
 
3491
 
3492
  }
3493
 
3478
  // prepare
3479
  } elseif( $context == 'prepare' ) {
3480
 
3481
+ $use_path = isset($attachment['filename']) ? $attachment['filename'] : $attachment['url'];
3482
+ $file['type'] = pathinfo($use_path, PATHINFO_EXTENSION);
3483
  $file['size'] = acf_maybe_get($attachment, 'filesizeInBytes', 0);
3484
  $file['width'] = acf_maybe_get($attachment, 'width', 0);
3485
  $file['height'] = acf_maybe_get($attachment, 'height', 0);
3488
  } else {
3489
 
3490
  $file = array_merge($file, $attachment);
3491
+ $use_path = isset($attachment['filename']) ? $attachment['filename'] : $attachment['url'];
3492
+ $file['type'] = pathinfo($use_path, PATHINFO_EXTENSION);
3493
 
3494
  }
3495
 
includes/api/api-template.php CHANGED
@@ -1041,7 +1041,7 @@ function delete_field( $selector, $post_id = false ) {
1041
 
1042
 
1043
  // delete
1044
- return acf_delete_value( $post_id, $field );
1045
 
1046
  }
1047
 
1041
 
1042
 
1043
  // delete
1044
+ return $field ? acf_delete_value( $post_id, $field ) : false;
1045
 
1046
  }
1047
 
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: deliciousbrains, bradt, elliotcondon
3
  Tags: acf, fields, custom fields, meta, repeater
4
  Requires at least: 4.7
5
- Tested up to: 5.7
6
  Requires PHP: 5.6
7
- Stable tag: 5.9.8
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -66,6 +66,13 @@ From your WordPress dashboard
66
 
67
  == Changelog ==
68
 
 
 
 
 
 
 
 
69
  = 5.9.8 =
70
  *Release Date - 08 July 2021*
71
 
2
  Contributors: deliciousbrains, bradt, elliotcondon
3
  Tags: acf, fields, custom fields, meta, repeater
4
  Requires at least: 4.7
5
+ Tested up to: 5.8
6
  Requires PHP: 5.6
7
+ Stable tag: 5.9.9
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
66
 
67
  == Changelog ==
68
 
69
+ = 5.9.9 =
70
+ *Release Date - 20 July 2021*
71
+
72
+ * Fix - Fixed warning when deleting fields which don't exist
73
+ * Fix - Fixed issues with older browsers and the blocks JavaScript
74
+ * Fix - Fixed file size & file type validation for front end forms using the basic uploader
75
+
76
  = 5.9.8 =
77
  *Release Date - 08 July 2021*
78