Add header image uploads with cropping to the customizer.
props mcsf, ehg, gcorne. see #21785. Built from https://develop.svn.wordpress.org/trunk@27497 git-svn-id: http://core.svn.wordpress.org/trunk@27339 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
45bc43515c
commit
a589d9d757
|
@ -455,6 +455,167 @@ body {
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Header control **/
|
||||||
|
|
||||||
|
#customize-control-header_image .current {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: current image container */
|
||||||
|
|
||||||
|
#customize-control-header_image .current .container {
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .placeholder {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
background: #262626;
|
||||||
|
text-align: center;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .inner {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 18px;
|
||||||
|
margin-top: -9px;
|
||||||
|
top: 50%;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: overlay "close" button */
|
||||||
|
|
||||||
|
#customize-control-header_image .header-view {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded .header-view .close {
|
||||||
|
font-size: 2em;
|
||||||
|
color: grey;
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded .header-view .close:hover {
|
||||||
|
color: black;
|
||||||
|
text-shadow:
|
||||||
|
-1px -1px 0 #fff,
|
||||||
|
1px -1px 0 #fff,
|
||||||
|
-1px 1px 0 #fff,
|
||||||
|
1px 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .header-view:hover .close {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: randomiz(s)er */
|
||||||
|
|
||||||
|
#customize-control-header_image .random.placeholder {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .random .inner {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .dice {
|
||||||
|
font-size: 16px;
|
||||||
|
vertical-align: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .placeholder:hover .dice {
|
||||||
|
-webkit-animation: dice-color-change 3s infinite;
|
||||||
|
-moz-animation: dice-color-change 3s infinite;
|
||||||
|
-ms-animation: dice-color-change 3s infinite;
|
||||||
|
animation: dice-color-change 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@-ms-keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: actions and choices */
|
||||||
|
|
||||||
|
#customize-control-header_image .actions {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .choice {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .choice.random:before {
|
||||||
|
position: absolute;
|
||||||
|
content: attr(data-label);
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded div:last-child > .choice {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .choices hr {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .remove {
|
||||||
|
float: right;
|
||||||
|
margin-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .new {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Handle cheaters. */
|
/** Handle cheaters. */
|
||||||
body.cheatin {
|
body.cheatin {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -455,6 +455,167 @@ body {
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Header control **/
|
||||||
|
|
||||||
|
#customize-control-header_image .current {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: current image container */
|
||||||
|
|
||||||
|
#customize-control-header_image .current .container {
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .placeholder {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
background: #262626;
|
||||||
|
text-align: center;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .inner {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 18px;
|
||||||
|
margin-top: -9px;
|
||||||
|
top: 50%;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: overlay "close" button */
|
||||||
|
|
||||||
|
#customize-control-header_image .header-view {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded .header-view .close {
|
||||||
|
font-size: 2em;
|
||||||
|
color: grey;
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded .header-view .close:hover {
|
||||||
|
color: black;
|
||||||
|
text-shadow:
|
||||||
|
-1px -1px 0 #fff,
|
||||||
|
1px -1px 0 #fff,
|
||||||
|
-1px 1px 0 #fff,
|
||||||
|
1px 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .header-view:hover .close {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: randomiz(s)er */
|
||||||
|
|
||||||
|
#customize-control-header_image .random.placeholder {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .random .inner {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .dice {
|
||||||
|
font-size: 16px;
|
||||||
|
vertical-align: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .placeholder:hover .dice {
|
||||||
|
-webkit-animation: dice-color-change 3s infinite;
|
||||||
|
-moz-animation: dice-color-change 3s infinite;
|
||||||
|
-ms-animation: dice-color-change 3s infinite;
|
||||||
|
animation: dice-color-change 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@-ms-keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dice-color-change {
|
||||||
|
0% { color: #d4b146; }
|
||||||
|
50% { color: #ef54b0; }
|
||||||
|
75% { color: #7190d3; }
|
||||||
|
100% { color: #d4b146; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header control: actions and choices */
|
||||||
|
|
||||||
|
#customize-control-header_image .actions {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .choice {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .choice.random:before {
|
||||||
|
position: absolute;
|
||||||
|
content: attr(data-label);
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .uploaded div:last-child > .choice {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .choices hr {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .remove {
|
||||||
|
float: left;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customize-control-header_image .new {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Handle cheaters. */
|
/** Handle cheaters. */
|
||||||
body.cheatin {
|
body.cheatin {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -43,7 +43,7 @@ class Custom_Image_Header {
|
||||||
var $default_headers = array();
|
var $default_headers = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds custom headers uploaded by the user
|
* Holds custom headers uploaded by the user.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @since 3.2.0
|
* @since 3.2.0
|
||||||
|
@ -73,6 +73,11 @@ class Custom_Image_Header {
|
||||||
$this->admin_image_div_callback = $admin_image_div_callback;
|
$this->admin_image_div_callback = $admin_image_div_callback;
|
||||||
|
|
||||||
add_action( 'admin_menu', array( $this, 'init' ) );
|
add_action( 'admin_menu', array( $this, 'init' ) );
|
||||||
|
|
||||||
|
add_action( 'customize_save_after', array( $this, 'customize_set_last_used' ) );
|
||||||
|
add_action( 'wp_ajax_custom-header-crop', array( $this, 'ajax_header_crop' ) );
|
||||||
|
add_action( 'wp_ajax_custom-header-add', array( $this, 'ajax_header_add' ) );
|
||||||
|
add_action( 'wp_ajax_custom-header-remove', array( $this, 'ajax_header_remove' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,6 +98,7 @@ class Custom_Image_Header {
|
||||||
add_action("admin_head-$page", array($this, 'js'), 50);
|
add_action("admin_head-$page", array($this, 'js'), 50);
|
||||||
if ( $this->admin_header_callback )
|
if ( $this->admin_header_callback )
|
||||||
add_action("admin_head-$page", $this->admin_header_callback, 51);
|
add_action("admin_head-$page", $this->admin_header_callback, 51);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -819,32 +825,15 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
|
||||||
$attachment_id = absint( $_POST['attachment_id'] );
|
$attachment_id = absint( $_POST['attachment_id'] );
|
||||||
$original = get_attached_file($attachment_id);
|
$original = get_attached_file($attachment_id);
|
||||||
|
|
||||||
|
$dimensions = $this->get_header_dimensions( array(
|
||||||
$max_width = 0;
|
'height' => $_POST['height'],
|
||||||
// For flex, limit size of image displayed to 1500px unless theme says otherwise
|
'width' => $_POST['width'],
|
||||||
if ( current_theme_supports( 'custom-header', 'flex-width' ) )
|
) );
|
||||||
$max_width = 1500;
|
$height = $dimensions['dst_height'];
|
||||||
|
$width = $dimensions['dst_width'];
|
||||||
if ( current_theme_supports( 'custom-header', 'max-width' ) )
|
|
||||||
$max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) );
|
|
||||||
$max_width = max( $max_width, get_theme_support( 'custom-header', 'width' ) );
|
|
||||||
|
|
||||||
if ( ( current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) || $_POST['width'] > $max_width )
|
|
||||||
$dst_height = absint( $_POST['height'] * ( $max_width / $_POST['width'] ) );
|
|
||||||
elseif ( current_theme_supports( 'custom-header', 'flex-height' ) && current_theme_supports( 'custom-header', 'flex-width' ) )
|
|
||||||
$dst_height = absint( $_POST['height'] );
|
|
||||||
else
|
|
||||||
$dst_height = get_theme_support( 'custom-header', 'height' );
|
|
||||||
|
|
||||||
if ( ( current_theme_supports( 'custom-header', 'flex-width' ) && ! current_theme_supports( 'custom-header', 'flex-height' ) ) || $_POST['width'] > $max_width )
|
|
||||||
$dst_width = absint( $_POST['width'] * ( $max_width / $_POST['width'] ) );
|
|
||||||
elseif ( current_theme_supports( 'custom-header', 'flex-width' ) && current_theme_supports( 'custom-header', 'flex-height' ) )
|
|
||||||
$dst_width = absint( $_POST['width'] );
|
|
||||||
else
|
|
||||||
$dst_width = get_theme_support( 'custom-header', 'width' );
|
|
||||||
|
|
||||||
if ( empty( $_POST['skip-cropping'] ) )
|
if ( empty( $_POST['skip-cropping'] ) )
|
||||||
$cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $dst_width, $dst_height );
|
$cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $width, $height );
|
||||||
elseif ( ! empty( $_POST['create-new-attachment'] ) )
|
elseif ( ! empty( $_POST['create-new-attachment'] ) )
|
||||||
$cropped = _copy_image_file( $attachment_id );
|
$cropped = _copy_image_file( $attachment_id );
|
||||||
else
|
else
|
||||||
|
@ -856,31 +845,15 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
|
||||||
/** This filter is documented in wp-admin/custom-header.php */
|
/** This filter is documented in wp-admin/custom-header.php */
|
||||||
$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication
|
$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication
|
||||||
|
|
||||||
$parent = get_post($attachment_id);
|
$object = $this->create_attachment_object( $cropped, $attachment_id );
|
||||||
$parent_url = $parent->guid;
|
|
||||||
$url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
|
|
||||||
|
|
||||||
$size = @getimagesize( $cropped );
|
|
||||||
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
|
|
||||||
|
|
||||||
// Construct the object array
|
|
||||||
$object = array(
|
|
||||||
'ID' => $attachment_id,
|
|
||||||
'post_title' => basename($cropped),
|
|
||||||
'post_content' => $url,
|
|
||||||
'post_mime_type' => $image_type,
|
|
||||||
'guid' => $url,
|
|
||||||
'context' => 'custom-header'
|
|
||||||
);
|
|
||||||
if ( ! empty( $_POST['create-new-attachment'] ) )
|
if ( ! empty( $_POST['create-new-attachment'] ) )
|
||||||
unset( $object['ID'] );
|
unset( $object['ID'] );
|
||||||
|
|
||||||
// Update the attachment
|
// Update the attachment
|
||||||
$attachment_id = wp_insert_attachment( $object, $cropped );
|
$attachment_id = $this->insert_attachment( $object, $cropped );
|
||||||
wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $cropped ) );
|
|
||||||
|
|
||||||
$width = $dst_width;
|
$url = $object['guid'];
|
||||||
$height = $dst_height;
|
|
||||||
$this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) );
|
$this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) );
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
|
@ -1041,4 +1014,218 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
|
||||||
set_theme_mod( 'header_image', $default );
|
set_theme_mod( 'header_image', $default );
|
||||||
set_theme_mod( 'header_image_data', (object) $default_data );
|
set_theme_mod( 'header_image_data', (object) $default_data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate width and height based on what the currently selected theme supports.
|
||||||
|
*
|
||||||
|
* @return array dst_height and dst_width of header image.
|
||||||
|
*/
|
||||||
|
final public function get_header_dimensions( $dimensions ) {
|
||||||
|
$max_width = 0;
|
||||||
|
$width = absint( $dimensions['width'] );
|
||||||
|
$height = absint( $dimensions['height'] );
|
||||||
|
$theme_height = get_theme_support( 'custom-header', 'height' );
|
||||||
|
$theme_width = get_theme_support( 'custom-header', 'width' );
|
||||||
|
$has_flex_width = current_theme_supports( 'custom-header', 'flex-width' );
|
||||||
|
$has_flex_height = current_theme_supports( 'custom-header', 'flex-height' );
|
||||||
|
$has_max_width = current_theme_supports( 'custom-header', 'max-width' ) ;
|
||||||
|
$dst = array( 'dst_height' => null, 'dst_height' => null );
|
||||||
|
|
||||||
|
// For flex, limit size of image displayed to 1500px unless theme says otherwise
|
||||||
|
if ( $has_flex_width ) {
|
||||||
|
$max_width = 1500;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $has_max_width ) {
|
||||||
|
$max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) );
|
||||||
|
}
|
||||||
|
$max_width = max( $max_width, $theme_width );
|
||||||
|
|
||||||
|
if ( $has_flex_height && ( ! $has_flex_width || $width > $max_width ) ) {
|
||||||
|
$dst['dst_height'] = absint( $height * ( $max_width / $width ) );
|
||||||
|
}
|
||||||
|
elseif ( $has_flex_height && $has_flex_width ) {
|
||||||
|
$dst['dst_height'] = $height;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$dst['dst_height'] = $theme_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $has_flex_width && ( ! $has_flex_height || $width > $max_width ) ) {
|
||||||
|
$dst['dst_width'] = absint( $width * ( $max_width / $width ) );
|
||||||
|
}
|
||||||
|
elseif ( $has_flex_width && $has_flex_height ) {
|
||||||
|
$dst['dst_width'] = $width;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$dst['dst_width'] = $theme_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an attachment 'object'.
|
||||||
|
*
|
||||||
|
* @param string $cropped Cropped image URL.
|
||||||
|
* @param int $parent_attachment_id Attachment ID of parent image.
|
||||||
|
*
|
||||||
|
* @return array Attachment object.
|
||||||
|
*/
|
||||||
|
final public function create_attachment_object( $cropped, $parent_attachment_id ) {
|
||||||
|
$parent = get_post( $parent_attachment_id );
|
||||||
|
$parent_url = $parent->guid;
|
||||||
|
$url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
|
||||||
|
|
||||||
|
$size = @getimagesize( $cropped );
|
||||||
|
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
|
||||||
|
|
||||||
|
$object = array(
|
||||||
|
'ID' => $parent_attachment_id,
|
||||||
|
'post_title' => basename($cropped),
|
||||||
|
'post_content' => $url,
|
||||||
|
'post_mime_type' => $image_type,
|
||||||
|
'guid' => $url,
|
||||||
|
'context' => 'custom-header'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert an attachment & its metadata.
|
||||||
|
*
|
||||||
|
* @param array $object Attachment object.
|
||||||
|
* @param string $cropped Cropped image URL.
|
||||||
|
*
|
||||||
|
* @return int Attachment ID.
|
||||||
|
*/
|
||||||
|
final public function insert_attachment( $object, $cropped ) {
|
||||||
|
$attachment_id = wp_insert_attachment( $object, $cropped );
|
||||||
|
$metadata = wp_generate_attachment_metadata( $attachment_id, $cropped );
|
||||||
|
/**
|
||||||
|
* Allows us to insert custom meta data for an attachment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
$metadata = apply_filters( 'wp_header_image_attachment_metadata', $metadata );
|
||||||
|
wp_update_attachment_metadata( $attachment_id, $metadata );
|
||||||
|
return $attachment_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets attachment uploaded by Media Manager, crops it, then saves it as a
|
||||||
|
* new object. Returns JSON-encoded object details.
|
||||||
|
*/
|
||||||
|
function ajax_header_crop() {
|
||||||
|
check_ajax_referer( 'image_editor-' . $_POST['id'], 'nonce' );
|
||||||
|
|
||||||
|
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! current_theme_supports( 'custom-header', 'uploads' ) ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
$crop_details = $_POST['cropDetails'];
|
||||||
|
|
||||||
|
$dimensions = $this->get_header_dimensions( array(
|
||||||
|
'height' => $crop_details['height'],
|
||||||
|
'width' => $crop_details['width'],
|
||||||
|
) );
|
||||||
|
|
||||||
|
$attachment_id = absint( $_POST['id'] );
|
||||||
|
|
||||||
|
$cropped = wp_crop_image(
|
||||||
|
$attachment_id,
|
||||||
|
(int) $crop_details['x1'],
|
||||||
|
(int) $crop_details['y1'],
|
||||||
|
(int) $crop_details['width'],
|
||||||
|
(int) $crop_details['height'],
|
||||||
|
(int) $dimensions['dst_width'],
|
||||||
|
(int) $dimensions['dst_height']
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( ! $cropped || is_wp_error( $cropped ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Image could not be processed. Please go back and try again.' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication
|
||||||
|
|
||||||
|
$object = $this->create_attachment_object( $cropped, $attachment_id );
|
||||||
|
|
||||||
|
unset( $object['ID'] );
|
||||||
|
|
||||||
|
$new_attachment_id = $this->insert_attachment( $object, $cropped );
|
||||||
|
|
||||||
|
$object['attachment_id'] = $new_attachment_id;
|
||||||
|
$object['width'] = $dimensions['dst_width'];
|
||||||
|
$object['height'] = $dimensions['dst_height'];
|
||||||
|
|
||||||
|
wp_send_json_success( $object );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an attachment ID for a header image, updates its "last used"
|
||||||
|
* timestamp to now.
|
||||||
|
*
|
||||||
|
* Triggered when the user tries adds a new header image from the
|
||||||
|
* Media Manager, even if s/he doesn't save that change.
|
||||||
|
*/
|
||||||
|
function ajax_header_add() {
|
||||||
|
check_ajax_referer( 'header-add', 'nonce' );
|
||||||
|
|
||||||
|
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
$attachment_id = absint( $_POST['attachment_id'] );
|
||||||
|
if ( $attachment_id < 1 ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||||
|
update_post_meta( $attachment_id, $key, time() );
|
||||||
|
update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
|
||||||
|
|
||||||
|
wp_send_json_success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an attachment ID for a header image, unsets it as a user-uploaded
|
||||||
|
* header image for the current theme.
|
||||||
|
*
|
||||||
|
* Triggered when the user clicks the overlay "X" button next to each image
|
||||||
|
* choice in the Customizer's Header tool.
|
||||||
|
*/
|
||||||
|
function ajax_header_remove() {
|
||||||
|
check_ajax_referer( 'header-remove', 'nonce' );
|
||||||
|
|
||||||
|
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
$attachment_id = absint( $_POST['attachment_id'] );
|
||||||
|
if ( $attachment_id < 1 ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||||
|
delete_post_meta( $attachment_id, $key );
|
||||||
|
delete_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
|
||||||
|
|
||||||
|
wp_send_json_success();
|
||||||
|
}
|
||||||
|
|
||||||
|
function customize_set_last_used( $wp_customize ) {
|
||||||
|
$data = $wp_customize->get_setting( 'header_image_data' )->post_value();
|
||||||
|
|
||||||
|
if ( ! isset( $data['attachment_id'] ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attachment_id = $data['attachment_id'];
|
||||||
|
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||||
|
update_post_meta( $attachment_id, $key, time() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* globals _wpCustomizeHeader, _wpMediaViewsL10n */
|
||||||
(function( exports, $ ){
|
(function( exports, $ ){
|
||||||
var api = wp.customize;
|
var api = wp.customize;
|
||||||
|
|
||||||
|
@ -306,6 +307,217 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
api.HeaderControl = api.Control.extend({
|
||||||
|
ready: function() {
|
||||||
|
this.btnRemove = $('.actions .remove');
|
||||||
|
this.btnNew = $('.actions .new');
|
||||||
|
|
||||||
|
_.bindAll(this, 'openMedia', 'removeImage');
|
||||||
|
|
||||||
|
this.btnNew.on( 'click', this.openMedia );
|
||||||
|
this.btnRemove.on( 'click', this.removeImage );
|
||||||
|
|
||||||
|
api.HeaderTool.currentHeader = new api.HeaderTool.ImageModel();
|
||||||
|
|
||||||
|
new api.HeaderTool.CurrentView({
|
||||||
|
model: api.HeaderTool.currentHeader,
|
||||||
|
el: '.current .container'
|
||||||
|
});
|
||||||
|
|
||||||
|
new api.HeaderTool.ChoiceListView({
|
||||||
|
collection: api.HeaderTool.UploadsList = new api.HeaderTool.ChoiceList(),
|
||||||
|
el: '.choices .uploaded .list'
|
||||||
|
});
|
||||||
|
|
||||||
|
new api.HeaderTool.ChoiceListView({
|
||||||
|
collection: api.HeaderTool.DefaultsList = new api.HeaderTool.DefaultsList(),
|
||||||
|
el: '.choices .default .list'
|
||||||
|
});
|
||||||
|
|
||||||
|
api.HeaderTool.combinedList = api.HeaderTool.CombinedList = new api.HeaderTool.CombinedList([
|
||||||
|
api.HeaderTool.UploadsList,
|
||||||
|
api.HeaderTool.DefaultsList
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set of options, computed from the attached image data and
|
||||||
|
* theme-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 xInit = parseInt(_wpCustomizeHeader.data.width, 10),
|
||||||
|
yInit = parseInt(_wpCustomizeHeader.data.height, 10),
|
||||||
|
flexWidth = !! parseInt(_wpCustomizeHeader.data['flex-width'], 10),
|
||||||
|
flexHeight = !! parseInt(_wpCustomizeHeader.data['flex-height'], 10),
|
||||||
|
ratio, xImg, yImg, realHeight, realWidth,
|
||||||
|
imgSelectOptions;
|
||||||
|
|
||||||
|
realWidth = attachment.get('width');
|
||||||
|
realHeight = attachment.get('height');
|
||||||
|
|
||||||
|
this.headerImage = new api.HeaderTool.ImageModel();
|
||||||
|
this.headerImage.set({
|
||||||
|
themeWidth: xInit,
|
||||||
|
themeHeight: yInit,
|
||||||
|
themeFlexWidth: flexWidth,
|
||||||
|
themeFlexHeight: flexHeight,
|
||||||
|
imageWidth: realWidth,
|
||||||
|
imageHeight: realHeight
|
||||||
|
});
|
||||||
|
|
||||||
|
controller.set( 'canSkipCrop', ! this.headerImage.shouldBeCropped() );
|
||||||
|
|
||||||
|
ratio = xInit / yInit;
|
||||||
|
xImg = realWidth;
|
||||||
|
yImg = 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,
|
||||||
|
parent: this.$el,
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up and opens the Media Manager in order to select an image.
|
||||||
|
* Depending on both the size of the image and the properties of the
|
||||||
|
* current theme, a cropping step after selection may be required or
|
||||||
|
* skippable.
|
||||||
|
*
|
||||||
|
* @param {event} event
|
||||||
|
*/
|
||||||
|
openMedia: function(event) {
|
||||||
|
var title, suggestedWidth, suggestedHeight,
|
||||||
|
l10n = _wpMediaViewsL10n;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
suggestedWidth = l10n.suggestedWidth.replace('%d', _wpCustomizeHeader.data.width);
|
||||||
|
suggestedHeight = l10n.suggestedHeight.replace('%d', _wpCustomizeHeader.data.height);
|
||||||
|
|
||||||
|
/* '<span class="suggested-dimensions">' + suggestedWidth + ' ' + suggestedHeight + '</span>' */
|
||||||
|
|
||||||
|
this.frame = wp.media({
|
||||||
|
title: l10n.chooseImage,
|
||||||
|
library: {
|
||||||
|
type: 'image'
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
text: l10n.selectAndCrop,
|
||||||
|
close: false
|
||||||
|
},
|
||||||
|
multiple: false,
|
||||||
|
imgSelectOptions: this.calculateImageSelectOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
this.frame.states.add([new wp.media.controller.Cropper()]);
|
||||||
|
|
||||||
|
this.frame.on('select', this.onSelect, this);
|
||||||
|
this.frame.on('cropped', this.onCropped, this);
|
||||||
|
this.frame.on('skippedcrop', this.onSkippedCrop, this);
|
||||||
|
|
||||||
|
this.frame.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelect: function() {
|
||||||
|
this.frame.setState('cropper');
|
||||||
|
},
|
||||||
|
onCropped: function(croppedImage) {
|
||||||
|
var url = croppedImage.post_content,
|
||||||
|
attachmentId = croppedImage.attachment_id,
|
||||||
|
w = croppedImage.width,
|
||||||
|
h = croppedImage.height;
|
||||||
|
this.setImageFromURL(url, attachmentId, w, h);
|
||||||
|
},
|
||||||
|
onSkippedCrop: function(selection) {
|
||||||
|
var url = selection.get('url'),
|
||||||
|
w = selection.get('width'),
|
||||||
|
h = selection.get('height');
|
||||||
|
this.setImageFromURL(url, selection.id, w, h);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new wp.customize.HeaderTool.ImageModel from provided
|
||||||
|
* header image data and inserts it into the user-uploaded headers
|
||||||
|
* collection.
|
||||||
|
*
|
||||||
|
* @param {String} url
|
||||||
|
* @param {Number} attachmentId
|
||||||
|
* @param {Number} width
|
||||||
|
* @param {Number} height
|
||||||
|
*/
|
||||||
|
setImageFromURL: function(url, attachmentId, width, height) {
|
||||||
|
var choice, data = {};
|
||||||
|
|
||||||
|
data.url = url;
|
||||||
|
data.thumbnail_url = url;
|
||||||
|
|
||||||
|
if (attachmentId) {
|
||||||
|
data.attachment_id = attachmentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width) {
|
||||||
|
data.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height) {
|
||||||
|
data.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
choice = new api.HeaderTool.ImageModel({
|
||||||
|
header: data,
|
||||||
|
choice: url.split('/').pop()
|
||||||
|
});
|
||||||
|
api.HeaderTool.UploadsList.add(choice);
|
||||||
|
api.HeaderTool.currentHeader.set(choice.toJSON());
|
||||||
|
choice.save();
|
||||||
|
choice.importImage();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the necessary events to deselect an image which was set as
|
||||||
|
* the currently selected one.
|
||||||
|
*/
|
||||||
|
removeImage: function() {
|
||||||
|
api.HeaderTool.currentHeader.trigger('hide');
|
||||||
|
api.HeaderTool.CombinedList.trigger('control:removeImage');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// Change objects contained within the main customize object to Settings.
|
// Change objects contained within the main customize object to Settings.
|
||||||
api.defaultConstructor = api.Setting;
|
api.defaultConstructor = api.Setting;
|
||||||
|
|
||||||
|
@ -686,7 +898,8 @@
|
||||||
api.controlConstructor = {
|
api.controlConstructor = {
|
||||||
color: api.ColorControl,
|
color: api.ColorControl,
|
||||||
upload: api.UploadControl,
|
upload: api.UploadControl,
|
||||||
image: api.ImageControl
|
image: api.ImageControl,
|
||||||
|
header: api.HeaderControl
|
||||||
};
|
};
|
||||||
|
|
||||||
$( function() {
|
$( function() {
|
||||||
|
@ -961,35 +1174,6 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle header image data
|
|
||||||
api.control( 'header_image', function( control ) {
|
|
||||||
control.setting.bind( function( to ) {
|
|
||||||
if ( to === control.params.removed )
|
|
||||||
control.settings.data.set( false );
|
|
||||||
});
|
|
||||||
|
|
||||||
control.library.on( 'click', 'a', function() {
|
|
||||||
control.settings.data.set( $(this).data('customizeHeaderImageData') );
|
|
||||||
});
|
|
||||||
|
|
||||||
control.uploader.success = function( attachment ) {
|
|
||||||
var data;
|
|
||||||
|
|
||||||
api.ImageControl.prototype.success.call( control, attachment );
|
|
||||||
|
|
||||||
data = {
|
|
||||||
attachment_id: attachment.get('id'),
|
|
||||||
url: attachment.get('url'),
|
|
||||||
thumbnail_url: attachment.get('url'),
|
|
||||||
height: attachment.get('height'),
|
|
||||||
width: attachment.get('width')
|
|
||||||
};
|
|
||||||
|
|
||||||
attachment.element.data( 'customizeHeaderImageData', data );
|
|
||||||
control.settings.data.set( data );
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
api.trigger( 'ready' );
|
api.trigger( 'ready' );
|
||||||
|
|
||||||
// Make sure left column gets focus
|
// Make sure left column gets focus
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -708,37 +708,9 @@ class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
final class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
|
||||||
* Customize Header Image Control Class
|
public $type = 'header';
|
||||||
*
|
|
||||||
* @package WordPress
|
|
||||||
* @subpackage Customize
|
|
||||||
* @since 3.4.0
|
|
||||||
*/
|
|
||||||
class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
|
|
||||||
/**
|
|
||||||
* The processed default headers.
|
|
||||||
* @since 3.4.2
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $default_headers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The uploaded headers.
|
|
||||||
* @since 3.4.2
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $uploaded_headers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @since 3.4.0
|
|
||||||
* @uses WP_Customize_Image_Control::__construct()
|
|
||||||
* @uses WP_Customize_Image_Control::add_tab()
|
|
||||||
*
|
|
||||||
* @param WP_Customize_Manager $manager
|
|
||||||
*/
|
|
||||||
public function __construct( $manager ) {
|
public function __construct( $manager ) {
|
||||||
parent::__construct( $manager, 'header_image', array(
|
parent::__construct( $manager, 'header_image', array(
|
||||||
'label' => __( 'Header Image' ),
|
'label' => __( 'Header Image' ),
|
||||||
|
@ -750,86 +722,305 @@ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
|
||||||
'context' => 'custom-header',
|
'context' => 'custom-header',
|
||||||
'removed' => 'remove-header',
|
'removed' => 'remove-header',
|
||||||
'get_url' => 'get_header_image',
|
'get_url' => 'get_header_image',
|
||||||
'statuses' => array(
|
) );
|
||||||
'' => __('Default'),
|
|
||||||
'remove-header' => __('No Image'),
|
}
|
||||||
'random-default-image' => __('Random Default Image'),
|
|
||||||
'random-uploaded-image' => __('Random Uploaded Image'),
|
public function to_json() {
|
||||||
|
parent::to_json();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function enqueue() {
|
||||||
|
wp_enqueue_media();
|
||||||
|
wp_enqueue_script( 'customize-views' );
|
||||||
|
|
||||||
|
$this->prepare_control();
|
||||||
|
|
||||||
|
wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(
|
||||||
|
'data' => array(
|
||||||
|
'width' => absint( get_theme_support( 'custom-header', 'width' ) ),
|
||||||
|
'height' => absint( get_theme_support( 'custom-header', 'height' ) ),
|
||||||
|
'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),
|
||||||
|
'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),
|
||||||
|
'currentImgSrc' => $this->get_current_image_src(),
|
||||||
|
),
|
||||||
|
'nonces' => array(
|
||||||
|
'add' => wp_create_nonce( 'header-add' ),
|
||||||
|
'remove' => wp_create_nonce( 'header-remove' ),
|
||||||
|
),
|
||||||
|
'l10n' => array(
|
||||||
|
/* translators: header images uploaded by user */
|
||||||
|
'uploaded' => __( 'uploaded' ),
|
||||||
|
/* translators: header images suggested by the current theme */
|
||||||
|
'default' => __( 'suggested' )
|
||||||
|
),
|
||||||
|
'uploads' => $this->uploaded_headers,
|
||||||
|
'defaults' => $this->default_headers
|
||||||
|
) );
|
||||||
|
|
||||||
|
parent::enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_default_header_images() {
|
||||||
|
global $custom_image_header;
|
||||||
|
|
||||||
|
// Get *the* default image if there is one
|
||||||
|
$default = get_theme_support( 'custom-header', 'default-image' );
|
||||||
|
|
||||||
|
if ( ! $default ) { // If not,
|
||||||
|
return $custom_image_header->default_headers; // easy peasy.
|
||||||
|
}
|
||||||
|
|
||||||
|
$default = sprintf( $default,
|
||||||
|
get_template_directory_uri(),
|
||||||
|
get_stylesheet_directory_uri() );
|
||||||
|
|
||||||
|
$header_images = array();
|
||||||
|
$already_has_default = false;
|
||||||
|
|
||||||
|
// Get the whole set of default images
|
||||||
|
$default_header_images = $custom_image_header->default_headers;
|
||||||
|
foreach ( $default_header_images as $k => $h ) {
|
||||||
|
if ( $h['url'] == $default ) {
|
||||||
|
$already_has_default = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If *the one true image* isn't included in the default set, add it in
|
||||||
|
// first position
|
||||||
|
if ( ! $already_has_default ) {
|
||||||
|
$header_images['default'] = array(
|
||||||
|
'url' => $default,
|
||||||
|
'thumbnail_url' => $default,
|
||||||
|
'description' => 'Default'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The rest of the set comes after
|
||||||
|
$header_images = array_merge( $header_images, $default_header_images );
|
||||||
|
|
||||||
|
return $header_images;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_uploaded_header_images() {
|
||||||
|
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||||
|
$header_images = array();
|
||||||
|
|
||||||
|
$headers_not_dated = get_posts( array(
|
||||||
|
'post_type' => 'attachment',
|
||||||
|
'meta_key' => '_wp_attachment_is_custom_header',
|
||||||
|
'meta_value' => get_option('stylesheet'),
|
||||||
|
'orderby' => 'none',
|
||||||
|
'nopaging' => true,
|
||||||
|
'meta_query' => array(
|
||||||
|
array(
|
||||||
|
'key' => '_wp_attachment_is_custom_header',
|
||||||
|
'value' => get_option( 'stylesheet' ),
|
||||||
|
'compare' => 'LIKE'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'key' => $key,
|
||||||
|
'value' => 'this string must not be empty',
|
||||||
|
'compare' => 'NOT EXISTS'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
) );
|
) );
|
||||||
|
|
||||||
// Remove the upload tab.
|
$headers_dated = get_posts( array(
|
||||||
$this->remove_tab( 'upload-new' );
|
'post_type' => 'attachment',
|
||||||
|
'meta_key' => $key,
|
||||||
|
'orderby' => 'meta_value_num',
|
||||||
|
'order' => 'DESC',
|
||||||
|
'nopaging' => true,
|
||||||
|
'meta_query' => array(
|
||||||
|
array(
|
||||||
|
'key' => '_wp_attachment_is_custom_header',
|
||||||
|
'value' => get_option( 'stylesheet' ),
|
||||||
|
'compare' => 'LIKE'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) );
|
||||||
|
|
||||||
|
$limit = apply_filters( 'custom_header_uploaded_limit', 15 );
|
||||||
|
$headers = array_merge( $headers_dated, $headers_not_dated );
|
||||||
|
$headers = array_slice( $headers, 0, $limit );
|
||||||
|
|
||||||
|
foreach ( (array) $headers as $header ) {
|
||||||
|
$url = esc_url_raw( $header->guid );
|
||||||
|
$header_data = wp_get_attachment_metadata( $header->ID );
|
||||||
|
$timestamp = get_post_meta( $header->ID,
|
||||||
|
'_wp_attachment_custom_header_last_used_' . get_stylesheet(),
|
||||||
|
true );
|
||||||
|
|
||||||
|
$h = array(
|
||||||
|
'attachment_id' => $header->ID,
|
||||||
|
'url' => $url,
|
||||||
|
'thumbnail_url' => $url,
|
||||||
|
'timestamp' => $timestamp ? $timestamp : 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( isset( $header_data['width'] ) ) {
|
||||||
|
$h['width'] = $header_data['width'];
|
||||||
|
}
|
||||||
|
if ( isset( $header_data['height'] ) ) {
|
||||||
|
$h['height'] = $header_data['height'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$header_images[] = $h;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $header_images;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepares the control.
|
|
||||||
*
|
|
||||||
* If no tabs exist, removes the control from the manager.
|
|
||||||
*
|
|
||||||
* @since 3.4.2
|
|
||||||
*/
|
|
||||||
public function prepare_control() {
|
public function prepare_control() {
|
||||||
global $custom_image_header;
|
global $custom_image_header;
|
||||||
if ( empty( $custom_image_header ) )
|
if ( empty( $custom_image_header ) ) {
|
||||||
return parent::prepare_control();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Process default headers and uploaded headers.
|
// Process default headers and uploaded headers.
|
||||||
$custom_image_header->process_default_headers();
|
$custom_image_header->process_default_headers();
|
||||||
$this->default_headers = $custom_image_header->default_headers;
|
$this->default_headers = $this->get_default_header_images();
|
||||||
$this->uploaded_headers = get_uploaded_header_images();
|
$this->uploaded_headers = $this->get_uploaded_header_images();
|
||||||
|
|
||||||
if ( $this->default_headers )
|
|
||||||
$this->add_tab( 'default', __('Default'), array( $this, 'tab_default_headers' ) );
|
|
||||||
|
|
||||||
if ( ! $this->uploaded_headers )
|
|
||||||
$this->remove_tab( 'uploaded' );
|
|
||||||
|
|
||||||
return parent::prepare_control();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function print_header_image_template() {
|
||||||
* @since 3.4.0
|
|
||||||
*
|
|
||||||
* @param mixed $choice Which header image to select. (@see Custom_Image_Header::get_header_image() )
|
|
||||||
* @param array $header
|
|
||||||
*/
|
|
||||||
public function print_header_image( $choice, $header ) {
|
|
||||||
$header['url'] = set_url_scheme( $header['url'] );
|
|
||||||
$header['thumbnail_url'] = set_url_scheme( $header['thumbnail_url'] );
|
|
||||||
|
|
||||||
$header_image_data = array( 'choice' => $choice );
|
|
||||||
foreach ( array( 'attachment_id', 'width', 'height', 'url', 'thumbnail_url' ) as $key ) {
|
|
||||||
if ( isset( $header[ $key ] ) )
|
|
||||||
$header_image_data[ $key ] = $header[ $key ];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<a href="#" class="thumbnail"
|
<script type="text/template" id="tmpl-header-choice">
|
||||||
data-customize-image-value="<?php echo esc_url( $header['url'] ); ?>"
|
<# if (data.random) { #>
|
||||||
data-customize-header-image-data="<?php echo esc_attr( json_encode( $header_image_data ) ); ?>">
|
|
||||||
<img src="<?php echo esc_url( $header['thumbnail_url'] ); ?>" />
|
<div class="placeholder random">
|
||||||
</a>
|
<div class="inner">
|
||||||
|
<span><span class="dice">⚄</span>
|
||||||
|
<# if ( data.type === 'uploaded' ) { #>
|
||||||
|
<?php _e( 'Randomize uploaded headers' ); ?>
|
||||||
|
<# } else if ( data.type === 'suggested' ) { #>
|
||||||
|
<?php _e( 'Randomize suggested headers' ); ?>
|
||||||
|
<# } #>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<# } else { #>
|
||||||
|
|
||||||
|
<# if (data.type === 'uploaded') { #>
|
||||||
|
<div class="dashicons dashicons-no close"></div>
|
||||||
|
<# } #>
|
||||||
|
|
||||||
|
<a href="#" class="choice thumbnail #>"
|
||||||
|
data-customize-image-value="{{{data.header.url}}}"
|
||||||
|
data-customize-header-image-data="{{JSON.stringify(data.header)}}">
|
||||||
|
<img src="{{{data.header.thumbnail_url}}}">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<# } #>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="tmpl-header-current">
|
||||||
|
<# if (data.choice) { #>
|
||||||
|
<# if (data.random) { #>
|
||||||
|
|
||||||
|
<div class="placeholder">
|
||||||
|
<div class="inner">
|
||||||
|
<span><span class="dice">⚄</span>
|
||||||
|
<# if ( data.type === 'uploaded' ) { #>
|
||||||
|
<?php _e( 'Randomizing uploaded headers' ); ?>
|
||||||
|
<# } else if ( data.type === 'suggested' ) { #>
|
||||||
|
<?php _e( 'Randomizing suggested headers' ); ?>
|
||||||
|
<# } #>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<# } else { #>
|
||||||
|
|
||||||
|
<img src="{{{data.header.thumbnail_url}}}" />
|
||||||
|
|
||||||
|
<# } #>
|
||||||
|
<# } else { #>
|
||||||
|
|
||||||
|
<div class="placeholder">
|
||||||
|
<div class="inner">
|
||||||
|
<span>
|
||||||
|
<?php _e( 'No image set' ); ?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<# } #>
|
||||||
|
</script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function get_current_image_src() {
|
||||||
* @since 3.4.0
|
$src = $this->value();
|
||||||
*/
|
if ( isset( $this->get_url ) ) {
|
||||||
public function tab_uploaded() {
|
$src = call_user_func( $this->get_url, $src );
|
||||||
?><div class="uploaded-target"></div><?php
|
return $src;
|
||||||
|
}
|
||||||
foreach ( $this->uploaded_headers as $choice => $header )
|
return null;
|
||||||
$this->print_header_image( $choice, $header );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function render_content() {
|
||||||
* @since 3.4.0
|
$this->print_header_image_template();
|
||||||
*/
|
$visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
|
||||||
public function tab_default_headers() {
|
$width = absint( get_theme_support( 'custom-header', 'width' ) );
|
||||||
foreach ( $this->default_headers as $choice => $header )
|
$height = absint( get_theme_support( 'custom-header', 'height' ) );
|
||||||
$this->print_header_image( $choice, $header );
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="customize-control-content">
|
||||||
|
<p class="customizer-section-intro">
|
||||||
|
<?php _e( 'Personalize your site with your own header image.' ); ?>
|
||||||
|
<?php
|
||||||
|
if ( $width && $height ) {
|
||||||
|
printf( __( 'While you can crop images to your liking after clicking <strong>%s</strong>, your theme recommends a header size of <strong>%dx%d</strong> pixels.' ),
|
||||||
|
_x( 'Add new', 'header image' ), $width, $height );
|
||||||
|
} else {
|
||||||
|
if ( $width ) {
|
||||||
|
printf( __( 'While you can crop images to your liking after clicking <strong>%s</strong>, your theme recommends a header width of <strong>%d</strong> pixels.' ),
|
||||||
|
_x( 'Add new', 'header image' ), $width );
|
||||||
|
}
|
||||||
|
if ( $height ) {
|
||||||
|
printf( __( 'While you can crop images to your liking after clicking <strong>%s</strong>, your theme recommends a header height of <strong>%d</strong> pixels.' ),
|
||||||
|
_x( 'Add new', 'header image' ), $height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
<div class="current">
|
||||||
|
<span class="customize-control-title">
|
||||||
|
<?php _e( 'Current header' ); ?>
|
||||||
|
</span>
|
||||||
|
<div class="container">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="actions">
|
||||||
|
<?php /* translators: Hide as in hide header image via the Customizer */ ?>
|
||||||
|
<a href="#" <?php echo $visibility ?> class="button remove"><?php _ex( 'Hide', 'custom header' ); ?></a>
|
||||||
|
<?php /* translators: New as in add new header image via the Customizer */ ?>
|
||||||
|
<a href="#" class="button new"><?php _ex( 'Add new', 'header image' ); ?></a>
|
||||||
|
<div style="clear:both"></div>
|
||||||
|
</div>
|
||||||
|
<div class="choices">
|
||||||
|
<span class="customize-control-title header-previously-uploaded">
|
||||||
|
<?php _ex( 'Previously uploaded', 'custom headers' ); ?>
|
||||||
|
</span>
|
||||||
|
<div class="uploaded">
|
||||||
|
<div class="list">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="customize-control-title header-default">
|
||||||
|
<?php _ex( 'Suggested', 'custom headers' ); ?>
|
||||||
|
</span>
|
||||||
|
<div class="default">
|
||||||
|
<div class="list">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -602,6 +602,19 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-frame-title .suggested-dimensions {
|
||||||
|
font-size: 14px;
|
||||||
|
float: left;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-frame-content .crop-content {
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iframes
|
* Iframes
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -602,6 +602,19 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-frame-title .suggested-dimensions {
|
||||||
|
font-size: 14px;
|
||||||
|
float: right;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-frame-content .crop-content {
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iframes
|
* Iframes
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,249 @@
|
||||||
|
/* globals _wpCustomizeHeader, _wpCustomizeSettings */
|
||||||
|
(function( $, wp ) {
|
||||||
|
var api = wp.customize;
|
||||||
|
api.HeaderTool = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.ImageModel
|
||||||
|
*
|
||||||
|
* A header image. This is where saves via the Customizer API are
|
||||||
|
* abstracted away, plus our own AJAX calls to add images to and remove
|
||||||
|
* images from the user's recently uploaded images setting on the server.
|
||||||
|
* These calls are made regardless of whether the user actually saves new
|
||||||
|
* Customizer settings.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments Backbone.Model
|
||||||
|
*/
|
||||||
|
api.HeaderTool.ImageModel = Backbone.Model.extend({
|
||||||
|
defaults: function() {
|
||||||
|
return {
|
||||||
|
header: {
|
||||||
|
attachment_id: 0,
|
||||||
|
url: '',
|
||||||
|
timestamp: Date.now(),
|
||||||
|
thumbnail_url: ''
|
||||||
|
},
|
||||||
|
choice: '',
|
||||||
|
hidden: false,
|
||||||
|
random: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.on('hide', this.hide, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
this.set('choice', '');
|
||||||
|
api('header_image').set('remove-header');
|
||||||
|
api('header_image_data').set('remove-header');
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
var data = this.get('header'),
|
||||||
|
curr = api.HeaderTool.currentHeader.get('header').attachment_id;
|
||||||
|
|
||||||
|
// If the image we're removing is also the current header, unset
|
||||||
|
// the latter
|
||||||
|
if (curr && data.attachment_id === curr) {
|
||||||
|
api.HeaderTool.currentHeader.trigger('hide');
|
||||||
|
}
|
||||||
|
|
||||||
|
wp.ajax.post( 'custom-header-remove', {
|
||||||
|
nonce: _wpCustomizeHeader.nonces.remove,
|
||||||
|
wp_customize: 'on',
|
||||||
|
theme: api.settings.theme.stylesheet,
|
||||||
|
attachment_id: data.attachment_id
|
||||||
|
});
|
||||||
|
|
||||||
|
this.trigger('destroy', this, this.collection);
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function() {
|
||||||
|
if (this.get('random')) {
|
||||||
|
api('header_image').set(this.get('header').random);
|
||||||
|
api('header_image_data').set(this.get('header').random);
|
||||||
|
} else {
|
||||||
|
if (this.get('header').defaultName) {
|
||||||
|
api('header_image').set(this.get('header').url);
|
||||||
|
api('header_image_data').set(this.get('header').defaultName);
|
||||||
|
} else {
|
||||||
|
api('header_image').set(this.get('header').url);
|
||||||
|
api('header_image_data').set(this.get('header'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
api.HeaderTool.combinedList.trigger('control:setImage', this);
|
||||||
|
},
|
||||||
|
|
||||||
|
importImage: function() {
|
||||||
|
var data = this.get('header');
|
||||||
|
if (data.attachment_id === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp.ajax.post( 'custom-header-add', {
|
||||||
|
nonce: _wpCustomizeHeader.nonces.add,
|
||||||
|
wp_customize: 'on',
|
||||||
|
theme: api.settings.theme.stylesheet,
|
||||||
|
attachment_id: data.attachment_id,
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
|
||||||
|
shouldBeCropped: function() {
|
||||||
|
if (this.get('themeFlexWidth') === true &&
|
||||||
|
this.get('themeFlexHeight') === true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.get('themeFlexWidth') === true &&
|
||||||
|
this.get('themeHeight') === this.get('imageHeight')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.get('themeFlexHeight') === true &&
|
||||||
|
this.get('themeWidth') === this.get('imageWidth')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.get('themeWidth') === this.get('imageWidth') &&
|
||||||
|
this.get('themeHeight') === this.get('imageHeight')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.ChoiceList
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments Backbone.Collection
|
||||||
|
*/
|
||||||
|
api.HeaderTool.ChoiceList = Backbone.Collection.extend({
|
||||||
|
model: api.HeaderTool.ImageModel,
|
||||||
|
|
||||||
|
// Ordered from most recently used to least
|
||||||
|
comparator: function(model) {
|
||||||
|
return -model.get('header').timestamp;
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
var current = api.HeaderTool.currentHeader.get('choice').replace(/^https?:\/\//, ''),
|
||||||
|
isRandom = this.isRandomChoice(api.get().header_image);
|
||||||
|
|
||||||
|
// Overridable by an extending class
|
||||||
|
if (!this.type) {
|
||||||
|
this.type = 'uploaded';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overridable by an extending class
|
||||||
|
if (!this.data) {
|
||||||
|
this.data = _wpCustomizeHeader.uploads;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRandom) {
|
||||||
|
// So that when adding data we don't hide regular images
|
||||||
|
current = api.get().header_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.on('control:setImage', this.setImage, this);
|
||||||
|
this.on('control:removeImage', this.removeImage, this);
|
||||||
|
this.on('add', this.maybeAddRandomChoice, this);
|
||||||
|
|
||||||
|
_.each(this.data, function(elt, index) {
|
||||||
|
if (!elt.attachment_id) {
|
||||||
|
elt.defaultName = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.add({
|
||||||
|
header: elt,
|
||||||
|
choice: elt.url.split('/').pop(),
|
||||||
|
hidden: current === elt.url.replace(/^https?:\/\//, '')
|
||||||
|
}, { silent: true });
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (this.size() > 0) {
|
||||||
|
this.addRandomChoice(current);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
maybeAddRandomChoice: function() {
|
||||||
|
if (this.size() === 1) {
|
||||||
|
this.addRandomChoice();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addRandomChoice: function(initialChoice) {
|
||||||
|
var isRandomSameType = RegExp(this.type).test(initialChoice),
|
||||||
|
randomChoice = 'random-' + this.type + '-image';
|
||||||
|
|
||||||
|
this.add({
|
||||||
|
header: {
|
||||||
|
timestamp: 0,
|
||||||
|
random: randomChoice,
|
||||||
|
width: 245,
|
||||||
|
height: 41
|
||||||
|
},
|
||||||
|
choice: randomChoice,
|
||||||
|
random: true,
|
||||||
|
hidden: isRandomSameType
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
isRandomChoice: function(choice) {
|
||||||
|
return (/^random-(uploaded|default)-image$/).test(choice);
|
||||||
|
},
|
||||||
|
|
||||||
|
shouldHideTitle: function() {
|
||||||
|
return _.every(this.pluck('hidden'));
|
||||||
|
},
|
||||||
|
|
||||||
|
setImage: function(model) {
|
||||||
|
this.each(function(m) {
|
||||||
|
m.set('hidden', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (model) {
|
||||||
|
model.set('hidden', true);
|
||||||
|
// Bump images to top except for special "Randomize" images
|
||||||
|
if (!model.get('random')) {
|
||||||
|
model.get('header').timestamp = Date.now();
|
||||||
|
this.sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeImage: function() {
|
||||||
|
this.each(function(m) {
|
||||||
|
m.set('hidden', false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
shown: function() {
|
||||||
|
var filtered = this.where({ hidden: false });
|
||||||
|
return new api.HeaderTool.ChoiceList( filtered );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.DefaultsList
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.customize.HeaderTool.ChoiceList
|
||||||
|
* @augments Backbone.Collection
|
||||||
|
*/
|
||||||
|
api.HeaderTool.DefaultsList = api.HeaderTool.ChoiceList.extend({
|
||||||
|
initialize: function() {
|
||||||
|
this.type = 'default';
|
||||||
|
this.data = _wpCustomizeHeader.defaults;
|
||||||
|
api.HeaderTool.ChoiceList.prototype.initialize.apply(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})( jQuery, window.wp );
|
|
@ -0,0 +1 @@
|
||||||
|
!function(a,b){var c=b.customize;c.HeaderTool={},c.HeaderTool.ImageModel=Backbone.Model.extend({defaults:function(){return{header:{attachment_id:0,url:"",timestamp:Date.now(),thumbnail_url:""},choice:"",hidden:!1,random:!1}},initialize:function(){this.on("hide",this.hide,this)},hide:function(){this.set("choice",""),c("header_image").set("remove-header"),c("header_image_data").set("remove-header")},destroy:function(){var a=this.get("header"),d=c.HeaderTool.currentHeader.get("header").attachment_id;d&&a.attachment_id===d&&c.HeaderTool.currentHeader.trigger("hide"),b.ajax.post("custom-header-remove",{nonce:_wpCustomizeHeader.nonces.remove,wp_customize:"on",theme:c.settings.theme.stylesheet,attachment_id:a.attachment_id}),this.trigger("destroy",this,this.collection)},save:function(){this.get("random")?(c("header_image").set(this.get("header").random),c("header_image_data").set(this.get("header").random)):this.get("header").defaultName?(c("header_image").set(this.get("header").url),c("header_image_data").set(this.get("header").defaultName)):(c("header_image").set(this.get("header").url),c("header_image_data").set(this.get("header"))),c.HeaderTool.combinedList.trigger("control:setImage",this)},importImage:function(){var a=this.get("header");void 0!==a.attachment_id&&b.ajax.post("custom-header-add",{nonce:_wpCustomizeHeader.nonces.add,wp_customize:"on",theme:c.settings.theme.stylesheet,attachment_id:a.attachment_id})},shouldBeCropped:function(){return this.get("themeFlexWidth")===!0&&this.get("themeFlexHeight")===!0?!1:this.get("themeFlexWidth")===!0&&this.get("themeHeight")===this.get("imageHeight")?!1:this.get("themeFlexHeight")===!0&&this.get("themeWidth")===this.get("imageWidth")?!1:this.get("themeWidth")===this.get("imageWidth")&&this.get("themeHeight")===this.get("imageHeight")?!1:!0}}),c.HeaderTool.ChoiceList=Backbone.Collection.extend({model:c.HeaderTool.ImageModel,comparator:function(a){return-a.get("header").timestamp},initialize:function(){var a=c.HeaderTool.currentHeader.get("choice").replace(/^https?:\/\//,""),b=this.isRandomChoice(c.get().header_image);this.type||(this.type="uploaded"),this.data||(this.data=_wpCustomizeHeader.uploads),b&&(a=c.get().header_image),this.on("control:setImage",this.setImage,this),this.on("control:removeImage",this.removeImage,this),this.on("add",this.maybeAddRandomChoice,this),_.each(this.data,function(b,c){b.attachment_id||(b.defaultName=c),this.add({header:b,choice:b.url.split("/").pop(),hidden:a===b.url.replace(/^https?:\/\//,"")},{silent:!0})},this),this.size()>0&&this.addRandomChoice(a)},maybeAddRandomChoice:function(){1===this.size()&&this.addRandomChoice()},addRandomChoice:function(a){var b=RegExp(this.type).test(a),c="random-"+this.type+"-image";this.add({header:{timestamp:0,random:c,width:245,height:41},choice:c,random:!0,hidden:b})},isRandomChoice:function(a){return/^random-(uploaded|default)-image$/.test(a)},shouldHideTitle:function(){return _.every(this.pluck("hidden"))},setImage:function(a){this.each(function(a){a.set("hidden",!1)}),a&&(a.set("hidden",!0),a.get("random")||(a.get("header").timestamp=Date.now(),this.sort()))},removeImage:function(){this.each(function(a){a.set("hidden",!1)})},shown:function(){var a=this.where({hidden:!1});return new c.HeaderTool.ChoiceList(a)}}),c.HeaderTool.DefaultsList=c.HeaderTool.ChoiceList.extend({initialize:function(){this.type="default",this.data=_wpCustomizeHeader.defaults,c.HeaderTool.ChoiceList.prototype.initialize.apply(this)}})}(jQuery,window.wp);
|
|
@ -0,0 +1,232 @@
|
||||||
|
/* globals _wpCustomizeHeader */
|
||||||
|
(function( $, wp, _ ) {
|
||||||
|
|
||||||
|
if ( ! wp || ! wp.customize ) { return; }
|
||||||
|
var api = wp.customize;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.CurrentView
|
||||||
|
*
|
||||||
|
* Displays the currently selected header image, or a placeholder in lack
|
||||||
|
* thereof.
|
||||||
|
*
|
||||||
|
* Instantiate with model wp.customize.HeaderTool.currentHeader.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.Backbone.View
|
||||||
|
*/
|
||||||
|
api.HeaderTool.CurrentView = wp.Backbone.View.extend({
|
||||||
|
template: wp.template('header-current'),
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.listenTo(this.model, 'change', this.render);
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
this.$el.html(this.template(this.model.toJSON()));
|
||||||
|
this.setPlaceholder();
|
||||||
|
this.setButtons();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
getHeight: function() {
|
||||||
|
var image = this.$el.find('img'),
|
||||||
|
saved = this.model.get('savedHeight'),
|
||||||
|
height = image.height() || saved,
|
||||||
|
headerImageData;
|
||||||
|
|
||||||
|
if (image.length) {
|
||||||
|
this.$el.find('.inner').hide();
|
||||||
|
} else {
|
||||||
|
this.$el.find('.inner').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// happens at ready
|
||||||
|
if (!height) {
|
||||||
|
headerImageData = api.get().header_image_data;
|
||||||
|
|
||||||
|
if (headerImageData && headerImageData.width && headerImageData.height) {
|
||||||
|
// hardcoded container width
|
||||||
|
height = 260 / headerImageData.width * headerImageData.height;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// fallback for when no image is set
|
||||||
|
height = 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return height;
|
||||||
|
},
|
||||||
|
|
||||||
|
setPlaceholder: function(_height) {
|
||||||
|
var height = _height || this.getHeight();
|
||||||
|
this.model.set('savedHeight', height);
|
||||||
|
this.$el
|
||||||
|
.add(this.$el.find('.placeholder'))
|
||||||
|
.height(height);
|
||||||
|
},
|
||||||
|
|
||||||
|
setButtons: function() {
|
||||||
|
var elements = $('.actions .remove');
|
||||||
|
if (this.model.get('choice')) {
|
||||||
|
elements.show();
|
||||||
|
} else {
|
||||||
|
elements.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.ChoiceView
|
||||||
|
*
|
||||||
|
* Represents a choosable header image, be it user-uploaded,
|
||||||
|
* theme-suggested or a special Randomize choice.
|
||||||
|
*
|
||||||
|
* Takes a wp.customize.HeaderTool.ImageModel.
|
||||||
|
*
|
||||||
|
* Manually changes model wp.customize.HeaderTool.currentHeader via the
|
||||||
|
* `select` method.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.Backbone.View
|
||||||
|
*/
|
||||||
|
(function () { // closures FTW
|
||||||
|
var lastHeight = 0;
|
||||||
|
api.HeaderTool.ChoiceView = wp.Backbone.View.extend({
|
||||||
|
template: wp.template('header-choice'),
|
||||||
|
|
||||||
|
className: 'header-view',
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'click .choice,.random': 'select',
|
||||||
|
'click .close': 'removeImage'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
var properties = [
|
||||||
|
this.model.get('header').url,
|
||||||
|
this.model.get('choice')
|
||||||
|
];
|
||||||
|
|
||||||
|
this.listenTo(this.model, 'change', this.render);
|
||||||
|
|
||||||
|
if (_.contains(properties, api.get().header_image)) {
|
||||||
|
api.HeaderTool.currentHeader.set(this.extendedModel());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
var model = this.model;
|
||||||
|
|
||||||
|
this.$el.html(this.template(this.extendedModel()));
|
||||||
|
|
||||||
|
if (model.get('random')) {
|
||||||
|
this.setPlaceholder(40);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastHeight = this.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$el.toggleClass('hidden', model.get('hidden'));
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
extendedModel: function() {
|
||||||
|
var c = this.model.get('collection'),
|
||||||
|
t = _wpCustomizeHeader.l10n[c.type] || '';
|
||||||
|
|
||||||
|
return _.extend(this.model.toJSON(), {
|
||||||
|
// -1 to exclude the randomize button
|
||||||
|
nImages: c.size() - 1,
|
||||||
|
type: t
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getHeight: api.HeaderTool.CurrentView.prototype.getHeight,
|
||||||
|
|
||||||
|
setPlaceholder: api.HeaderTool.CurrentView.prototype.setPlaceholder,
|
||||||
|
|
||||||
|
select: function() {
|
||||||
|
this.model.save();
|
||||||
|
api.HeaderTool.currentHeader.set(this.extendedModel());
|
||||||
|
},
|
||||||
|
|
||||||
|
removeImage: function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
this.model.destroy();
|
||||||
|
this.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.ChoiceListView
|
||||||
|
*
|
||||||
|
* A container for ChoiceViews. These choices should be of one same type:
|
||||||
|
* user-uploaded headers or theme-defined ones.
|
||||||
|
*
|
||||||
|
* Takes a wp.customize.HeaderTool.ChoiceList.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.Backbone.View
|
||||||
|
*/
|
||||||
|
api.HeaderTool.ChoiceListView = wp.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:hidden', this.toggleTitle);
|
||||||
|
this.listenTo(this.collection, 'change:hidden', this.setMaxListHeight);
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
this.$el.empty();
|
||||||
|
this.collection.each(this.addOne, this);
|
||||||
|
this.toggleTitle();
|
||||||
|
},
|
||||||
|
|
||||||
|
addOne: function(choice) {
|
||||||
|
var view;
|
||||||
|
choice.set({ collection: this.collection });
|
||||||
|
view = new api.HeaderTool.ChoiceView({ model: choice });
|
||||||
|
this.$el.append(view.render().el);
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleTitle: function() {
|
||||||
|
var title = this.$el.parents().prev('.customize-control-title');
|
||||||
|
if (this.collection.shouldHideTitle()) {
|
||||||
|
title.hide();
|
||||||
|
} else {
|
||||||
|
title.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.customize.HeaderTool.CombinedList
|
||||||
|
*
|
||||||
|
* Aggregates wp.customize.HeaderTool.ChoiceList collections (or any
|
||||||
|
* Backbone object, really) and acts as a bus to feed them events.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.Backbone.View
|
||||||
|
*/
|
||||||
|
api.HeaderTool.CombinedList = wp.Backbone.View.extend({
|
||||||
|
initialize: function(collections) {
|
||||||
|
this.collections = collections;
|
||||||
|
this.on('all', this.propagate, this);
|
||||||
|
},
|
||||||
|
propagate: function(event, arg) {
|
||||||
|
_.each(this.collections, function(collection) {
|
||||||
|
collection.trigger(event, arg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})( jQuery, window.wp, _ );
|
|
@ -0,0 +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=this.$el.find("img"),c=this.model.get("savedHeight"),e=b.height()||c;return b.length?this.$el.find(".inner").hide():this.$el.find(".inner").show(),e||(a=d.get().header_image_data,e=a&&a.width&&a.height?260/a.width*a.height:40),e},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(".actions .remove");this.model.get("choice")?b.show():b.hide()}}),function(){var a=0;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",this.render),c.contains(a,d.get().header_image)&&d.HeaderTool.currentHeader.set(this.extendedModel())},render:function(){var b=this.model;return this.$el.html(this.template(this.extendedModel())),b.get("random")?this.setPlaceholder(40):a=this.getHeight(),this.$el.toggleClass("hidden",b.get("hidden")),this},extendedModel:function(){var a=this.model.get("collection"),b=_wpCustomizeHeader.l10n[a.type]||"";return c.extend(this.model.toJSON(),{nImages:a.size()-1,type:b})},getHeight:d.HeaderTool.CurrentView.prototype.getHeight,setPlaceholder:d.HeaderTool.CurrentView.prototype.setPlaceholder,select:function(){this.model.save(),d.HeaderTool.currentHeader.set(this.extendedModel())},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:hidden",this.toggleTitle),this.listenTo(this.collection,"change:hidden",this.setMaxListHeight),this.render()},render:function(){this.$el.empty(),this.collection.each(this.addOne,this),this.toggleTitle()},addOne:function(a){var b;a.set({collection:this.collection}),b=new d.HeaderTool.ChoiceView({model:a}),this.$el.append(b.render().el)},toggleTitle:function(){var a=this.$el.parents().prev(".customize-control-title");this.collection.shouldHideTitle()?a.hide():a.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,_);
|
|
@ -1316,6 +1316,109 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.media.controller.Cropper
|
||||||
|
*
|
||||||
|
* Allows for a cropping step.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.media.controller.State
|
||||||
|
* @augments Backbone.Model
|
||||||
|
*/
|
||||||
|
media.controller.Cropper = media.controller.State.extend({
|
||||||
|
defaults: {
|
||||||
|
id: 'cropper',
|
||||||
|
title: l10n.cropImage,
|
||||||
|
toolbar: 'crop',
|
||||||
|
content: 'crop',
|
||||||
|
router: false,
|
||||||
|
canSkipCrop: false
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function() {
|
||||||
|
this.frame.on( 'content:create:crop', this.createCropContent, this );
|
||||||
|
this.frame.on( 'close', this.removeCropper, this );
|
||||||
|
this.set('selection', new Backbone.Collection(this.frame._selection.single));
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivate: function() {
|
||||||
|
this.frame.toolbar.mode('browse');
|
||||||
|
},
|
||||||
|
|
||||||
|
createCropContent: function() {
|
||||||
|
this.cropperView = new wp.media.view.Cropper({controller: this,
|
||||||
|
attachment: this.get('selection').first() });
|
||||||
|
this.cropperView.on('image-loaded', this.createCropToolbar, this);
|
||||||
|
this.frame.content.set(this.cropperView);
|
||||||
|
|
||||||
|
},
|
||||||
|
removeCropper: function() {
|
||||||
|
this.imgSelect.cancelSelection();
|
||||||
|
this.imgSelect.setOptions({remove: true});
|
||||||
|
this.imgSelect.update();
|
||||||
|
this.cropperView.remove();
|
||||||
|
},
|
||||||
|
createCropToolbar: function() {
|
||||||
|
var canSkipCrop, toolbarOptions;
|
||||||
|
|
||||||
|
canSkipCrop = this.get('canSkipCrop') || false;
|
||||||
|
|
||||||
|
toolbarOptions = {
|
||||||
|
controller: this.frame,
|
||||||
|
items: {
|
||||||
|
insert: {
|
||||||
|
style: 'primary',
|
||||||
|
text: l10n.cropImage,
|
||||||
|
priority: 80,
|
||||||
|
requires: { library: false, selection: false },
|
||||||
|
|
||||||
|
click: function() {
|
||||||
|
var self = this,
|
||||||
|
selection = this.controller.state().get('selection').first();
|
||||||
|
|
||||||
|
selection.set({cropDetails: this.controller.state().imgSelect.getSelection()});
|
||||||
|
|
||||||
|
this.$el.text(l10n.cropping);
|
||||||
|
this.$el.attr('disabled', true);
|
||||||
|
this.controller.state().doCrop( selection ).done( function( croppedImage ) {
|
||||||
|
console.log( croppedImage );
|
||||||
|
self.controller.trigger('cropped', croppedImage );
|
||||||
|
self.controller.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( canSkipCrop ) {
|
||||||
|
_.extend( toolbarOptions.items, {
|
||||||
|
skip: {
|
||||||
|
style: 'secondary',
|
||||||
|
text: l10n.skipCropping,
|
||||||
|
priority: 70,
|
||||||
|
requires: { library: false, selection: false },
|
||||||
|
click: function() {
|
||||||
|
var selection = this.controller.state().get('selection').first();
|
||||||
|
this.controller.state().cropperView.remove();
|
||||||
|
this.controller.trigger('skippedcrop', selection);
|
||||||
|
this.controller.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frame.toolbar.set( new wp.media.view.Toolbar(toolbarOptions) );
|
||||||
|
},
|
||||||
|
|
||||||
|
doCrop: function( attachment ) {
|
||||||
|
return wp.ajax.post( 'custom-header-crop', {
|
||||||
|
nonce: attachment.get('nonces').edit,
|
||||||
|
id: attachment.get('id'),
|
||||||
|
cropDetails: attachment.get('cropDetails')
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* VIEWS
|
* VIEWS
|
||||||
|
@ -6323,6 +6426,53 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wp.media.view.Cropper
|
||||||
|
*
|
||||||
|
* Uses the imgAreaSelect plugin to allow a user to crop an image.
|
||||||
|
*
|
||||||
|
* Takes imgAreaSelect options from
|
||||||
|
* wp.customize.HeaderControl.calculateImageSelectOptions via
|
||||||
|
* wp.customize.HeaderControl.openMM.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @augments wp.media.View
|
||||||
|
* @augments wp.Backbone.View
|
||||||
|
* @augments Backbone.View
|
||||||
|
*/
|
||||||
|
media.view.Cropper = media.View.extend({
|
||||||
|
tagName: 'img',
|
||||||
|
className: 'crop-content',
|
||||||
|
initialize: function() {
|
||||||
|
_.bindAll(this, 'onImageLoad');
|
||||||
|
this.$el.attr('src', this.options.attachment.get('url'));
|
||||||
|
},
|
||||||
|
ready: function() {
|
||||||
|
this.$el.on('load', this.onImageLoad);
|
||||||
|
$(window).on('resize.cropper', _.debounce(this.onImageLoad, 250));
|
||||||
|
},
|
||||||
|
remove: function() {
|
||||||
|
$(window).off('resize.cropper');
|
||||||
|
this.$el.remove();
|
||||||
|
this.$el.off();
|
||||||
|
wp.media.View.prototype.remove.apply(this, arguments);
|
||||||
|
},
|
||||||
|
prepare: function() {
|
||||||
|
return {
|
||||||
|
title: l10n.cropYourImage,
|
||||||
|
url: this.options.attachment.get('url')
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onImageLoad: function() {
|
||||||
|
var imgOptions = this.controller.frame.options.imgSelectOptions;
|
||||||
|
if (typeof imgOptions === 'function') {
|
||||||
|
imgOptions = imgOptions(this.options.attachment, this.controller);
|
||||||
|
}
|
||||||
|
this.trigger('image-loaded');
|
||||||
|
this.controller.imgSelect = this.$el.imgAreaSelect(imgOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
media.view.EditImage = media.View.extend({
|
media.view.EditImage = media.View.extend({
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2476,6 +2476,23 @@ function wp_enqueue_media( $args = array() ) {
|
||||||
'imageDetailsCancel' => __( 'Cancel Edit' ),
|
'imageDetailsCancel' => __( 'Cancel Edit' ),
|
||||||
'editImage' => __( 'Edit Image' ),
|
'editImage' => __( 'Edit Image' ),
|
||||||
|
|
||||||
|
// Crop Image
|
||||||
|
/* translators: title for Media Manager library view */
|
||||||
|
'chooseImage' => __( 'Choose Image' ),
|
||||||
|
/* translators: button to select an image from the MM library to crop */
|
||||||
|
'selectAndCrop' => __( 'Select and Crop' ),
|
||||||
|
/* translators: button to choose not to crop the selected image */
|
||||||
|
'skipCropping' => __( 'Skip Cropping' ),
|
||||||
|
/* translators: button to choose to crop the selected image */
|
||||||
|
'cropImage' => __( 'Crop Image' ),
|
||||||
|
'cropYourImage' => __( 'Crop your image' ),
|
||||||
|
/* translators: button label changes to this while the image is being cropped server-side */
|
||||||
|
'cropping' => __( 'Cropping...' ),
|
||||||
|
/* translators: suggested width of header image in pixels */
|
||||||
|
'suggestedWidth' => __( 'Suggested width is %d pixels.' ),
|
||||||
|
/* translators: suggested height of header image in pixels */
|
||||||
|
'suggestedHeight' => __( 'Suggested height is %d pixels.' ),
|
||||||
|
|
||||||
// Edit Audio
|
// Edit Audio
|
||||||
'audioDetailsTitle' => __( 'Audio Details' ),
|
'audioDetailsTitle' => __( 'Audio Details' ),
|
||||||
'audioReplaceTitle' => __( 'Replace Audio' ),
|
'audioReplaceTitle' => __( 'Replace Audio' ),
|
||||||
|
|
|
@ -363,6 +363,8 @@ function wp_default_scripts( &$scripts ) {
|
||||||
$scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2' ), false, 1 );
|
$scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2' ), false, 1 );
|
||||||
$scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 );
|
$scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 );
|
||||||
$scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'customize-base' ), false, 1 );
|
$scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'customize-base' ), false, 1 );
|
||||||
|
$scripts->add( 'customize-models', "/wp-includes/js/customize-models.js", array( 'underscore', 'backbone' ), false, 1 );
|
||||||
|
$scripts->add( 'customize-views', "/wp-includes/js/customize-views.js", array( 'jquery', 'underscore', 'imgareaselect', 'customize-models' ), false, 1 );
|
||||||
$scripts->add( 'customize-controls', "/wp-admin/js/customize-controls$suffix.js", array( 'customize-base' ), false, 1 );
|
$scripts->add( 'customize-controls', "/wp-admin/js/customize-controls$suffix.js", array( 'customize-base' ), false, 1 );
|
||||||
did_action( 'init' ) && $scripts->localize( 'customize-controls', '_wpCustomizeControlsL10n', array(
|
did_action( 'init' ) && $scripts->localize( 'customize-controls', '_wpCustomizeControlsL10n', array(
|
||||||
'activate' => __( 'Save & Activate' ),
|
'activate' => __( 'Save & Activate' ),
|
||||||
|
@ -600,7 +602,7 @@ function wp_default_styles( &$styles ) {
|
||||||
$styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'buttons', 'open-sans', 'dashicons' ) );
|
$styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'buttons', 'open-sans', 'dashicons' ) );
|
||||||
$styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'buttons', 'open-sans' ) );
|
$styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'buttons', 'open-sans' ) );
|
||||||
$styles->add( 'wp-color-picker', "/wp-admin/css/color-picker$suffix.css" );
|
$styles->add( 'wp-color-picker', "/wp-admin/css/color-picker$suffix.css" );
|
||||||
$styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'ie' ) );
|
$styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'ie', 'imgareaselect' ) );
|
||||||
$styles->add( 'ie', "/wp-admin/css/ie$suffix.css" );
|
$styles->add( 'ie', "/wp-admin/css/ie$suffix.css" );
|
||||||
|
|
||||||
$styles->add_data( 'ie', 'conditional', 'lte IE 7' );
|
$styles->add_data( 'ie', 'conditional', 'lte IE 7' );
|
||||||
|
|
Loading…
Reference in New Issue