593 lines
14 KiB
JavaScript
593 lines
14 KiB
JavaScript
(function($, undefined){
|
|
|
|
acf.screen = new acf.Model({
|
|
|
|
active: true,
|
|
|
|
xhr: false,
|
|
|
|
timeout: false,
|
|
|
|
wait: 'load',
|
|
|
|
events: {
|
|
'change #page_template': 'onChange',
|
|
'change #parent_id': 'onChange',
|
|
'change #post-formats-select': 'onChange',
|
|
'change .categorychecklist': 'onChange',
|
|
'change .tagsdiv': 'onChange',
|
|
'change .acf-taxonomy-field[data-save="1"]': 'onChange',
|
|
'change #product-type': 'onChange'
|
|
},
|
|
|
|
isPost: function(){
|
|
return acf.get('screen') === 'post';
|
|
},
|
|
|
|
isUser: function(){
|
|
return acf.get('screen') === 'user';
|
|
},
|
|
|
|
isTaxonomy: function(){
|
|
return acf.get('screen') === 'taxonomy';
|
|
},
|
|
|
|
isAttachment: function(){
|
|
return acf.get('screen') === 'attachment';
|
|
},
|
|
|
|
isNavMenu: function(){
|
|
return acf.get('screen') === 'nav_menu';
|
|
},
|
|
|
|
isWidget: function(){
|
|
return acf.get('screen') === 'widget';
|
|
},
|
|
|
|
isComment: function(){
|
|
return acf.get('screen') === 'comment';
|
|
},
|
|
|
|
getPageTemplate: function(){
|
|
var $el = $('#page_template');
|
|
return $el.length ? $el.val() : null;
|
|
},
|
|
|
|
getPageParent: function( e, $el ){
|
|
var $el = $('#parent_id');
|
|
return $el.length ? $el.val() : null;
|
|
},
|
|
|
|
getPageType: function( e, $el ){
|
|
return this.getPageParent() ? 'child' : 'parent';
|
|
},
|
|
|
|
getPostType: function(){
|
|
return $('#post_type').val();
|
|
},
|
|
|
|
getPostFormat: function( e, $el ){
|
|
var $el = $('#post-formats-select input:checked');
|
|
if( $el.length ) {
|
|
var val = $el.val();
|
|
return (val == '0') ? 'standard' : val;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
getPostCoreTerms: function(){
|
|
|
|
// vars
|
|
var terms = {};
|
|
|
|
// serialize WP taxonomy postboxes
|
|
var data = acf.serialize( $('.categorydiv, .tagsdiv') );
|
|
|
|
// use tax_input (tag, custom-taxonomy) when possible.
|
|
// this data is already formatted in taxonomy => [terms].
|
|
if( data.tax_input ) {
|
|
terms = data.tax_input;
|
|
}
|
|
|
|
// append "category" which uses a different name
|
|
if( data.post_category ) {
|
|
terms.category = data.post_category;
|
|
}
|
|
|
|
// convert any string values (tags) into array format
|
|
for( var tax in terms ) {
|
|
if( !acf.isArray(terms[tax]) ) {
|
|
terms[tax] = terms[tax].split(/,[\s]?/);
|
|
}
|
|
}
|
|
|
|
// return
|
|
return terms;
|
|
},
|
|
|
|
getPostTerms: function(){
|
|
|
|
// Get core terms.
|
|
var terms = this.getPostCoreTerms();
|
|
|
|
// loop over taxonomy fields and add their values
|
|
acf.getFields({type: 'taxonomy'}).map(function( field ){
|
|
|
|
// ignore fields that don't save
|
|
if( !field.get('save') ) {
|
|
return;
|
|
}
|
|
|
|
// vars
|
|
var val = field.val();
|
|
var tax = field.get('taxonomy');
|
|
|
|
// check val
|
|
if( val ) {
|
|
|
|
// ensure terms exists
|
|
terms[ tax ] = terms[ tax ] || [];
|
|
|
|
// ensure val is an array
|
|
val = acf.isArray(val) ? val : [val];
|
|
|
|
// append
|
|
terms[ tax ] = terms[ tax ].concat( val );
|
|
}
|
|
});
|
|
|
|
// add WC product type
|
|
if( (productType = this.getProductType()) !== null ) {
|
|
terms.product_type = [productType];
|
|
}
|
|
|
|
// remove duplicate values
|
|
for( var tax in terms ) {
|
|
terms[tax] = acf.uniqueArray(terms[tax]);
|
|
}
|
|
|
|
// return
|
|
return terms;
|
|
},
|
|
|
|
getProductType: function(){
|
|
var $el = $('#product-type');
|
|
return $el.length ? $el.val() : null;
|
|
},
|
|
|
|
check: function(){
|
|
|
|
// bail early if not for post
|
|
if( acf.get('screen') !== 'post' ) {
|
|
return;
|
|
}
|
|
|
|
// abort XHR if is already loading AJAX data
|
|
if( this.xhr ) {
|
|
this.xhr.abort();
|
|
}
|
|
|
|
// vars
|
|
var ajaxData = acf.parseArgs(this.data, {
|
|
action: 'acf/ajax/check_screen',
|
|
screen: acf.get('screen'),
|
|
exists: []
|
|
});
|
|
|
|
// post id
|
|
if( this.isPost() ) {
|
|
ajaxData.post_id = acf.get('post_id');
|
|
}
|
|
|
|
// post type
|
|
if( (postType = this.getPostType()) !== null ) {
|
|
ajaxData.post_type = postType;
|
|
}
|
|
|
|
// page template
|
|
if( (pageTemplate = this.getPageTemplate()) !== null ) {
|
|
ajaxData.page_template = pageTemplate;
|
|
}
|
|
|
|
// page parent
|
|
if( (pageParent = this.getPageParent()) !== null ) {
|
|
ajaxData.page_parent = pageParent;
|
|
}
|
|
|
|
// page type
|
|
if( (pageType = this.getPageType()) !== null ) {
|
|
ajaxData.page_type = pageType;
|
|
}
|
|
|
|
// post format
|
|
if( (postFormat = this.getPostFormat()) !== null ) {
|
|
ajaxData.post_format = postFormat;
|
|
}
|
|
|
|
// post terms
|
|
if( (postTerms = this.getPostTerms()) !== null ) {
|
|
ajaxData.post_terms = postTerms;
|
|
}
|
|
|
|
// add array of existing postboxes to increase performance and reduce JSON HTML
|
|
acf.getPostboxes().map(function( postbox ){
|
|
ajaxData.exists.push( postbox.get('key') );
|
|
});
|
|
|
|
// filter
|
|
ajaxData = acf.applyFilters('check_screen_args', ajaxData);
|
|
|
|
// success
|
|
var onSuccess = function( json ){
|
|
|
|
// Check success.
|
|
if( acf.isAjaxSuccess(json) ) {
|
|
|
|
// Render post screen.
|
|
if( acf.get('screen') == 'post' ) {
|
|
this.renderPostScreen( json.data );
|
|
|
|
// Render user screen.
|
|
} else if( acf.get('screen') == 'user' ) {
|
|
this.renderUserScreen( json.data );
|
|
}
|
|
}
|
|
|
|
// action
|
|
acf.doAction('check_screen_complete', json.data, ajaxData);
|
|
};
|
|
|
|
// ajax
|
|
this.xhr = $.ajax({
|
|
url: acf.get('ajaxurl'),
|
|
data: acf.prepareForAjax( ajaxData ),
|
|
type: 'post',
|
|
dataType: 'json',
|
|
context: this,
|
|
success: onSuccess
|
|
});
|
|
},
|
|
|
|
onChange: function( e, $el ){
|
|
this.setTimeout(this.check, 1);
|
|
},
|
|
|
|
renderPostScreen: function( data ){
|
|
|
|
// vars
|
|
var visible = [];
|
|
|
|
// Helper function to copy events
|
|
var copyEvents = function( $from, $to ){
|
|
var events = $._data($from[0]).events;
|
|
for( var type in events ) {
|
|
for( var i = 0; i < events[type].length; i++ ) {
|
|
$to.on( type, events[type][i].handler );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper function to sort metabox.
|
|
var sortMetabox = function( id, ids ){
|
|
|
|
// Find position of id within ids.
|
|
var index = ids.indexOf( id );
|
|
|
|
// Bail early if index not found.
|
|
if( index == -1 ) {
|
|
return false;
|
|
}
|
|
|
|
// Loop over metaboxes behind (in reverse order).
|
|
for( var i = index-1; i >= 0; i-- ) {
|
|
if( $('#'+ids[i]).length ) {
|
|
return $('#'+ids[i]).after( $('#'+id) );
|
|
}
|
|
}
|
|
|
|
// Loop over metaboxes infront.
|
|
for( var i = index+1; i < ids.length; i++ ) {
|
|
if( $('#'+ids[i]).length ) {
|
|
return $('#'+ids[i]).before( $('#'+id) );
|
|
}
|
|
}
|
|
|
|
// Return false if not sorted.
|
|
return false;
|
|
};
|
|
|
|
// Show these postboxes.
|
|
data.results.map(function( result, i ){
|
|
|
|
// vars
|
|
var postbox = acf.getPostbox( result.id );
|
|
|
|
// Create postbox if doesn't exist.
|
|
if( !postbox ) {
|
|
|
|
// Create it.
|
|
var $postbox = $([
|
|
'<div id="' + result.id + '" class="postbox">',
|
|
'<button type="button" class="handlediv" aria-expanded="false">',
|
|
'<span class="screen-reader-text">Toggle panel: ' + result.title + '</span>',
|
|
'<span class="toggle-indicator" aria-hidden="true"></span>',
|
|
'</button>',
|
|
'<h2 class="hndle ui-sortable-handle">',
|
|
'<span>' + result.title + '</span>',
|
|
'</h2>',
|
|
'<div class="inside">',
|
|
result.html,
|
|
'</div>',
|
|
'</div>'
|
|
].join(''));
|
|
|
|
// Create new hide toggle.
|
|
if( $('#adv-settings').length ) {
|
|
var $prefs = $('#adv-settings .metabox-prefs');
|
|
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.
|
|
copyEvents( $prefs.find('input').first(), $label.find('input') );
|
|
|
|
// Append hide label
|
|
$prefs.append( $label );
|
|
}
|
|
|
|
// Append metabox to the bottom of "side-sortables".
|
|
if( result.position === 'side' ) {
|
|
$('#' + result.position + '-sortables').append( $postbox );
|
|
|
|
// Prepend metabox to the top of "normal-sortbables".
|
|
} else {
|
|
$('#' + result.position + '-sortables').prepend( $postbox );
|
|
}
|
|
|
|
// Position metabox amongst existing ACF metaboxes within the same location.
|
|
var order = [];
|
|
data.results.map(function( _result ){
|
|
if( result.position === _result.position && $('#' + result.position + '-sortables #' + _result.id).length ) {
|
|
order.push( _result.id );
|
|
}
|
|
});
|
|
sortMetabox(result.id, order)
|
|
|
|
// Check 'sorted' for user preference.
|
|
if( data.sorted ) {
|
|
|
|
// Loop over each position (acf_after_title, side, normal).
|
|
for( var position in data.sorted ) {
|
|
|
|
// Explode string into array of ids.
|
|
var order = data.sorted[position].split(',');
|
|
|
|
// Position metabox relative to order.
|
|
if( sortMetabox(result.id, order) ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy default WP events onto metabox.
|
|
var $submitdiv = $('#submitdiv');
|
|
if( $('#submitdiv').length ) {
|
|
copyEvents( $submitdiv.children('.handlediv'), $postbox.children('.handlediv') );
|
|
copyEvents( $submitdiv.children('.hndle'), $postbox.children('.hndle') );
|
|
}
|
|
|
|
// Initalize it (modifies HTML).
|
|
postbox = acf.newPostbox( result );
|
|
|
|
// Trigger action.
|
|
acf.doAction('append', $postbox);
|
|
acf.doAction('append_postbox', postbox);
|
|
}
|
|
|
|
// show postbox
|
|
postbox.showEnable();
|
|
|
|
// Do action.
|
|
acf.doAction('show_postbox', postbox);
|
|
|
|
// append
|
|
visible.push( result.id );
|
|
});
|
|
|
|
// Hide these postboxes.
|
|
acf.getPostboxes().map(function( postbox ){
|
|
if( visible.indexOf( postbox.get('id') ) === -1 ) {
|
|
postbox.hideDisable();
|
|
|
|
// Do action.
|
|
acf.doAction('hide_postbox', postbox);
|
|
}
|
|
});
|
|
|
|
// Update style.
|
|
$('#acf-style').html( data.style );
|
|
},
|
|
|
|
renderUserScreen: function( json ){
|
|
|
|
}
|
|
});
|
|
|
|
/**
|
|
* gutenScreen
|
|
*
|
|
* Adds compatibility with the Gutenberg edit screen.
|
|
*
|
|
* @date 11/12/18
|
|
* @since 5.8.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
var gutenScreen = new acf.Model({
|
|
|
|
// Wait until load to avoid 'core' issues when loading taxonomies.
|
|
wait: 'load',
|
|
|
|
initialize: function(){
|
|
|
|
// Bail early if not Gutenberg.
|
|
if( !acf.isGutenberg() ) {
|
|
return;
|
|
}
|
|
|
|
// Listen for changes.
|
|
wp.data.subscribe(this.proxy(this.onChange));
|
|
|
|
// Customize "acf.screen.get" functions.
|
|
acf.screen.getPageTemplate = this.getPageTemplate;
|
|
acf.screen.getPageParent = this.getPageParent;
|
|
acf.screen.getPostType = this.getPostType;
|
|
acf.screen.getPostFormat = this.getPostFormat;
|
|
acf.screen.getPostCoreTerms = this.getPostCoreTerms;
|
|
|
|
// Disable unload
|
|
acf.unload.disable();
|
|
|
|
// Add actions.
|
|
//this.addAction( 'append_postbox', acf.screen.refreshAvailableMetaBoxesPerLocation );
|
|
},
|
|
|
|
onChange: function(){
|
|
|
|
// Get edits.
|
|
var edits = wp.data.select( 'core/editor' ).getPostEdits();
|
|
|
|
// Check specific attributes.
|
|
var attributes = [
|
|
'template',
|
|
'parent',
|
|
'format'
|
|
];
|
|
|
|
// Append taxonomy attributes.
|
|
var taxonomies = wp.data.select( 'core' ).getTaxonomies() || [];
|
|
taxonomies.map(function( taxonomy ){
|
|
attributes.push( taxonomy.rest_base );
|
|
});
|
|
|
|
// Filter out attributes that have not changed.
|
|
attributes = attributes.filter(this.proxy(function( attr ){
|
|
return ( edits[attr] !== undefined && edits[attr] !== this.get(attr) );
|
|
}));
|
|
|
|
// Trigger change if has attributes.
|
|
if( attributes.length ) {
|
|
this.triggerChange( edits )
|
|
}
|
|
},
|
|
|
|
triggerChange: function( edits ){
|
|
|
|
// Update this.data if edits are provided.
|
|
if( edits !== undefined ) {
|
|
this.data = edits;
|
|
}
|
|
|
|
// Check screen.
|
|
acf.screen.check();
|
|
},
|
|
|
|
getPageTemplate: function(){
|
|
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'template' );
|
|
},
|
|
|
|
getPageParent: function( e, $el ){
|
|
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'parent' );
|
|
},
|
|
|
|
getPostType: function(){
|
|
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'type' );
|
|
},
|
|
|
|
getPostFormat: function( e, $el ){
|
|
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'format' );
|
|
},
|
|
|
|
getPostCoreTerms: function(){
|
|
|
|
// vars
|
|
var terms = {};
|
|
|
|
// Loop over taxonomies.
|
|
var taxonomies = wp.data.select( 'core' ).getTaxonomies() || [];
|
|
taxonomies.map(function( taxonomy ){
|
|
|
|
// Append selected taxonomies to terms object.
|
|
var postTerms = wp.data.select( 'core/editor' ).getEditedPostAttribute( taxonomy.rest_base );
|
|
if( postTerms ) {
|
|
terms[ taxonomy.slug ] = postTerms;
|
|
}
|
|
});
|
|
|
|
// return
|
|
return terms;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* acf.screen.refreshAvailableMetaBoxesPerLocation
|
|
*
|
|
* Refreshes the WP data state based on metaboxes found in the DOM.
|
|
*
|
|
* Caution. Not safe to use.
|
|
* Causes duplicate dispatch listeners when saving post resulting in duplicate postmeta.
|
|
*
|
|
* @date 6/3/19
|
|
* @since 5.7.13
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
acf.screen.refreshAvailableMetaBoxesPerLocation = function() {
|
|
|
|
// Extract vars.
|
|
var select = wp.data.select( 'core/edit-post' );
|
|
var dispatch = wp.data.dispatch( 'core/edit-post' );
|
|
|
|
// Load current metabox locations and data.
|
|
var data = {};
|
|
select.getActiveMetaBoxLocations().map(function( location ){
|
|
data[ location ] = select.getMetaBoxesPerLocation( location );
|
|
});
|
|
|
|
// Generate flat array of existing ids.
|
|
var ids = [];
|
|
for( var k in data ) {
|
|
ids = ids.concat( data[k].map(function(m){ return m.id; }) );
|
|
}
|
|
|
|
// Append ACF metaboxes.
|
|
acf.getPostboxes().map(function( postbox ){
|
|
|
|
// Ignore if already exists in data.
|
|
if( ids.indexOf( postbox.get('id') ) !== -1 ) {
|
|
return;
|
|
}
|
|
|
|
// Get metabox location looking at parent form.
|
|
var location = postbox.$el.closest('form').attr('class').replace('metabox-location-', '');
|
|
|
|
// Ensure location exists.
|
|
data[ location ] = data[ location ] || [];
|
|
|
|
// Append.
|
|
data[ location ].push({
|
|
id: postbox.get('id'),
|
|
title: postbox.get('title')
|
|
});
|
|
});
|
|
|
|
// Update state.
|
|
dispatch.setAvailableMetaBoxesPerLocation(data);
|
|
};
|
|
|
|
})(jQuery); |