Site Icon: Add Customizer UI.

Second part of the Site Icon feature after [32994] introduced it for Settings.

Props celloexpressions.
See #16434.


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


git-svn-id: http://core.svn.wordpress.org/trunk@33126 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Konstantin Obenland 2015-07-10 21:33:24 +00:00
parent 75d6c10b01
commit f29e5044cd
16 changed files with 552 additions and 21 deletions

View File

@ -62,7 +62,7 @@ $core_actions_post = array(
'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs', 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail', 'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail',
'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post', 'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post',
'press-this-add-category', 'press-this-add-category', 'crop-image',
); );
// Deprecated // Deprecated

View File

@ -751,6 +751,8 @@ p.customize-section-description {
.customize-control-upload .current, .customize-control-upload .current,
.customize-control-image .current, .customize-control-image .current,
.customize-control-background .current, .customize-control-background .current,
.customize-control-cropped_image .current,
.customize-control-site_icon .current,
.customize-control-header .current { .customize-control-header .current {
margin-bottom: 8px; margin-bottom: 8px;
} }
@ -786,6 +788,12 @@ p.customize-section-description {
.customize-control-background .remove-button, .customize-control-background .remove-button,
.customize-control-background .default-button, .customize-control-background .default-button,
.customize-control-background .upload-button, .customize-control-background .upload-button,
.customize-control-cropped_image .remove-button,
.customize-control-cropped_image .default-button,
.customize-control-cropped_image .upload-button,
.customize-control-site_icon .remove-button,
.customize-control-site_icon .default-button,
.customize-control-site_icon .upload-button,
.customize-control-header button.new, .customize-control-header button.new,
.customize-control-header button.remove { .customize-control-header button.remove {
white-space: normal; white-space: normal;
@ -797,6 +805,8 @@ p.customize-section-description {
.customize-control-upload .current .container, .customize-control-upload .current .container,
.customize-control-image .current .container, .customize-control-image .current .container,
.customize-control-background .current .container, .customize-control-background .current .container,
.customize-control-cropped_image .current .container,
.customize-control-site_icon .current .container,
.customize-control-header .current .container { .customize-control-header .current .container {
overflow: hidden; overflow: hidden;
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
@ -808,6 +818,8 @@ p.customize-section-description {
.customize-control-media .current .container, .customize-control-media .current .container,
.customize-control-upload .current .container, .customize-control-upload .current .container,
.customize-control-background .current .container, .customize-control-background .current .container,
.customize-control-cropped_image .current .container,
.customize-control-site_icon .current .container,
.customize-control-image .current .container { .customize-control-image .current .container {
min-height: 40px; min-height: 40px;
} }
@ -816,6 +828,8 @@ p.customize-section-description {
.customize-control-upload .placeholder, .customize-control-upload .placeholder,
.customize-control-image .placeholder, .customize-control-image .placeholder,
.customize-control-background .placeholder, .customize-control-background .placeholder,
.customize-control-cropped_image .placeholder,
.customize-control-site_icon .placeholder,
.customize-control-header .placeholder { .customize-control-header .placeholder {
width: 100%; width: 100%;
position: relative; position: relative;
@ -827,6 +841,8 @@ p.customize-section-description {
.customize-control-upload .inner, .customize-control-upload .inner,
.customize-control-image .inner, .customize-control-image .inner,
.customize-control-background .inner, .customize-control-background .inner,
.customize-control-cropped_image .inner,
.customize-control-site_icon .inner,
.customize-control-header .inner { .customize-control-header .inner {
display: none; display: none;
position: absolute; position: absolute;
@ -840,6 +856,8 @@ p.customize-section-description {
.customize-control-media .inner, .customize-control-media .inner,
.customize-control-upload .inner, .customize-control-upload .inner,
.customize-control-background .inner, .customize-control-background .inner,
.customize-control-cropped_image .inner,
.customize-control-site_icon .inner,
.customize-control-image .inner { .customize-control-image .inner {
display: block; display: block;
min-height: 40px; min-height: 40px;
@ -849,6 +867,8 @@ p.customize-section-description {
.customize-control-upload .inner, .customize-control-upload .inner,
.customize-control-image .inner, .customize-control-image .inner,
.customize-control-background .inner, .customize-control-background .inner,
.customize-control-cropped_image .inner,
.customize-control-site_icon .inner,
.customize-control-header .inner, .customize-control-header .inner,
.customize-control-header .inner .dashicons { .customize-control-header .inner .dashicons {
line-height: 20px; line-height: 20px;
@ -952,6 +972,8 @@ p.customize-section-description {
.customize-control-upload .actions, .customize-control-upload .actions,
.customize-control-image .actions, .customize-control-image .actions,
.customize-control-background .actions, .customize-control-background .actions,
.customize-control-cropped_image .actions,
.customize-control-site_icon .actions,
.customize-control-header .actions { .customize-control-header .actions {
margin-bottom: 32px; margin-bottom: 32px;
} }
@ -970,6 +992,8 @@ p.customize-section-description {
.customize-control-upload img, .customize-control-upload img,
.customize-control-image img, .customize-control-image img,
.customize-control-background img, .customize-control-background img,
.customize-control-cropped_image img,
.customize-control-site_icon img,
.customize-control-header img { .customize-control-header img {
width: 100%; width: 100%;
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
@ -984,6 +1008,10 @@ p.customize-section-description {
.customize-control-image .default-button, .customize-control-image .default-button,
.customize-control-background .remove-button, .customize-control-background .remove-button,
.customize-control-background .default-button, .customize-control-background .default-button,
.customize-control-cropped_image .remove-button,
.customize-control-cropped_image .default-button,
.customize-control-site_icon .remove-button,
.customize-control-site_icon .default-button,
.customize-control-header .remove { .customize-control-header .remove {
float: right; float: right;
margin-left: 3px; margin-left: 3px;
@ -993,6 +1021,8 @@ p.customize-section-description {
.customize-control-upload .upload-button, .customize-control-upload .upload-button,
.customize-control-image .upload-button, .customize-control-image .upload-button,
.customize-control-background .upload-button, .customize-control-background .upload-button,
.customize-control-cropped_image .upload-button,
.customize-control-site_icon .upload-button,
.customize-control-header .new { .customize-control-header .new {
float: left; float: left;
} }

File diff suppressed because one or more lines are too long

View File

@ -751,6 +751,8 @@ p.customize-section-description {
.customize-control-upload .current, .customize-control-upload .current,
.customize-control-image .current, .customize-control-image .current,
.customize-control-background .current, .customize-control-background .current,
.customize-control-cropped_image .current,
.customize-control-site_icon .current,
.customize-control-header .current { .customize-control-header .current {
margin-bottom: 8px; margin-bottom: 8px;
} }
@ -786,6 +788,12 @@ p.customize-section-description {
.customize-control-background .remove-button, .customize-control-background .remove-button,
.customize-control-background .default-button, .customize-control-background .default-button,
.customize-control-background .upload-button, .customize-control-background .upload-button,
.customize-control-cropped_image .remove-button,
.customize-control-cropped_image .default-button,
.customize-control-cropped_image .upload-button,
.customize-control-site_icon .remove-button,
.customize-control-site_icon .default-button,
.customize-control-site_icon .upload-button,
.customize-control-header button.new, .customize-control-header button.new,
.customize-control-header button.remove { .customize-control-header button.remove {
white-space: normal; white-space: normal;
@ -797,6 +805,8 @@ p.customize-section-description {
.customize-control-upload .current .container, .customize-control-upload .current .container,
.customize-control-image .current .container, .customize-control-image .current .container,
.customize-control-background .current .container, .customize-control-background .current .container,
.customize-control-cropped_image .current .container,
.customize-control-site_icon .current .container,
.customize-control-header .current .container { .customize-control-header .current .container {
overflow: hidden; overflow: hidden;
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
@ -808,6 +818,8 @@ p.customize-section-description {
.customize-control-media .current .container, .customize-control-media .current .container,
.customize-control-upload .current .container, .customize-control-upload .current .container,
.customize-control-background .current .container, .customize-control-background .current .container,
.customize-control-cropped_image .current .container,
.customize-control-site_icon .current .container,
.customize-control-image .current .container { .customize-control-image .current .container {
min-height: 40px; min-height: 40px;
} }
@ -816,6 +828,8 @@ p.customize-section-description {
.customize-control-upload .placeholder, .customize-control-upload .placeholder,
.customize-control-image .placeholder, .customize-control-image .placeholder,
.customize-control-background .placeholder, .customize-control-background .placeholder,
.customize-control-cropped_image .placeholder,
.customize-control-site_icon .placeholder,
.customize-control-header .placeholder { .customize-control-header .placeholder {
width: 100%; width: 100%;
position: relative; position: relative;
@ -827,6 +841,8 @@ p.customize-section-description {
.customize-control-upload .inner, .customize-control-upload .inner,
.customize-control-image .inner, .customize-control-image .inner,
.customize-control-background .inner, .customize-control-background .inner,
.customize-control-cropped_image .inner,
.customize-control-site_icon .inner,
.customize-control-header .inner { .customize-control-header .inner {
display: none; display: none;
position: absolute; position: absolute;
@ -840,6 +856,8 @@ p.customize-section-description {
.customize-control-media .inner, .customize-control-media .inner,
.customize-control-upload .inner, .customize-control-upload .inner,
.customize-control-background .inner, .customize-control-background .inner,
.customize-control-cropped_image .inner,
.customize-control-site_icon .inner,
.customize-control-image .inner { .customize-control-image .inner {
display: block; display: block;
min-height: 40px; min-height: 40px;
@ -849,6 +867,8 @@ p.customize-section-description {
.customize-control-upload .inner, .customize-control-upload .inner,
.customize-control-image .inner, .customize-control-image .inner,
.customize-control-background .inner, .customize-control-background .inner,
.customize-control-cropped_image .inner,
.customize-control-site_icon .inner,
.customize-control-header .inner, .customize-control-header .inner,
.customize-control-header .inner .dashicons { .customize-control-header .inner .dashicons {
line-height: 20px; line-height: 20px;
@ -952,6 +972,8 @@ p.customize-section-description {
.customize-control-upload .actions, .customize-control-upload .actions,
.customize-control-image .actions, .customize-control-image .actions,
.customize-control-background .actions, .customize-control-background .actions,
.customize-control-cropped_image .actions,
.customize-control-site_icon .actions,
.customize-control-header .actions { .customize-control-header .actions {
margin-bottom: 32px; margin-bottom: 32px;
} }
@ -970,6 +992,8 @@ p.customize-section-description {
.customize-control-upload img, .customize-control-upload img,
.customize-control-image img, .customize-control-image img,
.customize-control-background img, .customize-control-background img,
.customize-control-cropped_image img,
.customize-control-site_icon img,
.customize-control-header img { .customize-control-header img {
width: 100%; width: 100%;
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
@ -984,6 +1008,10 @@ p.customize-section-description {
.customize-control-image .default-button, .customize-control-image .default-button,
.customize-control-background .remove-button, .customize-control-background .remove-button,
.customize-control-background .default-button, .customize-control-background .default-button,
.customize-control-cropped_image .remove-button,
.customize-control-cropped_image .default-button,
.customize-control-site_icon .remove-button,
.customize-control-site_icon .default-button,
.customize-control-header .remove { .customize-control-header .remove {
float: left; float: left;
margin-right: 3px; margin-right: 3px;
@ -993,6 +1021,8 @@ p.customize-section-description {
.customize-control-upload .upload-button, .customize-control-upload .upload-button,
.customize-control-image .upload-button, .customize-control-image .upload-button,
.customize-control-background .upload-button, .customize-control-background .upload-button,
.customize-control-cropped_image .upload-button,
.customize-control-site_icon .upload-button,
.customize-control-header .new { .customize-control-header .new {
float: right; float: right;
} }

File diff suppressed because one or more lines are too long

View File

@ -3052,3 +3052,65 @@ function wp_ajax_press_this_add_category() {
$GLOBALS['wp_press_this']->add_category(); $GLOBALS['wp_press_this']->add_category();
} }
/**
* AJAX handler for cropping an image.
*
* @since 4.3.0
*
* @global WP_Site_Icon $wp_site_icon
*/
function wp_ajax_crop_image() {
$attachment_id = absint( $_POST['id'] );
check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error();
}
$context = str_replace( '_', '-', $_POST['context'] );
$data = array_map( 'absint', $_POST['cropDetails'] );
$cropped = wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] );
if ( ! $cropped || is_wp_error( $cropped ) ) {
wp_send_json_error( array( 'message' => __( 'Image could not be processed.' ) ) );
}
switch ( $context ) {
case 'site-icon':
require_once ABSPATH . '/wp-admin/includes/class-wp-site-icon.php';
global $wp_site_icon;
/** This filter is documented in wp-admin/custom-header.php */
$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
$object = $wp_site_icon->create_attachment_object( $cropped, $attachment_id );
unset( $object['ID'] );
// Update the attachment.
add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
$attachment_id = $wp_site_icon->insert_attachment( $object, $cropped );
remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
// Additional sizes in wp_prepare_attachment_for_js().
add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
break;
default:
/**
* Filters the attachment id for a cropped image.
*
* @since 4.3.0
*
* @param int $attachment_id The ID of the cropped image.
* @param string $context The feature requesting the cropped image.
*/
$attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', 0, $context );
if ( ! $attachment_id ) {
wp_send_json_error();
}
}
wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) );
}

View File

@ -274,7 +274,7 @@ class WP_Site_Icon {
<div class="site-icon-crop-preview-shell hide-if-no-js"> <div class="site-icon-crop-preview-shell hide-if-no-js">
<h3><?php _e( 'Preview' ); ?></h3> <h3><?php _e( 'Preview' ); ?></h3>
<strong><?php _e( 'As your favicon' ); ?></strong> <strong><?php _e( 'As a browser icon' ); ?></strong>
<div class="site-icon-crop-favicon-preview-shell"> <div class="site-icon-crop-favicon-preview-shell">
<img src="images/browser.png" class="site-icon-browser-preview" width="182" height="" alt="<?php esc_attr_e( 'Browser Chrome' ); ?>"/> <img src="images/browser.png" class="site-icon-browser-preview" width="182" height="" alt="<?php esc_attr_e( 'Browser Chrome' ); ?>"/>
@ -284,7 +284,7 @@ class WP_Site_Icon {
<span class="site-icon-browser-title"><?php bloginfo( 'name' ); ?></span> <span class="site-icon-browser-title"><?php bloginfo( 'name' ); ?></span>
</div> </div>
<strong><?php _e( 'As a mobile icon' ); ?></strong> <strong><?php _e( 'As an app icon' ); ?></strong>
<div class="site-icon-crop-preview-homeicon"> <div class="site-icon-crop-preview-homeicon">
<img src="<?php echo esc_url( $url ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' ); ?>"/> <img src="<?php echo esc_url( $url ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' ); ?>"/>
</div> </div>
@ -505,7 +505,7 @@ class WP_Site_Icon {
// ensure that we only resize the image into // ensure that we only resize the image into
foreach ( $sizes as $name => $size_array ) { foreach ( $sizes as $name => $size_array ) {
if ( $size_array['crop'] ) { if ( isset( $size_array['crop'] ) ) {
$only_crop_sizes[ $name ] = $size_array; $only_crop_sizes[ $name ] = $size_array;
} }
} }

View File

@ -1835,6 +1835,245 @@
} }
}); });
/**
* A control for selecting and cropping an image.
*
* @class
* @augments wp.customize.MediaControl
* @augments wp.customize.Control
* @augments wp.customize.Class
*/
api.CroppedImageControl = api.MediaControl.extend({
/**
* Open the media modal to the library state.
*/
openFrame: function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
this.initFrame();
this.frame.setState( 'library' ).open();
},
/**
* Create a media modal select frame, and store it so the instance can be reused when needed.
*/
initFrame: function() {
var l10n = _wpMediaViewsL10n;
this.frame = wp.media({
button: {
text: l10n.select,
close: false
},
states: [
new wp.media.controller.Library({
title: this.params.button_labels.frame_title,
library: wp.media.query({ type: 'image' }),
multiple: false,
date: false,
priority: 20,
suggestedWidth: this.params.width,
suggestedHeight: this.params.height
}),
new wp.media.controller.customizeImageCropper({
imgSelectOptions: this.calculateImageSelectOptions,
control: this
})
]
});
this.frame.on( 'select', this.onSelect, this );
this.frame.on( 'cropped', this.onCropped, this );
this.frame.on( 'skippedcrop', this.onSkippedCrop, this );
},
/**
* After an image is selected in the media modal, switch to the cropper
* state if the image isn't the right size.
*/
onSelect: function() {
var attachment = this.frame.state().get( 'selection' ).first().toJSON();
if ( this.params.width === attachment.width && this.params.height === attachment.height && ! this.params.flex_width && ! this.params.flex_height ) {
this.setImageFromAttachment( attachment );
this.frame.close();
} else {
this.frame.setState( 'cropper' );
}
},
/**
* After the image has been cropped, apply the cropped image data to the setting.
*
* @param {object} croppedImage Cropped attachment data.
*/
onCropped: function( croppedImage ) {
this.setImageFromAttachment( croppedImage );
},
/**
* Returns a set of options, computed from the attached image data and
* control-specific data, to be fed to the imgAreaSelect plugin in
* wp.media.view.Cropper.
*
* @param {wp.media.model.Attachment} attachment
* @param {wp.media.controller.Cropper} controller
* @returns {Object} Options
*/
calculateImageSelectOptions: function( attachment, controller ) {
var control = controller.get( 'control' ),
flexWidth = !! parseInt( control.params.flex_width, 10 ),
flexHeight = !! parseInt( control.params.flex_height, 10 ),
realWidth = attachment.get( 'width' ),
realHeight = attachment.get( 'height' ),
xInit = parseInt( control.params.width, 10 ),
yInit = parseInt( control.params.height, 10 ),
ratio = xInit / yInit,
xImg = realWidth,
yImg = realHeight,
imgSelectOptions;
controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) );
if ( xImg / yImg > ratio ) {
yInit = yImg;
xInit = yInit * ratio;
} else {
xInit = xImg;
yInit = xInit / ratio;
}
imgSelectOptions = {
handles: true,
keys: true,
instance: true,
persistent: true,
imageWidth: realWidth,
imageHeight: realHeight,
x1: 0,
y1: 0,
x2: xInit,
y2: yInit
};
if ( flexHeight === false && flexWidth === false ) {
imgSelectOptions.aspectRatio = xInit + ':' + yInit;
}
if ( flexHeight === false ) {
imgSelectOptions.maxHeight = yInit;
}
if ( flexWidth === false ) {
imgSelectOptions.maxWidth = xInit;
}
return imgSelectOptions;
},
/**
* Return whether the image must be cropped, based on required dimensions.
*
* @param {bool} flexW
* @param {bool} flexH
* @param {int} dstW
* @param {int} dstH
* @param {int} imgW
* @param {int} imgH
* @return {bool}
*/
mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) {
if ( true === flexW && true === flexH ) {
return false;
}
if ( true === flexW && dstH === imgH ) {
return false;
}
if ( true === flexH && dstW === imgW ) {
return false;
}
if ( dstW === imgW && dstH === imgH ) {
return false;
}
if ( imgW <= dstW ) {
return false;
}
return true;
},
/**
* If cropping was skipped, apply the image data directly to the setting.
*/
onSkippedCrop: function() {
var attachment = this.frame.state().get( 'selection' ).first().toJSON();
this.setImageFromAttachment( attachment );
},
/**
* Updates the setting and re-renders the control UI.
*
* @param {object} attachment
*/
setImageFromAttachment: function( attachment ) {
this.params.attachment = attachment;
// Set the Customizer setting; the callback takes care of rendering.
this.setting( attachment.id );
}
});
/**
* A control for selecting and cropping Site Icons.
*
* @class
* @augments wp.customize.CroppedImageControl
* @augments wp.customize.MediaControl
* @augments wp.customize.Control
* @augments wp.customize.Class
*/
api.SiteIconControl = api.CroppedImageControl.extend({
/**
* Updates the setting and re-renders the control UI.
*
* @param {object} attachment
*/
setImageFromAttachment: function( attachment ) {
var icon = typeof attachment.sizes['site_icon-32'] !== 'undefined' ? attachment.sizes['site_icon-32'] : attachment.sizes.thumbnail;
this.params.attachment = attachment;
// Set the Customizer setting; the callback takes care of rendering.
this.setting( attachment.id );
// Update the icon in-browser.
$( 'link[rel="icon"]' ).attr( 'href', icon.url );
},
/**
* Called when the "Remove" link is clicked. Empties the setting.
*
* @param {object} event jQuery Event object
*/
removeFile: function( event ) {
if ( api.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
event.preventDefault();
this.params.attachment = {};
this.setting( '' );
this.renderContent(); // Not bound to setting change when emptying.
$( 'link[rel="icon"]' ).attr( 'href', '' );
}
});
/** /**
* @class * @class
* @augments wp.customize.Control * @augments wp.customize.Control
@ -2699,6 +2938,8 @@
media: api.MediaControl, media: api.MediaControl,
upload: api.UploadControl, upload: api.UploadControl,
image: api.ImageControl, image: api.ImageControl,
cropped_image: api.CroppedImageControl,
site_icon: api.SiteIconControl,
header: api.HeaderControl, header: api.HeaderControl,
background: api.BackgroundControl, background: api.BackgroundControl,
theme: api.ThemeControl theme: api.ThemeControl

File diff suppressed because one or more lines are too long

View File

@ -163,7 +163,7 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
<a class="button hide-if-js" href="<?php echo esc_url( $upload_url ); ?>"><?php _e( 'Add a Site Icon' ); ?></a> <a class="button hide-if-js" href="<?php echo esc_url( $upload_url ); ?>"><?php _e( 'Add a Site Icon' ); ?></a>
<?php endif; ?> <?php endif; ?>
<p class="description"><?php _e( 'Site Icon creates a favicon and app icons for your site.' ) ?></p> <p class="description"><?php _e( 'The Site Icon is used as a browser and app icon for your site.' ); ?></p>
</td> </td>
</tr> </tr>
<?php if ( !is_multisite() ) { ?> <?php if ( !is_multisite() ) { ?>

View File

@ -1000,6 +1000,134 @@ class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
} }
} }
/**
* Customize Cropped Image Control class.
*
* @since 4.3.0
*
* @see WP_Customize_Image_Control
*/
class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control {
/**
* Control type.
*
* @since 4.3.0
*
* @access public
* @var string
*/
public $type = 'cropped_image';
/**
* Suggested width for cropped image.
*
* @since 4.3.0
*
* @access public
* @var int
*/
public $width = 150;
/**
* Suggested height for cropped image.
*
* @since 4.3.0
*
* @access public
* @var int
*/
public $height = 150;
/**
* Whether the width is flexible.
*
* @since 4.3.0
*
* @access public
* @var bool
*/
public $flex_width = false;
/**
* Whether the height is flexible.
*
* @since 4.3.0
*
* @access public
* @var bool
*/
public $flex_height = false;
/**
* Enqueue control related scripts/styles.
*
* @since 4.3.0
*
* @access public
*/
public function enqueue() {
wp_enqueue_script( 'customize-views' );
parent::enqueue();
}
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @since 4.3.0
*
* @access public
* @uses WP_Customize_Image_Control::to_json()
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
$this->json['width'] = absint( $this->width );
$this->json['height'] = absint( $this->height );
$this->json['flex_width'] = absint( $this->flex_width );
$this->json['flex_height'] = absint( $this->flex_height );
}
}
/**
* Customize Site Icon control class.
*
* Used only for custom functionality in JavaScript.
*
* @since 4.3.0
*
* @see WP_Customize_Cropped_Image_Control
*/
class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control {
/**
* Control type.
*
* @since 4.3.0
*
* @access public
* @var string
*/
public $type = 'site_icon';
/**
* Constructor.
*
* @since 4.3.0
*
* @param WP_Customize_Manager $manager
* @param string $id
* @param array $args
*/
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 );
}
}
/** /**
* Customize Header Image Control class. * Customize Header Image Control class.
* *

View File

@ -1278,6 +1278,8 @@ final class WP_Customize_Manager {
$this->register_control_type( 'WP_Customize_Upload_Control' ); $this->register_control_type( 'WP_Customize_Upload_Control' );
$this->register_control_type( 'WP_Customize_Image_Control' ); $this->register_control_type( 'WP_Customize_Image_Control' );
$this->register_control_type( 'WP_Customize_Background_Image_Control' ); $this->register_control_type( 'WP_Customize_Background_Image_Control' );
$this->register_control_type( 'WP_Customize_Cropped_Image_Control' );
$this->register_control_type( 'WP_Customize_Site_Icon_Control' );
$this->register_control_type( 'WP_Customize_Theme_Control' ); $this->register_control_type( 'WP_Customize_Theme_Control' );
/* Themes */ /* Themes */
@ -1324,10 +1326,10 @@ final class WP_Customize_Manager {
) ) ); ) ) );
} }
/* Site Title & Tagline */ /* Site Identity */
$this->add_section( 'title_tagline', array( $this->add_section( 'title_tagline', array(
'title' => __( 'Site Title & Tagline' ), 'title' => __( 'Site Identity' ),
'priority' => 20, 'priority' => 20,
) ); ) );
@ -1353,6 +1355,23 @@ final class WP_Customize_Manager {
'section' => 'title_tagline', 'section' => 'title_tagline',
) ); ) );
$icon = wp_get_attachment_image_src( absint( get_option( 'site_icon' ) ), 'full' );
$this->add_setting( 'site_icon', array(
'default' => $icon[0] ? $icon[0] : '',
'type' => 'option',
'capability' => 'manage_options',
'transport' => 'postMessage', // Previewed with JS in the Customizer controls window.
) );
$this->add_control( new WP_Customize_Site_Icon_Control( $this, 'site_icon', array(
'label' => __( 'Site Icon' ),
'description' => __( 'The Site Icon is used as a browser and app icon for your site. Icons must be square, and at least 512px wide and tall.' ),
'section' => 'title_tagline',
'priority' => 60,
'height' => 512,
'width' => 512,
) ) );
/* Colors */ /* Colors */
$this->add_section( 'colors', array( $this->add_section( 'colors', array(
@ -1375,6 +1394,7 @@ final class WP_Customize_Manager {
'label' => __( 'Display Header Text' ), 'label' => __( 'Display Header Text' ),
'section' => 'title_tagline', 'section' => 'title_tagline',
'type' => 'checkbox', 'type' => 'checkbox',
'priority' => 40,
) ); ) );
$this->add_control( new WP_Customize_Color_Control( $this, 'header_textcolor', array( $this->add_control( new WP_Customize_Color_Control( $this, 'header_textcolor', array(

View File

@ -2445,7 +2445,7 @@ function wp_no_robots() {
* @link http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon. * @link http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon.
*/ */
function wp_site_icon() { function wp_site_icon() {
if ( ! has_site_icon() ) { if ( ! has_site_icon() && ! is_customize_preview() ) {
return; return;
} }

View File

@ -3,6 +3,26 @@
if ( ! wp || ! wp.customize ) { return; } if ( ! wp || ! wp.customize ) { return; }
var api = wp.customize; var api = wp.customize;
/**
* Use a custom ajax action for cropped image controls.
*/
wp.media.controller.customizeImageCropper = wp.media.controller.Cropper.extend( {
doCrop: function( attachment ) {
var cropDetails = attachment.get( 'cropDetails' ),
control = this.get( 'control' );
cropDetails.dst_width = control.params.width;
cropDetails.dst_height = control.params.height;
return wp.ajax.post( 'crop-image', {
wp_customize: 'on',
nonce: attachment.get( 'nonces' ).edit,
id: attachment.get( 'id' ),
context: control.id,
cropDetails: cropDetails
} );
}
} );
/** /**
* wp.customize.HeaderTool.CurrentView * wp.customize.HeaderTool.CurrentView

View File

@ -1 +1 @@
!function(a,b,c){if(b&&b.customize){var d=b.customize;d.HeaderTool.CurrentView=b.Backbone.View.extend({template:b.template("header-current"),initialize:function(){this.listenTo(this.model,"change",this.render),this.render()},render:function(){return this.$el.html(this.template(this.model.toJSON())),this.setPlaceholder(),this.setButtons(),this},getHeight:function(){var a,b,c,e=this.$el.find("img");return e.length?(this.$el.find(".inner").hide(),a=this.model.get("savedHeight"),b=e.height()||a,b||(c=d.get().header_image_data,b=c&&c.width&&c.height?260/c.width*c.height:40),b):(this.$el.find(".inner").show(),40)},setPlaceholder:function(a){var b=a||this.getHeight();this.model.set("savedHeight",b),this.$el.add(this.$el.find(".placeholder")).height(b)},setButtons:function(){var b=a("#customize-control-header_image .actions .remove");this.model.get("choice")?b.show():b.hide()}}),d.HeaderTool.ChoiceView=b.Backbone.View.extend({template:b.template("header-choice"),className:"header-view",events:{"click .choice,.random":"select","click .close":"removeImage"},initialize:function(){var a=[this.model.get("header").url,this.model.get("choice")];this.listenTo(this.model,"change:selected",this.toggleSelected),c.contains(a,d.get().header_image)&&d.HeaderTool.currentHeader.set(this.extendedModel())},render:function(){return this.$el.html(this.template(this.extendedModel())),this.toggleSelected(),this},toggleSelected:function(){this.$el.toggleClass("selected",this.model.get("selected"))},extendedModel:function(){var a=this.model.get("collection");return c.extend(this.model.toJSON(),{type:a.type})},getHeight:d.HeaderTool.CurrentView.prototype.getHeight,setPlaceholder:d.HeaderTool.CurrentView.prototype.setPlaceholder,select:function(){this.preventJump(),this.model.save(),d.HeaderTool.currentHeader.set(this.extendedModel())},preventJump:function(){var b=a(".wp-full-overlay-sidebar-content"),d=b.scrollTop();c.defer(function(){b.scrollTop(d)})},removeImage:function(a){a.stopPropagation(),this.model.destroy(),this.remove()}}),d.HeaderTool.ChoiceListView=b.Backbone.View.extend({initialize:function(){this.listenTo(this.collection,"add",this.addOne),this.listenTo(this.collection,"remove",this.render),this.listenTo(this.collection,"sort",this.render),this.listenTo(this.collection,"change",this.toggleList),this.render()},render:function(){this.$el.empty(),this.collection.each(this.addOne,this),this.toggleList()},addOne:function(a){var b;a.set({collection:this.collection}),b=new d.HeaderTool.ChoiceView({model:a}),this.$el.append(b.render().el)},toggleList:function(){var a=this.$el.parents().prev(".customize-control-title"),b=this.$el.find(".random").parent();this.collection.shouldHideTitle()?a.add(b).hide():a.add(b).show()}}),d.HeaderTool.CombinedList=b.Backbone.View.extend({initialize:function(a){this.collections=a,this.on("all",this.propagate,this)},propagate:function(a,b){c.each(this.collections,function(c){c.trigger(a,b)})}})}}(jQuery,window.wp,_); !function(a,b,c){if(b&&b.customize){var d=b.customize;b.media.controller.customizeImageCropper=b.media.controller.Cropper.extend({doCrop:function(a){var c=a.get("cropDetails"),d=this.get("control");return c.dst_width=d.params.width,c.dst_height=d.params.height,b.ajax.post("crop-image",{wp_customize:"on",nonce:a.get("nonces").edit,id:a.get("id"),context:d.id,cropDetails:c})}}),d.HeaderTool.CurrentView=b.Backbone.View.extend({template:b.template("header-current"),initialize:function(){this.listenTo(this.model,"change",this.render),this.render()},render:function(){return this.$el.html(this.template(this.model.toJSON())),this.setPlaceholder(),this.setButtons(),this},getHeight:function(){var a,b,c,e=this.$el.find("img");return e.length?(this.$el.find(".inner").hide(),a=this.model.get("savedHeight"),b=e.height()||a,b||(c=d.get().header_image_data,b=c&&c.width&&c.height?260/c.width*c.height:40),b):(this.$el.find(".inner").show(),40)},setPlaceholder:function(a){var b=a||this.getHeight();this.model.set("savedHeight",b),this.$el.add(this.$el.find(".placeholder")).height(b)},setButtons:function(){var b=a("#customize-control-header_image .actions .remove");this.model.get("choice")?b.show():b.hide()}}),d.HeaderTool.ChoiceView=b.Backbone.View.extend({template:b.template("header-choice"),className:"header-view",events:{"click .choice,.random":"select","click .close":"removeImage"},initialize:function(){var a=[this.model.get("header").url,this.model.get("choice")];this.listenTo(this.model,"change:selected",this.toggleSelected),c.contains(a,d.get().header_image)&&d.HeaderTool.currentHeader.set(this.extendedModel())},render:function(){return this.$el.html(this.template(this.extendedModel())),this.toggleSelected(),this},toggleSelected:function(){this.$el.toggleClass("selected",this.model.get("selected"))},extendedModel:function(){var a=this.model.get("collection");return c.extend(this.model.toJSON(),{type:a.type})},getHeight:d.HeaderTool.CurrentView.prototype.getHeight,setPlaceholder:d.HeaderTool.CurrentView.prototype.setPlaceholder,select:function(){this.preventJump(),this.model.save(),d.HeaderTool.currentHeader.set(this.extendedModel())},preventJump:function(){var b=a(".wp-full-overlay-sidebar-content"),d=b.scrollTop();c.defer(function(){b.scrollTop(d)})},removeImage:function(a){a.stopPropagation(),this.model.destroy(),this.remove()}}),d.HeaderTool.ChoiceListView=b.Backbone.View.extend({initialize:function(){this.listenTo(this.collection,"add",this.addOne),this.listenTo(this.collection,"remove",this.render),this.listenTo(this.collection,"sort",this.render),this.listenTo(this.collection,"change",this.toggleList),this.render()},render:function(){this.$el.empty(),this.collection.each(this.addOne,this),this.toggleList()},addOne:function(a){var b;a.set({collection:this.collection}),b=new d.HeaderTool.ChoiceView({model:a}),this.$el.append(b.render().el)},toggleList:function(){var a=this.$el.parents().prev(".customize-control-title"),b=this.$el.find(".random").parent();this.collection.shouldHideTitle()?a.add(b).hide():a.add(b).show()}}),d.HeaderTool.CombinedList=b.Backbone.View.extend({initialize:function(a){this.collections=a,this.on("all",this.propagate,this)},propagate:function(a,b){c.each(this.collections,function(c){c.trigger(a,b)})}})}}(jQuery,window.wp,_);

View File

@ -4,7 +4,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '4.3-beta2-33153'; $wp_version = '4.3-beta2-33154';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.