Ticket #21483: 21483.wip.2.diff
File 21483.wip.2.diff, 16.7 KB (added by , 10 years ago) |
---|
-
src/wp-admin/css/customize-controls.css
10 10 font-size: 14px; 11 11 } 12 12 13 #customize-controls img { 14 max-width: 100%; 15 } 16 13 17 #customize-controls .submit { 14 18 text-align: center; 15 19 } … … 414 418 margin-right: 5px; 415 419 } 416 420 421 .customize-control .attachment-thumb.type-icon { 422 float: left; 423 margin-right: 12px; 424 } 425 426 .customize-control .attachment-title { 427 font-weight: bold; 428 margin: 0 0 12px 0; 429 } 430 431 .customize-control .remove-button { 432 margin-left: 8px; 433 vertical-align: middle; 434 } 435 417 436 #customize-preview iframe { 418 437 width: 100%; 419 438 height: 100%; -
src/wp-admin/js/customize-controls.js
200 200 * @augments wp.customize.Class 201 201 */ 202 202 api.UploadControl = api.Control.extend({ 203 204 /** 205 * Setup control and do event bindings. 206 */ 203 207 ready: function() { 204 var control = this; 208 209 // Cache buttons for re-use. 210 this.$button = this.container.find( '.upload-button' ); 211 this.$img = this.container.find( '.thumbnail-image img' ); 212 this.$removeButton = this.container.find( '.remove-button' ); 205 213 206 this.params.removed = this.params.removed || ''; 214 // Shortcut so that we don't have to use _.bind every time we add a callback. 215 _.bindAll( this, 'removeFile', 'reRender', 'upload', 'select' ); 207 216 208 this.success = $.proxy( this.success, this ); 217 // Ensure clicking "remove" removes the file. 218 this.$removeButton.on( 'click', this.removeFile ); 209 219 210 this.uploader = $.extend({ 211 container: this.container, 212 browser: this.container.find('.upload'), 213 dropzone: this.container.find('.upload-dropzone'), 214 success: this.success, 215 plupload: {}, 216 params: {} 217 }, this.uploader || {} ); 220 // Bind upload button, and image (if it exists). 221 this.$button.on( 'click keydown', this.upload ); 222 this.$img.on( 'click keydown', this.upload ); 223 }, 218 224 219 if ( control.params.extensions ) { 220 control.uploader.plupload.filters = [{ 221 title: api.l10n.allowedFiles, 222 extensions: control.params.extensions 223 }]; 225 /** 226 * Remember that _.bind was used to maintain `this` as the control 227 * object rather than the usual jQuery way of binding to the DOM element. 228 */ 229 upload: function( event ) { 230 event.preventDefault(); 231 232 if ( ! this.frame ) { 233 this.initFrame(); 224 234 } 225 235 226 if ( control.params.context )227 control.uploader.params['post_data[context]'] = this.params.context;236 this.frame.open(); 237 }, 228 238 229 if ( api.settings.theme.stylesheet ) 230 control.uploader.params['post_data[theme]'] = api.settings.theme.stylesheet; 239 /** 240 * Set the media frame so that it can be reused and accessed when needed. 241 */ 242 initFrame: function() { 243 this.frame = wp.media({ 244 // The title of the media modal 245 title: this.params.button_labels.frame_title, 231 246 232 this.uploader = new wp.Uploader( this.uploader ); 247 // Restrict to specified mime type. 248 // @todo try to map $extensions to this in PHP. 249 library: { 250 type: this.params.mime_type 251 }, 252 button: { 253 // Change the submit button label. 254 text: this.params.button_labels.frame_button 255 }, 256 multiple: false 257 }); 233 258 234 this.remover = this.container.find('.remove'); 235 this.remover.on( 'click keydown', function( event ) { 236 if ( event.type === 'keydown' && 13 !== event.which ) // enter 237 return; 259 // When a file is selected, run a callback. 260 this.frame.on( 'select', this.select ); 261 }, 238 262 239 control.setting.set( control.params.removed ); 240 event.preventDefault(); 241 }); 263 /** 264 * Fired when an image is selected in the media modal. Gets the selected 265 * image information, and sets it within the control. 266 */ 267 select: function() { 268 // Get the attachment from the modal frame. 269 var attachment = this.frame.state().get( 'selection' ).first().toJSON(); 242 270 243 this.removerVisibility = $.proxy( this.removerVisibility, this ); 244 this.setting.bind( this.removerVisibility ); 245 this.removerVisibility( this.setting.get() ); 271 this.params.attachment = attachment; 272 273 // Set the Customizer setting; the callback takes care of rendering. 274 this.setting( attachment.url ); 275 this.reRender(); 246 276 }, 247 success: function( attachment ) { 248 this.setting.set( attachment.get('url') ); 277 278 /** 279 * Called on whenever a setting is changed. 280 * 281 */ 282 reRender: function() { 283 // @todo: something else is needed to preview audio/video files 284 var self = this; 285 self.container.html(''); 286 self.renderContent( function() { 287 // Don't call ready() until the content has rendered. 288 self.ready(); 289 } ); 249 290 }, 250 removerVisibility: function( to ) { 251 this.remover.toggle( to != this.params.removed ); 252 } 291 292 293 /** 294 * Called when the "Remove" link is clicked. Empties the setting. 295 * @param {object} event jQuery Event object from click event 296 */ 297 removeFile: function( event ) { 298 event.preventDefault(); 299 this.setting( '' ); // @todo maybe set to default instead 300 this.params.attachment = {}; 301 this.reRender(); 302 } 253 303 }); 254 304 255 305 /** -
src/wp-includes/class-wp-customize-control.php
580 580 * @since 3.4.0 581 581 */ 582 582 class WP_Customize_Upload_Control extends WP_Customize_Control { 583 public $type = 'upload'; 584 public $removed = ''; 585 public $context; 586 public $extensions = array(); 583 public $type = 'upload'; 584 public $mime_type = ''; 585 public $button_labels = array( 586 'select' => 'Select File', // @todo PHP doesn't like letting us translate these 587 'change' => 'Change File', 588 'remove' => 'Remove', 589 'frame_title' => 'Select File', 590 'frame_button' => 'Choose File', 591 ); 592 public $removed = ''; // unused 593 public $context; // unused 594 public $extensions = array(); // unused 587 595 588 596 /** 589 597 * Enqueue control related scripts/styles. … … 591 599 * @since 3.4.0 592 600 */ 593 601 public function enqueue() { 594 wp_enqueue_ script( 'wp-plupload');602 wp_enqueue_media(); 595 603 } 596 604 597 605 /** … … 602 610 */ 603 611 public function to_json() { 604 612 parent::to_json(); 613 $this->json['mime_type'] = $this->mime_type; 614 $this->json['button_labels'] = $this->button_labels; 605 615 606 $this->json['removed'] = $this->removed; 616 if ( $this->setting ) { 617 // if ( $this->setting->default ) { 618 // $this->json['default_url'] = $this->setting->default; @todo 619 // } 607 620 608 if ( $this->context ) 609 $this->json['context'] = $this->context; 610 611 if ( $this->extensions ) 612 $this->json['extensions'] = implode( ',', $this->extensions ); 621 // Get the attachment model for the existing file, or make one. 622 if ( $this->value() ) { 623 $attachment_id = attachment_url_to_postid( $this->value() ); 624 if ( $attachment_id ) { 625 $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id); 626 } 627 } 628 } 613 629 } 614 630 615 631 /** 616 * Render the control's content.632 * Don't render any content for this control from PHP. 617 633 * 634 * @see WP_Customize_Upload_Control::content_template() 618 635 * @since 3.4.0 619 636 */ 620 public function render_content() { 637 public function render_content() {} 638 639 /** 640 * Render a JS template for the content of the upload control. 641 * 642 * @since 4.1.0 643 */ 644 public function content_template() { 621 645 ?> 622 646 <label> 623 <?php if ( ! empty( $this->label ) ) : ?> 624 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span> 625 <?php endif; 626 if ( ! empty( $this->description ) ) : ?> 627 <span class="description customize-control-description"><?php echo $this->description; ?></span> 628 <?php endif; ?> 629 <div> 630 <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a> 631 <a href="#" class="remove"><?php _e( 'Remove' ); ?></a> 632 </div> 647 <# if ( data.label ) { #> 648 <span class="customize-control-title">{{ data.label }}</span> 649 <# } #> 650 <# if ( data.description ) { #> 651 <span class="description customize-control-description">{{ data.description }}</span> 652 <# } #> 653 654 <# if ( data.attachment && data.attachment.id ) { #> 655 <div class="attachment-media-view {{ data.attachment.orientation }}"> 656 <div class="thumbnail thumbnail-{{ data.attachment.type }}"> 657 <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #> 658 <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" /> 659 <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #> 660 <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" /> 661 <# } else if ( -1 === jQuery.inArray( data.attachment.type, [ 'audio', 'video' ] ) ) { #> 662 <img class="attachment-thumb type-icon" src="{{ data.attachment.icon }}" class="icon" draggable="false" /> 663 <p class="attachment-title">{{ data.attachment.title }}</p> 664 <# } #> 665 666 <# if ( 'audio' === data.attachment.type ) { #> 667 <div class="wp-media-wrapper"> 668 <p class="attachment-title">{{ data.attachment.title }}</p> 669 <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none"> 670 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/> 671 </audio> 672 </div> 673 <# } else if ( 'video' === data.attachment.type ) { 674 var w_rule = h_rule = ''; 675 if ( data.attachment.width ) { 676 w_rule = 'width: ' + data.attachment.width + 'px;'; 677 } else if ( wp.media.view.settings.contentWidth ) { 678 w_rule = 'width: ' + wp.media.view.settings.contentWidth + 'px;'; 679 } 680 if ( data.attachment.height ) { 681 h_rule = 'height: ' + data.attachment.height + 'px;'; 682 } 683 #> 684 <div style="{{ w_rule }}{{ h_rule }}" class="wp-media-wrapper wp-video"> 685 <video controls="controls" class="wp-video-shortcode" preload="metadata" 686 <# if ( data.attachment.width ) { #>width="{{ data.attachment.width }}"<# } #> 687 <# if ( data.attachment.height ) { #>height="{{ data.attachment.height }}"<# } #> 688 <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>> 689 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/> 690 </video> 691 </div> 692 <# } #> 693 </div> 694 </div> 695 <a class="button upload-button" href="#"><?php echo $this->button_labels['change']; ?></a> 696 <a class="remove-button" href="#"><?php echo $this->button_labels['remove']; ?></a> 697 <# } else { #> 698 <a class="button upload-button" href="#"><?php echo $this->button_labels['select']; ?></a> 699 <# } #> 633 700 </label> 634 701 <?php 635 702 } … … 644 711 */ 645 712 class WP_Customize_Image_Control extends WP_Customize_Upload_Control { 646 713 public $type = 'image'; 647 public $get_url; 648 public $statuses; 649 public $extensions = array( 'jpg', 'jpeg', 'gif', 'png' ); 714 public $mime_type = 'image'; 715 public $button_labels = array( 716 'select' => 'Select Image', // @todo PHP doesn't like letting us translate these 717 'change' => 'Change Image', 718 'remove' => 'Remove', 719 'frame_title' => 'Select Image', 720 'frame_button' => 'Choose Image', 721 ); 650 722 651 protected $tabs = array();652 653 723 /** 654 * Constructor.655 *656 * @since 3.4.0657 * @uses WP_Customize_Upload_Control::__construct()658 *659 * @param WP_Customize_Manager $manager660 * @param string $id661 * @param array $args662 */663 public function __construct( $manager, $id, $args ) {664 $this->statuses = array( '' => __('No Image') );665 666 parent::__construct( $manager, $id, $args );667 668 $this->add_tab( 'upload-new', __('Upload New'), array( $this, 'tab_upload_new' ) );669 $this->add_tab( 'uploaded', __('Uploaded'), array( $this, 'tab_uploaded' ) );670 671 // Early priority to occur before $this->manager->prepare_controls();672 add_action( 'customize_controls_init', array( $this, 'prepare_control' ), 5 );673 }674 675 /**676 * Prepares the control.677 *678 * If no tabs exist, removes the control from the manager.679 *680 * @since 3.4.2681 */682 public function prepare_control() {683 if ( ! $this->tabs )684 $this->manager->remove_control( $this->id );685 }686 687 /**688 * Refresh the parameters passed to the JavaScript via JSON.689 *690 * @since 3.4.0691 * @uses WP_Customize_Upload_Control::to_json()692 */693 public function to_json() {694 parent::to_json();695 $this->json['statuses'] = $this->statuses;696 }697 698 /**699 * Render the control's content.700 *701 * @since 3.4.0702 */703 public function render_content() {704 $src = $this->value();705 if ( isset( $this->get_url ) )706 $src = call_user_func( $this->get_url, $src );707 708 ?>709 <div class="customize-image-picker">710 <?php if ( ! empty( $this->label ) ) : ?>711 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>712 <?php endif;713 if ( ! empty( $this->description ) ) : ?>714 <span class="description customize-control-description"><?php echo $this->description; ?></span>715 <?php endif; ?>716 717 <div class="customize-control-content">718 <div class="dropdown preview-thumbnail" tabindex="0">719 <div class="dropdown-content">720 <?php if ( empty( $src ) ): ?>721 <img style="display:none;" />722 <?php else: ?>723 <img src="<?php echo esc_url( set_url_scheme( $src ) ); ?>" />724 <?php endif; ?>725 <div class="dropdown-status"></div>726 </div>727 <div class="dropdown-arrow"></div>728 </div>729 </div>730 731 <div class="library">732 <ul>733 <?php foreach ( $this->tabs as $id => $tab ): ?>734 <li data-customize-tab='<?php echo esc_attr( $id ); ?>' tabindex='0'>735 <?php echo esc_html( $tab['label'] ); ?>736 </li>737 <?php endforeach; ?>738 </ul>739 <?php foreach ( $this->tabs as $id => $tab ): ?>740 <div class="library-content" data-customize-tab='<?php echo esc_attr( $id ); ?>'>741 <?php call_user_func( $tab['callback'] ); ?>742 </div>743 <?php endforeach; ?>744 </div>745 746 <div class="actions">747 <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>748 </div>749 </div>750 <?php751 }752 753 /**754 724 * Add a tab to the control. 755 725 * 756 726 * @since 3.4.0 727 * @deprecated 4.1.0 757 728 * 758 729 * @param string $id 759 730 * @param string $label 760 731 * @param mixed $callback 761 732 */ 762 public function add_tab( $id, $label, $callback ) { 763 $this->tabs[ $id ] = array( 764 'label' => $label, 765 'callback' => $callback, 766 ); 767 } 733 public function add_tab( $id, $label, $callback ) {} 768 734 769 735 /** 770 736 * Remove a tab from the control. 771 737 * 772 738 * @since 3.4.0 739 * @deprecated 4.1.0 773 740 * 774 741 * @param string $id 775 742 */ 776 public function remove_tab( $id ) { 777 unset( $this->tabs[ $id ] ); 778 } 779 780 /** 781 * @since 3.4.0 782 */ 783 public function tab_upload_new() { 784 if ( ! _device_can_upload() ) { 785 echo '<p>' . sprintf( __('The web browser on your device cannot be used to upload files. You may be able to use the <a href="%s">native app for your device</a> instead.'), 'https://apps.wordpress.org/' ) . '</p>'; 786 } else { 787 ?> 788 <div class="upload-dropzone"> 789 <?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?> 790 </div> 791 <div class="upload-fallback"> 792 <span class="button-secondary"><?php _e('Select File'); ?></span> 793 </div> 794 <?php 795 } 796 } 797 798 /** 799 * @since 3.4.0 800 */ 801 public function tab_uploaded() { 802 ?> 803 <div class="uploaded-target"></div> 804 <?php 805 } 806 807 /** 808 * @since 3.4.0 809 * 810 * @param string $url 811 * @param string $thumbnail_url 812 */ 813 public function print_tab_image( $url, $thumbnail_url = null ) { 814 $url = set_url_scheme( $url ); 815 $thumbnail_url = ( $thumbnail_url ) ? set_url_scheme( $thumbnail_url ) : $url; 816 ?> 817 <a href="#" class="thumbnail" data-customize-image-value="<?php echo esc_url( $url ); ?>"> 818 <img src="<?php echo esc_url( $thumbnail_url ); ?>" /> 819 </a> 820 <?php 821 } 743 public function remove_tab( $id ) {} 822 744 } 823 745 824 746 /** -
src/wp-includes/class-wp-customize-manager.php
962 962 963 963 /* Control Types (custom control classes) */ 964 964 $this->register_control_type( 'WP_Customize_Color_Control' ); 965 $this->register_control_type( 'WP_Customize_Upload_Control' ); 966 $this->register_control_type( 'WP_Customize_Image_Control' ); 965 967 966 968 /* Site Title & Tagline */ 967 969