Customize: Allow controls to be created with pre-instantiated `Setting` object(s), or even with plain `Value` object(s).

* Allow passing settings in keyed object (e.g. `settings: { default: 'id' }  ), or as an array (e.g. `settings: [ 'id' ]`) with first being default; again, `Setting`/`Value` objects may be supplied instead of IDs.
* Allow a single setting to be supplied with just a single `setting` param, either a string or a `Setting`/`Value` object.
* Update `changeset_status` and `scheduled_changeset_date` to be added dynamically with JS and simply passing of `api.state()` instances as `setting`.
* Introduce a `data-customize-setting-key-link` attribute which, unlike `data-customize-setting-link`, allows passing the setting key (e.g. `default`) as opposed to the setting ID.
* Allow `WP_Customize_Control::get_link()` to return `data-customize-setting-key-link` when setting is not registered.
* Eliminate `default_value` from `WP_Customize_Date_Time_Control` since now comes from supplied `Value`.
* Export status choices as `wp.customize.settings.changeset.statusChoices`.
* Export date and time formats as `wp.customize.settings.dateFormat` and `wp.customize.settings.timeFormat` respectively.

Props westonruter, sayedwp.
See #39896, #30738, #30741, #42083.
Fixes #37964, #36167.

Built from https://develop.svn.wordpress.org/trunk@41750


git-svn-id: http://core.svn.wordpress.org/trunk@41584 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Weston Ruter 2017-10-04 20:02:49 +00:00
parent 08b5714221
commit f5bc1d1f52
11 changed files with 276 additions and 218 deletions

View File

@ -138,7 +138,7 @@ body.trashing #publish-settings {
margin-bottom: 15px;
}
#customize-control-changeset_status label,
#customize-control-changeset_status .customize-inside-control-row,
#customize-control-changeset_preview_link input {
background-color: #ffffff;
border-bottom: 1px solid #ddd;
@ -170,13 +170,13 @@ body.trashing #publish-settings {
border-color: #dc3232;
}
#customize-control-changeset_status label {
#customize-control-changeset_status .customize-inside-control-row {
padding-top: 10px;
padding-bottom: 10px;
font-weight: 500;
}
#customize-control-changeset_status label:first-of-type {
#customize-control-changeset_status .customize-inside-control-row:first-of-type {
border-top: 1px solid #ddd;
}
@ -2809,7 +2809,7 @@ body.adding-widget .add-new-widget:before,
height: 31px;
}
#customize-control-changeset_status label {
#customize-control-changeset_status .customize-inside-control-row {
padding-top: 15px;
}

File diff suppressed because one or more lines are too long

View File

@ -138,7 +138,7 @@ body.trashing #publish-settings {
margin-bottom: 15px;
}
#customize-control-changeset_status label,
#customize-control-changeset_status .customize-inside-control-row,
#customize-control-changeset_preview_link input {
background-color: #ffffff;
border-bottom: 1px solid #ddd;
@ -170,13 +170,13 @@ body.trashing #publish-settings {
border-color: #dc3232;
}
#customize-control-changeset_status label {
#customize-control-changeset_status .customize-inside-control-row {
padding-top: 10px;
padding-bottom: 10px;
font-weight: 500;
}
#customize-control-changeset_status label:first-of-type {
#customize-control-changeset_status .customize-inside-control-row:first-of-type {
border-top: 1px solid #ddd;
}
@ -2809,7 +2809,7 @@ body.adding-widget .add-new-widget:before,
height: 31px;
}
#customize-control-changeset_status label {
#customize-control-changeset_status .customize-inside-control-row {
padding-top: 15px;
}

File diff suppressed because one or more lines are too long

View File

@ -3094,8 +3094,10 @@
* @param {string} [options.priority=10] - Order of priority to show the control within the section.
* @param {string} [options.active=true] - Whether the control is active.
* @param {string} options.section - The ID of the section the control belongs to.
* @param {string} options.settings.default - The ID of the setting the control relates to.
* @param {string} options.settings.data
* @param {mixed} [options.setting] - The ID of the main setting or an instance of this setting.
* @param {mixed} options.settings - An object with keys (e.g. default) that maps to setting IDs or Setting/Value objects, or an array of setting IDs or Setting/Value objects.
* @param {mixed} options.settings.default - The ID of the setting the control relates to.
* @param {string} options.settings.data - @todo Is this used?
* @param {string} options.label - Label.
* @param {string} options.description - Description.
* @param {number} [options.instanceNumber] - Order in which this instance was created in relation to other instances.
@ -3110,8 +3112,7 @@
},
initialize: function( id, options ) {
var control = this,
nodes, radios, settings;
var control = this, deferredSettingIds = [], settings, gatherSettings;
control.params = _.extend( {}, control.defaults );
@ -3123,6 +3124,17 @@
control.params.instanceNumber = api.Control.instanceCounter;
}
// Look up the type if one was not supplied.
if ( ! control.params.type ) {
_.find( api.controlConstructor, function( Constructor, type ) {
if ( Constructor === control.constructor ) {
control.params.type = type;
return true;
}
return false;
} );
}
_.extend( control.params, options.params || options );
if ( ! control.params.content ) {
control.params.content = $( '<li></li>', {
@ -3153,31 +3165,6 @@
control.elements = [];
nodes = control.container.find('[data-customize-setting-link]');
radios = {};
nodes.each( function() {
var node = $( this ),
name;
if ( node.is( ':radio' ) ) {
name = node.prop( 'name' );
if ( radios[ name ] ) {
return;
}
radios[ name ] = true;
node = nodes.filter( '[name="' + name + '"]' );
}
api( node.data( 'customizeSettingLink' ), function( setting ) {
var element = new api.Element( node );
control.elements.push( element );
element.sync( setting );
element.set( setting() );
});
});
control.active.bind( function ( active ) {
var args = control.activeArgumentsQueue.shift();
args = $.extend( {}, control.defaultActiveArguments, args );
@ -3190,57 +3177,105 @@
api.utils.bubbleChildValueChanges( control, [ 'section', 'priority', 'active' ] );
/*
* After all settings related to the control are available,
* make them available on the control and embed the control into the page.
*/
settings = $.map( control.params.settings, function( value ) {
return value;
});
control.settings = {};
if ( 0 === settings.length ) {
control.setting = null;
control.settings = {};
control.embed();
} else {
api.apply( api, settings.concat( function() {
var key;
settings = {};
if ( control.params.setting ) {
settings['default'] = control.params.setting;
}
_.extend( settings, control.params.settings );
control.settings = {};
for ( key in control.params.settings ) {
control.settings[ key ] = api( control.params.settings[ key ] );
// Note: Settings can be an array or an object.
_.each( settings, function( setting, key ) {
if ( _.isObject( setting ) ) { // @todo Or check if instance of api.Setting?
control.settings[ key ] = setting;
} else {
deferredSettingIds.push( setting );
}
} );
gatherSettings = function() {
// Fill-in all resolved settings.
_.each( settings, function ( settingId, key ) {
if ( ! control.settings[ key ] && _.isString( settingId ) ) {
control.settings[ key ] = api( settingId );
}
} );
control.setting = control.settings['default'] || null;
// Make sure settings passed as array gets associated with default.
if ( control.settings[0] && ! control.settings['default'] ) {
control.settings['default'] = control.settings[0];
}
// Add setting notifications to the control notification.
_.each( control.settings, function( setting ) {
setting.notifications.bind( 'add', function( settingNotification ) {
var params = _.extend(
{},
settingNotification,
{
setting: setting.id
}
);
control.notifications.add( new api.Notification( setting.id + ':' + settingNotification.code, params ) );
} );
setting.notifications.bind( 'remove', function( settingNotification ) {
control.notifications.remove( setting.id + ':' + settingNotification.code );
} );
} );
// Identify the main setting.
control.setting = control.settings['default'] || null;
control.embed();
}) );
control.embed();
};
if ( 0 === deferredSettingIds.length ) {
gatherSettings();
} else {
api.apply( api, deferredSettingIds.concat( gatherSettings ) );
}
// After the control is embedded on the page, invoke the "ready" method.
control.deferred.embedded.done( function () {
control.linkElements();
control.setupNotifications();
control.ready();
});
},
/**
* Link elements between settings and inputs.
*
* @since 4.7.0
* @access public
*
* @returns {void}
*/
linkElements: function () {
var control = this, nodes, radios, element;
nodes = control.container.find( '[data-customize-setting-link], [data-customize-setting-key-link]' );
radios = {};
nodes.each( function () {
var node = $( this ), name, setting;
if ( node.data( 'customizeSettingLinked' ) ) {
return;
}
node.data( 'customizeSettingLinked', true ); // Prevent re-linking element.
if ( node.is( ':radio' ) ) {
name = node.prop( 'name' );
if ( radios[name] ) {
return;
}
radios[name] = true;
node = nodes.filter( '[name="' + name + '"]' );
}
// Let link by default refer to setting ID. If it doesn't exist, fallback to looking up by setting key.
if ( node.data( 'customizeSettingLink' ) ) {
setting = api( node.data( 'customizeSettingLink' ) );
} else if ( node.data( 'customizeSettingKeyLink' ) ) {
setting = control.settings[ node.data( 'customizeSettingKeyLink' ) ];
}
if ( setting ) {
element = new api.Element( node );
control.elements.push( element );
element.sync( setting );
element.set( setting() );
}
} );
},
/**
* Embed the control into the page.
*/
@ -3342,6 +3377,26 @@
setupNotifications: function() {
var control = this, renderNotificationsIfVisible, onSectionAssigned;
// Add setting notifications to the control notification.
_.each( control.settings, function( setting ) {
if ( ! setting.notifications ) {
return;
}
setting.notifications.bind( 'add', function( settingNotification ) {
var params = _.extend(
{},
settingNotification,
{
setting: setting.id
}
);
control.notifications.add( new api.Notification( setting.id + ':' + settingNotification.code, params ) );
} );
setting.notifications.bind( 'remove', function( settingNotification ) {
control.notifications.remove( setting.id + ':' + settingNotification.code );
} );
} );
control.notifications.container = control.getNotificationsContainerElement();
renderNotificationsIfVisible = function() {
@ -4986,14 +5041,8 @@
_.bindAll( control, 'populateSetting', 'updateDaysForMonth', 'updateMinutesForHour', 'populateDateInputs' );
// @todo This needs https://core.trac.wordpress.org/ticket/37964
if ( ! control.setting ) {
control.setting = new api.Value();
}
// @todo Should this be? Default should be on client. The default value should be in the setting itself.
if ( ! control.setting.get() && control.params.defaultValue ) {
control.setting.set( control.params.defaultValue );
throw new Error( 'Missing setting' );
}
control.container.find( '.date-input' ).each( function() {
@ -6360,8 +6409,9 @@
publishSettingsBtn = $( '#publish-settings' ),
footerActions = $( '#customize-footer-actions' );
// Set up publish settings section and its controls.
api.section( 'publish_settings', function( section ) {
var updateButtonsState, trashControl, updateSectionActive, isSectionActive;
var updateButtonsState, trashControl, updateSectionActive, isSectionActive, statusControl, dateControl, toggleDateControl, publishWhenTime, pollInterval, updateTimeArrivedPoller, timeArrivedPollingInterval = 1000;
trashControl = new api.Control( 'trash_changeset', {
type: 'button',
@ -6433,6 +6483,84 @@
publishSettingsBtn.attr( 'aria-expanded', String( isExpanded ) );
publishSettingsBtn.toggleClass( 'active', isExpanded );
} );
statusControl = new api.Control( 'changeset_status', {
priority: 10,
type: 'radio',
section: 'publish_settings',
setting: api.state( 'selectedChangesetStatus' ),
templateId: 'customize-selected-changeset-status-control',
label: api.l10n.action,
choices: api.settings.changeset.statusChoices
} );
api.control.add( statusControl );
dateControl = new api.DateTimeControl( 'changeset_scheduled_date', {
priority: 20,
section: 'publish_settings',
setting: api.state( 'selectedChangesetDate' ),
minYear: ( new Date() ).getFullYear(),
allowPastDate: false,
includeTime: true,
twelveHourFormat: /a/i.test( api.settings.timeFormat ),
description: api.l10n.scheduleDescription
} );
dateControl.notifications.alt = true;
api.control.add( dateControl );
publishWhenTime = function() {
api.state( 'selectedChangesetStatus' ).set( 'publish' );
api.previewer.save();
};
// Start countdown for when the dateTime arrives, or clear interval when it is .
updateTimeArrivedPoller = function() {
var shouldPoll = (
'future' === api.state( 'changesetStatus' ).get() &&
'future' === api.state( 'selectedChangesetStatus' ).get() &&
api.state( 'changesetDate' ).get() &&
api.state( 'selectedChangesetDate' ).get() === api.state( 'changesetDate' ).get() &&
api.utils.getRemainingTime( api.state( 'changesetDate' ).get() ) >= 0
);
if ( shouldPoll && ! pollInterval ) {
pollInterval = setInterval( function() {
var remainingTime = api.utils.getRemainingTime( api.state( 'changesetDate' ).get() );
api.state( 'remainingTimeToPublish' ).set( remainingTime );
if ( remainingTime <= 0 ) {
clearInterval( pollInterval );
pollInterval = 0;
publishWhenTime();
}
}, timeArrivedPollingInterval );
} else if ( ! shouldPoll && pollInterval ) {
clearInterval( pollInterval );
pollInterval = 0;
}
};
api.state( 'changesetDate' ).bind( updateTimeArrivedPoller );
api.state( 'selectedChangesetDate' ).bind( updateTimeArrivedPoller );
api.state( 'changesetStatus' ).bind( updateTimeArrivedPoller );
api.state( 'selectedChangesetStatus' ).bind( updateTimeArrivedPoller );
updateTimeArrivedPoller();
// Ensure dateControl only appears when selected status is future.
dateControl.active.validate = function() {
return 'future' === api.state( 'selectedChangesetStatus' ).get();
};
toggleDateControl = function( value ) {
dateControl.active.set( 'future' === value );
};
toggleDateControl( api.state( 'selectedChangesetStatus' ).get() );
api.state( 'selectedChangesetStatus' ).bind( toggleDateControl );
// Show notification on date control when status is future but it isn't a future date.
api.state( 'saving' ).bind( function( isSaving ) {
if ( isSaving && 'future' === api.state( 'selectedChangesetStatus' ).get() ) {
dateControl.toggleFutureDateNotification( ! dateControl.isFutureDate() );
}
} );
} );
// Prevent the form from saving when enter is pressed on an input or select element.
@ -7062,6 +7190,7 @@
// Set default states.
changesetStatus( api.settings.changeset.status );
changesetDate( api.settings.changeset.publishDate );
selectedChangesetDate( api.settings.changeset.publishDate );
selectedChangesetStatus( '' === api.settings.changeset.status || 'auto-draft' === api.settings.changeset.status ? 'publish' : api.settings.changeset.status );
selectedChangesetStatus.link( changesetStatus ); // Ensure that direct updates to status on server via wp.customizer.previewer.save() will update selection.
saved( true );
@ -7985,80 +8114,6 @@
});
})();
// Publish settings section and controls.
api.control( 'changeset_status', 'changeset_scheduled_date', function( statusControl, dateControl ) {
$.when( statusControl.deferred.embedded, dateControl.deferred.embedded ).done( function() {
var radioNodes, statusElement, toggleDateControl, publishWhenTime, pollInterval, updateTimeArrivedPoller, timeArrivedPollingInterval = 1000;
radioNodes = statusControl.container.find( 'input[type=radio][name]' );
statusElement = new api.Element( radioNodes );
statusControl.elements.push( statusElement );
statusElement.sync( api.state( 'selectedChangesetStatus' ) );
statusElement.set( api.state( 'selectedChangesetStatus' ).get() );
dateControl.notifications.alt = true;
dateControl.deferred.embedded.done( function() {
api.state( 'selectedChangesetDate' ).sync( dateControl.setting );
api.state( 'selectedChangesetDate' ).set( dateControl.setting() );
} );
publishWhenTime = function() {
api.state( 'selectedChangesetStatus' ).set( 'publish' );
api.previewer.save();
};
// Start countdown for when the dateTime arrives, or clear interval when it is .
updateTimeArrivedPoller = function() {
var shouldPoll = (
'future' === api.state( 'changesetStatus' ).get() &&
'future' === api.state( 'selectedChangesetStatus' ).get() &&
api.state( 'changesetDate' ).get() &&
api.state( 'selectedChangesetDate' ).get() === api.state( 'changesetDate' ).get() &&
api.utils.getRemainingTime( api.state( 'changesetDate' ).get() ) >= 0
);
if ( shouldPoll && ! pollInterval ) {
pollInterval = setInterval( function() {
var remainingTime = api.utils.getRemainingTime( api.state( 'changesetDate' ).get() );
api.state( 'remainingTimeToPublish' ).set( remainingTime );
if ( remainingTime <= 0 ) {
clearInterval( pollInterval );
pollInterval = 0;
publishWhenTime();
}
}, timeArrivedPollingInterval );
} else if ( ! shouldPoll && pollInterval ) {
clearInterval( pollInterval );
pollInterval = 0;
}
};
api.state( 'changesetDate' ).bind( updateTimeArrivedPoller );
api.state( 'selectedChangesetDate' ).bind( updateTimeArrivedPoller );
api.state( 'changesetStatus' ).bind( updateTimeArrivedPoller );
api.state( 'selectedChangesetStatus' ).bind( updateTimeArrivedPoller );
updateTimeArrivedPoller();
// Ensure dateControl only appears when selected status is future.
dateControl.active.validate = function() {
return 'future' === statusElement.get();
};
toggleDateControl = function( value ) {
dateControl.active.set( 'future' === value );
};
toggleDateControl( statusElement.get() );
statusElement.bind( toggleDateControl );
// Show notification on date control when status is future but it isn't a future date.
api.state( 'saving' ).bind( function( isSaving ) {
if ( isSaving && 'future' === api.state( 'selectedChangesetStatus' ).get() ) {
dateControl.toggleFutureDateNotification( ! dateControl.isFutureDate() );
}
} );
} );
} );
// Toggle visibility of Header Video notice when active state change.
api.control( 'header_video', function( headerVideoControl ) {
headerVideoControl.deferred.embedded.done( function() {

File diff suppressed because one or more lines are too long

View File

@ -430,15 +430,18 @@ class WP_Customize_Control {
* Get the data link attribute for a setting.
*
* @since 3.4.0
* @since 4.9.0 Return a `data-customize-setting-key-link` attribute if a setting is not registered for the supplied setting key.
*
* @param string $setting_key
* @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
* @return string Data link parameter, a `data-customize-setting-link` attribute if the `$setting_key` refers to a pre-registered setting,
* and a `data-customize-setting-key-link` attribute if the setting is not yet registered.
*/
public function get_link( $setting_key = 'default' ) {
if ( ! isset( $this->settings[ $setting_key ] ) )
return '';
return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
if ( isset( $this->settings[ $setting_key ] ) && $this->settings[ $setting_key ] instanceof WP_Customize_Setting ) {
return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
} else {
return 'data-customize-setting-key-link="' . esc_attr( $setting_key ) . '"';
}
}
/**

View File

@ -3642,6 +3642,23 @@ final class WP_Customize_Manager {
<script type="text/html" id="tmpl-customize-trash-changeset-control">
<button type="button" class="button-link button-link-delete"><?php _e( 'Discard changes' ); ?></button>
</script>
<script type="text/html" id="tmpl-customize-selected-changeset-status-control">
<# var inputId = _.uniqueId( 'customize-selected-changeset-status-control-input-' ); #>
<# var descriptionId = _.uniqueId( 'customize-selected-changeset-status-control-description-' ); #>
<# if ( data.label ) { #>
<label for="{{ inputId }}" class="customize-control-title">{{ data.label }}</label>
<# } #>
<# if ( data.description ) { #>
<span id="{{ descriptionId }}" class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<# _.each( data.choices, function( choice ) { #>
<# var choiceId = inputId + '-' + choice.status; #>
<span class="customize-inside-control-row">
<input id="{{ choiceId }}" type="radio" value="{{ choice.status }}" name="{{ inputId }}" data-customize-setting-key-link="default">
<label for="{{ choiceId }}">{{ choice.label }}</label>
</span>
<# } ); #>
</script>
<?php
}
@ -4024,12 +4041,39 @@ final class WP_Customize_Manager {
}
}
$current_user_can_publish = current_user_can( get_post_type_object( 'customize_changeset' )->cap->publish_posts );
// @todo Include all of the status labels here from script-loader.php, and then allow it to be filtered.
$status_choices = array();
if ( $current_user_can_publish ) {
$status_choices[] = array(
'status' => 'publish',
'label' => __( 'Publish' ),
);
}
$status_choices[] = array(
'status' => 'draft',
'label' => __( 'Save Draft' ),
);
if ( $current_user_can_publish ) {
$status_choices[] = array(
'status' => 'future',
'label' => __( 'Schedule' ),
);
}
// Prepare Customizer settings to pass to JavaScript.
$changeset_post = null;
if ( $changeset_post_id ) {
$changeset_post = get_post( $changeset_post_id );
}
if ( $this->changeset_post_id() && 'future' === get_post_status( $this->changeset_post_id() ) ) {
$initial_date = get_the_time( 'Y-m-d H:i:s', $this->changeset_post_id() );
} else {
$initial_date = current_time( 'mysql', false );
}
$settings = array(
'changeset' => array(
'uuid' => $this->changeset_uuid(),
@ -4038,10 +4082,13 @@ final class WP_Customize_Manager {
'hasAutosaveRevision' => ! empty( $autosave_revision_post ),
'latestAutoDraftUuid' => $autosave_autodraft_post ? $autosave_autodraft_post->post_name : null,
'status' => $changeset_post ? $changeset_post->post_status : '',
'currentUserCanPublish' => current_user_can( get_post_type_object( 'customize_changeset' )->cap->publish_posts ),
'publishDate' => $changeset_post ? $changeset_post->post_date : '', // @todo Only if future status? Rename to just date?
'currentUserCanPublish' => $current_user_can_publish,
'publishDate' => $initial_date,
'statusChoices' => $status_choices,
),
'initialServerDate' => current_time( 'mysql', false ),
'dateFormat' => get_option( 'date_format' ),
'timeFormat' => get_option( 'time_format' ),
'initialServerTimestamp' => floor( microtime( true ) * 1000 ),
'initialClientTimestamp' => -1, // To be set with JS below.
'timeouts' => array(
@ -4205,6 +4252,7 @@ final class WP_Customize_Manager {
/* Publish Settings */
// Note the controls for this section are added via JS.
$this->add_section( 'publish_settings', array(
'title' => __( 'Publish Settings' ),
'priority' => 0,
@ -4213,47 +4261,6 @@ final class WP_Customize_Manager {
'active_callback' => array( $this, 'is_theme_active' ),
) );
/* Publish Settings Controls */
$status_choices = array(
'publish' => __( 'Publish' ),
'draft' => __( 'Save Draft' ),
'future' => __( 'Schedule' ),
);
if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->publish_posts ) ) {
unset( $status_choices['publish'] );
}
$this->add_control( 'changeset_status', array(
'section' => 'publish_settings',
'priority' => 10,
'settings' => array(),
'type' => 'radio',
'label' => __( 'Action' ),
'choices' => $status_choices,
'capability' => 'customize',
) );
if ( $this->changeset_post_id() && 'future' === get_post_status( $this->changeset_post_id() ) ) {
$initial_date = get_the_time( 'Y-m-d H:i:s', $this->changeset_post_id() );
} else {
$initial_date = current_time( 'mysql', false );
}
$this->add_control( new WP_Customize_Date_Time_Control( $this, 'changeset_scheduled_date', array(
'section' => 'publish_settings',
'priority' => 20,
'settings' => array(),
'type' => 'date_time',
'min_year' => date( 'Y' ),
'allow_past_date' => false,
'include_time' => true,
'twelve_hour_format' => false !== stripos( get_option( 'time_format' ), 'a' ),
'description' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ),
'capability' => 'customize',
'default_value' => $initial_date,
) ) );
/* Themes (controls are loaded via ajax) */
$this->add_panel( new WP_Customize_Themes_Panel( $this, 'themes', array(

View File

@ -65,14 +65,6 @@ class WP_Customize_Date_Time_Control extends WP_Customize_Control {
*/
public $twelve_hour_format = true;
/**
* Default date/time to be displayed in the control.
*
* @since 4.9.0
* @var string
*/
public $default_value;
/**
* Don't render the control's content - it's rendered with a JS template.
*
@ -94,7 +86,6 @@ class WP_Customize_Date_Time_Control extends WP_Customize_Control {
$data['allowPastDate'] = (bool) $this->allow_past_date;
$data['twelveHourFormat'] = (bool) $this->twelve_hour_format;
$data['includeTime'] = (bool) $this->include_time;
$data['defaultValue'] = $this->default_value;
return $data;
}

View File

@ -566,6 +566,7 @@ function wp_default_scripts( &$scripts ) {
'saved' => __( 'Saved' ),
'cancel' => __( 'Cancel' ),
'close' => __( 'Close' ),
'action' => __( 'Action' ),
'cheatin' => __( 'Cheatin&#8217; uh?' ),
'notAllowed' => __( 'Sorry, you are not allowed to customize this site.' ),
'previewIframeTitle' => __( 'Site Preview' ),
@ -594,6 +595,7 @@ function wp_default_scripts( &$scripts ) {
_n_noop( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.' ),
array( 'singular', 'plural' )
),
'scheduleDescription' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ),
) );
$scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.9-alpha-41749';
$wp_version = '4.9-alpha-41750';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.