Ticket #21483: 21483.4.diff
File 21483.4.diff, 22.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 436 .customize-control .thumbnail-audio .attachment-title, 437 .customize-control .thumbnail.thumbnail-audio, 438 .customize-control .thumbnail.thumbnail-video, 439 .customize-control .thumbnail.thumbnail-image { 440 margin-bottom: 8px; 441 } 442 443 .customize-control .placeholder-text { 444 font-size: 18px; 445 font-weight: 300; 446 text-align: center; 447 color: #aaa; 448 cursor: default; 449 } 450 451 .customize-control .thumbnail-image img { 452 cursor: pointer; 453 } 454 417 455 #customize-preview iframe { 418 456 width: 100%; 419 457 height: 100%; -
src/wp-admin/js/customize-controls.js
898 898 * @augments wp.customize.Class 899 899 */ 900 900 api.UploadControl = api.Control.extend({ 901 ready: function() { 901 902 /** 903 * Set up control and do event bindings. 904 */ 905 ready: function() { 902 906 var control = this; 903 907 904 this.params.removed = this.params.removed || ''; 908 control.setupEvents(); 909 control.setting.bind( function () { control.reRender(); } ); 910 }, 905 911 906 this.success = $.proxy( this.success, this ); 912 setupEvents: function() { 913 // Cache buttons for re-use. 914 this.$button = this.container.find( '.upload-button' ); 915 this.$img = this.container.find( '.thumbnail-image img' ); 916 this.$defaultButton = this.container.find( '.default-button' ); 917 this.$removeButton = this.container.find( '.remove-button' ); 907 918 908 this.uploader = $.extend({ 909 container: this.container, 910 browser: this.container.find('.upload'), 911 dropzone: this.container.find('.upload-dropzone'), 912 success: this.success, 913 plupload: {}, 914 params: {} 915 }, this.uploader || {} ); 919 // Shortcut so that we don't have to use _.bind every time we add a callback. 920 _.bindAll( this, 'removeFile', 'reRender', 'openFrame', 'select' ); 916 921 917 if ( control.params.extensions ) { 918 control.uploader.plupload.filters = [{ 919 title: api.l10n.allowedFiles, 920 extensions: control.params.extensions 921 }]; 922 } 922 this.$defaultButton.on( 'click keydown', this.restoreDefault ); 923 this.$removeButton.on( 'click keydown', this.removeFile ); 924 this.$button.on( 'click keydown', this.openFrame ); 925 this.$img.on( 'click keydown', this.openFrame ); 926 }, 923 927 924 if ( control.params.context ) 925 control.uploader.params['post_data[context]'] = this.params.context; 928 /** 929 * Open the media modal. 930 */ 931 openFrame: function( event ) { 932 if ( event.type === 'keydown' && 13 !== event.which ) { // enter 933 return; 934 } 926 935 927 if ( api.settings.theme.stylesheet ) 928 control.uploader.params['post_data[theme]'] = api.settings.theme.stylesheet; 936 event.preventDefault(); 929 937 930 this.uploader = new wp.Uploader( this.uploader ); 938 if ( ! this.frame ) { 939 this.initFrame(); 940 } 931 941 932 this.remover = this.container.find('.remove'); 933 this.remover.on( 'click keydown', function( event ) { 934 if ( isKeydownButNotEnterEvent( event ) ) { 935 return; 936 } 937 938 control.setting.set( control.params.removed ); 939 event.preventDefault(); 940 }); 941 942 this.removerVisibility = $.proxy( this.removerVisibility, this ); 943 this.setting.bind( this.removerVisibility ); 944 this.removerVisibility( this.setting.get() ); 942 this.frame.open(); 945 943 }, 946 success: function( attachment ) {947 this.setting.set( attachment.get('url') );948 },949 removerVisibility: function( to ) {950 this.remover.toggle( to != this.params.removed );951 }952 });953 944 954 /** 955 * @constructor 956 * @augments wp.customize.UploadControl 957 * @augments wp.customize.Control 958 * @augments wp.customize.Class 959 */ 960 api.ImageControl = api.UploadControl.extend({ 961 ready: function() { 962 var control = this, 963 panels; 945 /** 946 * Set up the media modal so that it can be reused and accessed when needed. 947 */ 948 initFrame: function() { 949 this.frame = wp.media({ 950 // The title of the media modal. 951 title: this.params.button_labels.frame_title, 964 952 965 this.uploader = { 966 init: function() { 967 var fallback, button; 953 // Restrict to specified mime type. 954 // @todo try to map $extensions to this in PHP? 955 library: { 956 type: this.params.mime_type 957 }, 958 button: { 959 // Change the submit button label. 960 text: this.params.button_labels.frame_button 961 }, 962 multiple: false 963 }); 968 964 969 if ( this.supports.dragdrop ) 970 return; 965 // When a file is selected, run a callback. 966 this.frame.on( 'select', this.select ); 967 }, 971 968 972 // Maintain references while wrapping the fallback button. 973 fallback = control.container.find( '.upload-fallback' ); 974 button = fallback.children().detach(); 969 /** 970 * Fired when an attachment is selected in the media modal. Gets the selected 971 * image information, and sets it within the control. 972 */ 973 select: function() { 974 // Get the attachment from the modal frame. 975 var attachment = this.frame.state().get( 'selection' ).first().toJSON(); 975 976 976 this.browser.detach().empty().append( button ); 977 fallback.append( this.browser ).show(); 978 } 979 }; 977 this.params.attachment = attachment; 980 978 981 api.UploadControl.prototype.ready.call( this ); 979 // Set the Customizer setting; the callback takes care of rendering. 980 this.setting( attachment.url ); 981 }, 982 982 983 this.thumbnail = this.container.find('.preview-thumbnail img'); 984 this.thumbnailSrc = $.proxy( this.thumbnailSrc, this ); 985 this.setting.bind( this.thumbnailSrc ); 983 /** 984 * Called on whenever a setting is changed. 985 */ 986 reRender: function() { 987 this.container.html(''); 988 this.renderContent(); 989 this.setupEvents(); 990 // @todo: something else is needed to preview audio/video files 991 }, 986 992 987 this.library = this.container.find('.library'); 988 989 // Generate tab objects 990 this.tabs = {}; 991 panels = this.library.find('.library-content'); 992 993 this.library.children('ul').children('li').each( function() { 994 var link = $(this), 995 id = link.data('customizeTab'), 996 panel = panels.filter('[data-customize-tab="' + id + '"]'); 997 998 control.tabs[ id ] = { 999 both: link.add( panel ), 1000 link: link, 1001 panel: panel 1002 }; 1003 }); 1004 1005 // Bind tab switch events 1006 this.library.children('ul').on( 'click keydown', 'li', function( event ) { 1007 if ( isKeydownButNotEnterEvent( event ) ) { 1008 return; 1009 } 1010 1011 var id = $(this).data('customizeTab'), 1012 tab = control.tabs[ id ]; 1013 1014 event.preventDefault(); 1015 1016 if ( tab.link.hasClass('library-selected') ) 1017 return; 1018 1019 control.selected.both.removeClass('library-selected'); 1020 control.selected = tab; 1021 control.selected.both.addClass('library-selected'); 1022 }); 1023 1024 // Bind events to switch image urls. 1025 this.library.on( 'click keydown', 'a', function( event ) { 1026 if ( isKeydownButNotEnterEvent( event ) ) { 1027 return; 1028 } 1029 1030 var value = $(this).data('customizeImageValue'); 1031 1032 if ( value ) { 1033 control.setting.set( value ); 1034 event.preventDefault(); 1035 } 1036 }); 1037 1038 if ( this.tabs.uploaded ) { 1039 this.tabs.uploaded.target = this.library.find('.uploaded-target'); 1040 if ( ! this.tabs.uploaded.panel.find('.thumbnail').length ) 1041 this.tabs.uploaded.both.addClass('hidden'); 993 /** 994 * Reset the setting to the default value. @todo default button instead of remove that calls this. 995 */ 996 restoreDefault: function( event ) { 997 if ( event.type === 'keydown' && 13 !== event.which ) { // enter 998 return; 1042 999 } 1043 1000 1044 // Select a tab 1045 panels.each( function() { 1046 var tab = control.tabs[ $(this).data('customizeTab') ]; 1001 event.preventDefault(); 1002 this.setting( this.params.defaultAttachment.url ); 1003 this.params.attachment = this.params.defaultAttachment; 1004 }, 1047 1005 1048 // Select the first visible tab. 1049 if ( ! tab.link.hasClass('hidden') ) { 1050 control.selected = tab; 1051 tab.both.addClass('library-selected'); 1052 return false; 1053 } 1054 }); 1006 /** 1007 * Called when the "Remove" link is clicked. Empties the setting. 1008 * @param {object} event jQuery Event object 1009 */ 1010 removeFile: function( event ) { 1011 if ( event.type === 'keydown' && 13 !== event.which ) { // enter 1012 return; 1013 } 1055 1014 1056 this.dropdownInit(); 1057 }, 1058 success: function( attachment ) { 1059 api.UploadControl.prototype.success.call( this, attachment ); 1015 event.preventDefault(); 1016 this.params.attachment = {}; 1017 this.setting( '' ); 1018 } 1019 }); 1060 1020 1061 // Add the uploaded image to the uploaded tab. 1062 if ( this.tabs.uploaded && this.tabs.uploaded.target.length ) { 1063 this.tabs.uploaded.both.removeClass('hidden'); 1021 /** 1022 * @constructor 1023 * @augments wp.customize.UploadControl 1024 * @augments wp.customize.Control 1025 * @augments wp.customize.Class 1026 */ 1027 api.ImageControl = api.UploadControl.extend({}); 1064 1028 1065 // @todo: Do NOT store this on the attachment model. That is bad.1066 attachment.element = $( '<a href="#" class="thumbnail"></a>' )1067 .data( 'customizeImageValue', attachment.get('url') )1068 .append( '<img src="' + attachment.get('url')+ '" />' )1069 .appendTo( this.tabs.uploaded.target );1070 }1071 },1072 thumbnailSrc: function( to ) {1073 if ( /^(https?:)?\/\//.test( to ) )1074 this.thumbnail.prop( 'src', to ).show();1075 else1076 this.thumbnail.hide();1077 }1078 });1079 1080 1029 /** 1081 1030 * @constructor 1082 1031 * @augments wp.customize.Control … … 1717 1666 api.controlConstructor = { 1718 1667 color: api.ColorControl, 1719 1668 upload: api.UploadControl, 1720 image: 1669 image: api.ImageControl, 1721 1670 header: api.HeaderControl 1722 1671 }; 1723 1672 api.panelConstructor = {}; -
src/wp-includes/class-wp-customize-control.php
637 637 * @since 3.4.0 638 638 */ 639 639 class WP_Customize_Upload_Control extends WP_Customize_Control { 640 public $type = 'upload'; 641 public $removed = ''; 642 public $context; 643 public $extensions = array(); 640 public $type = 'upload'; 641 public $mime_type = ''; 642 public $button_labels = array(); 643 public $removed = ''; // unused 644 public $context; // unused 645 public $extensions = array(); // unused 644 646 645 647 /** 648 * Constructor. 649 * 650 * @since 4.1.0 651 * @uses WP_Customize_Control::__construct() 652 * 653 * @param WP_Customize_Manager $manager 654 */ 655 public function __construct( $manager, $id, $args = array() ) { 656 parent::__construct( $manager, $id, $args ); 657 658 $this->button_labels = array( 659 'select' => __( 'Select File' ), 660 'change' => __( 'Change File' ), 661 'default' => __( 'Default' ), 662 'remove' => __( 'Remove' ), 663 'placeholder' => __( 'No file selected' ), 664 'frame_title' => __( 'Select File' ), 665 'frame_button' => __( 'Choose File' ), 666 ); 667 } 668 669 /** 646 670 * Enqueue control related scripts/styles. 647 671 * 648 672 * @since 3.4.0 649 673 */ 650 674 public function enqueue() { 651 wp_enqueue_ script( 'wp-plupload');675 wp_enqueue_media(); 652 676 } 653 677 654 678 /** … … 659 683 */ 660 684 public function to_json() { 661 685 parent::to_json(); 686 $this->json['mime_type'] = $this->mime_type; 687 $this->json['button_labels'] = $this->button_labels; 662 688 663 $this->json['removed'] = $this->removed; 689 if ( $this->setting ) { 690 if ( $this->settings['default']->value() ) { 691 // @todo: 692 // generate an attachment object & prepare for js (or fake it - needs all fields used by template) 693 // $this->json['defaultAttachment'] = $default_attachment; 694 } 664 695 665 if ( $this->context ) 666 $this->json['context'] = $this->context; 667 668 if ( $this->extensions ) 669 $this->json['extensions'] = implode( ',', $this->extensions ); 696 // Get the attachment model for the existing file, or make one. 697 if ( $this->value() ) { 698 $attachment_id = attachment_url_to_postid( $this->value() ); 699 if ( $attachment_id ) { 700 $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id); 701 } 702 } 703 } 670 704 } 671 705 672 706 /** 673 * Render the control's content.707 * Don't render any content for this control from PHP. 674 708 * 709 * @see WP_Customize_Upload_Control::content_template() 675 710 * @since 3.4.0 676 711 */ 677 public function render_content() { 712 public function render_content() {} 713 714 /** 715 * Render a JS template for the content of the upload control. 716 * 717 * @since 4.1.0 718 */ 719 public function content_template() { 678 720 ?> 679 <label> 680 <?php if ( ! empty( $this->label ) ) : ?> 681 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span> 682 <?php endif; 683 if ( ! empty( $this->description ) ) : ?> 684 <span class="description customize-control-description"><?php echo $this->description; ?></span> 685 <?php endif; ?> 686 <div> 687 <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a> 688 <a href="#" class="remove"><?php _e( 'Remove' ); ?></a> 721 <label for="{{ data.settings.default }}-button"> 722 <# if ( data.label ) { #> 723 <span class="customize-control-title">{{ data.label }}</span> 724 <# } #> 725 <# if ( data.description ) { #> 726 <span class="description customize-control-description">{{ data.description }}</span> 727 <# } #> 728 </label> 729 730 <# if ( data.attachment && data.attachment.id ) { #> 731 <div class="attachment-media-view {{ data.attachment.orientation }}"> 732 <div class="thumbnail thumbnail-{{ data.attachment.type }}"> 733 <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #> 734 <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" /> 735 <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #> 736 <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" /> 737 <# } else if ( -1 === jQuery.inArray( data.attachment.type, [ 'audio', 'video' ] ) ) { #> 738 <img class="attachment-thumb type-icon" src="{{ data.attachment.icon }}" class="icon" draggable="false" /> 739 <p class="attachment-title">{{ data.attachment.title }}</p> 740 <# } #> 741 742 <# if ( 'audio' === data.attachment.type ) { #> 743 <div class="wp-media-wrapper"> 744 <p class="attachment-title">{{ data.attachment.title }}</p> 745 <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none"> 746 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/> 747 </audio> 748 </div> 749 <# } else if ( 'video' === data.attachment.type ) { 750 var w_rule = h_rule = ''; 751 if ( data.attachment.width ) { 752 w_rule = 'width: ' + data.attachment.width + 'px;'; 753 } else if ( wp.media.view.settings.contentWidth ) { 754 w_rule = 'width: ' + wp.media.view.settings.contentWidth + 'px;'; 755 } 756 if ( data.attachment.height ) { 757 h_rule = 'height: ' + data.attachment.height + 'px;'; 758 } 759 #> 760 <div style="{{ w_rule }}{{ h_rule }}" class="wp-media-wrapper wp-video"> 761 <video controls="controls" class="wp-video-shortcode" preload="metadata" 762 <# if ( data.attachment.width ) { #>width="{{ data.attachment.width }}"<# } #> 763 <# if ( data.attachment.height ) { #>height="{{ data.attachment.height }}"<# } #> 764 <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>> 765 <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/> 766 </video> 767 </div> 768 <# } #> 769 </div> 689 770 </div> 690 </label> 771 <a class="button upload-button" id="{{ data.settings.default }}-button" href="#"><?php echo $this->button_labels['change']; ?></a> 772 <# if ( data.defaultAttachmet && data.defaultAttachment.id !== data.attachment.id ) { #> 773 <a class="default-button remove-button" href="#"><?php echo $this->button_labels['default']; ?></a> 774 <# } else { #> 775 <a class="remove-button" href="#"><?php echo $this->button_labels['remove']; ?></a> 776 <# } #> 777 <# } else { #> 778 <p class="placeholder-text"><?php echo $this->button_labels['placeholder']; ?></p> 779 <a class="button upload-button" id="{{ data.settings.default }}-button" href="#"><?php echo $this->button_labels['select']; ?></a> 780 <# } #> 691 781 <?php 692 782 } 693 783 } … … 701 791 */ 702 792 class WP_Customize_Image_Control extends WP_Customize_Upload_Control { 703 793 public $type = 'image'; 704 public $get_url; 705 public $statuses; 706 public $extensions = array( 'jpg', 'jpeg', 'gif', 'png' ); 794 public $mime_type = 'image'; 707 795 708 protected $tabs = array();709 710 796 /** 711 797 * Constructor. 712 798 * 713 * @since 3.4.0799 * @since 4.1.0 714 800 * @uses WP_Customize_Upload_Control::__construct() 715 801 * 716 802 * @param WP_Customize_Manager $manager 717 * @param string $id718 * @param array $args719 803 */ 720 public function __construct( $manager, $id, $args ) { 721 $this->statuses = array( '' => __('No Image') ); 722 804 public function __construct( $manager, $id, $args = array() ) { 723 805 parent::__construct( $manager, $id, $args ); 724 806 725 $this->add_tab( 'upload-new', __('Upload New'), array( $this, 'tab_upload_new' ) ); 726 $this->add_tab( 'uploaded', __('Uploaded'), array( $this, 'tab_uploaded' ) ); 727 728 // Early priority to occur before $this->manager->prepare_controls(); 729 add_action( 'customize_controls_init', array( $this, 'prepare_control' ), 5 ); 807 $this->button_labels = array( 808 'select' => __( 'Select Image' ), 809 'change' => __( 'Change Image' ), 810 'remove' => __( 'Remove' ), 811 'default' => __( 'Default' ), 812 'placeholder' => __( 'No image selected' ), 813 'frame_title' => __( 'Select Image' ), 814 'frame_button' => __( 'Choose Image' ), 815 ); 730 816 } 731 817 732 818 /** 733 * Prepares the control.734 *735 * If no tabs exist, removes the control from the manager.736 *737 819 * @since 3.4.2 820 * @deprecated 4.1.0 738 821 */ 739 public function prepare_control() { 740 if ( ! $this->tabs ) 741 $this->manager->remove_control( $this->id ); 742 } 822 public function prepare_control() {} 743 823 744 824 /** 745 * Refresh the parameters passed to the JavaScript via JSON.746 *747 825 * @since 3.4.0 748 * @uses WP_Customize_Upload_Control::to_json() 749 */ 750 public function to_json() { 751 parent::to_json(); 752 $this->json['statuses'] = $this->statuses; 753 } 754 755 /** 756 * Render the control's content. 826 * @deprecated 4.1.0 757 827 * 758 * @since 3.4.0759 */760 public function render_content() {761 $src = $this->value();762 if ( isset( $this->get_url ) )763 $src = call_user_func( $this->get_url, $src );764 765 ?>766 <div class="customize-image-picker">767 <?php if ( ! empty( $this->label ) ) : ?>768 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>769 <?php endif;770 if ( ! empty( $this->description ) ) : ?>771 <span class="description customize-control-description"><?php echo $this->description; ?></span>772 <?php endif; ?>773 774 <div class="customize-control-content">775 <div class="dropdown preview-thumbnail" tabindex="0">776 <div class="dropdown-content">777 <?php if ( empty( $src ) ): ?>778 <img style="display:none;" />779 <?php else: ?>780 <img src="<?php echo esc_url( set_url_scheme( $src ) ); ?>" />781 <?php endif; ?>782 <div class="dropdown-status"></div>783 </div>784 <div class="dropdown-arrow"></div>785 </div>786 </div>787 788 <div class="library">789 <ul>790 <?php foreach ( $this->tabs as $id => $tab ): ?>791 <li data-customize-tab='<?php echo esc_attr( $id ); ?>' tabindex='0'>792 <?php echo esc_html( $tab['label'] ); ?>793 </li>794 <?php endforeach; ?>795 </ul>796 <?php foreach ( $this->tabs as $id => $tab ): ?>797 <div class="library-content" data-customize-tab='<?php echo esc_attr( $id ); ?>'>798 <?php call_user_func( $tab['callback'] ); ?>799 </div>800 <?php endforeach; ?>801 </div>802 803 <div class="actions">804 <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>805 </div>806 </div>807 <?php808 }809 810 /**811 * Add a tab to the control.812 *813 * @since 3.4.0814 *815 828 * @param string $id 816 829 * @param string $label 817 830 * @param mixed $callback 818 831 */ 819 public function add_tab( $id, $label, $callback ) { 820 $this->tabs[ $id ] = array( 821 'label' => $label, 822 'callback' => $callback, 823 ); 824 } 832 public function add_tab( $id, $label, $callback ) {} 825 833 826 834 /** 827 * Remove a tab from the control.828 *829 835 * @since 3.4.0 836 * @deprecated 4.1.0 830 837 * 831 838 * @param string $id 832 839 */ 833 public function remove_tab( $id ) { 834 unset( $this->tabs[ $id ] ); 835 } 840 public function remove_tab( $id ) {} 836 841 837 842 /** 838 843 * @since 3.4.0 839 */ 840 public function tab_upload_new() { 841 if ( ! _device_can_upload() ) { 842 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>'; 843 } else { 844 ?> 845 <div class="upload-dropzone"> 846 <?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?> 847 </div> 848 <div class="upload-fallback"> 849 <span class="button-secondary"><?php _e('Select File'); ?></span> 850 </div> 851 <?php 852 } 853 } 854 855 /** 856 * @since 3.4.0 857 */ 858 public function tab_uploaded() { 859 ?> 860 <div class="uploaded-target"></div> 861 <?php 862 } 863 864 /** 865 * @since 3.4.0 844 * @deprecated 4.1.0 866 845 * 867 846 * @param string $url 868 847 * @param string $thumbnail_url 869 848 */ 870 public function print_tab_image( $url, $thumbnail_url = null ) { 871 $url = set_url_scheme( $url ); 872 $thumbnail_url = ( $thumbnail_url ) ? set_url_scheme( $thumbnail_url ) : $url; 873 ?> 874 <a href="#" class="thumbnail" data-customize-image-value="<?php echo esc_url( $url ); ?>"> 875 <img src="<?php echo esc_url( $thumbnail_url ); ?>" /> 876 </a> 877 <?php 878 } 849 public function print_tab_image( $url, $thumbnail_url = null ) {} 879 850 } 880 851 881 852 /** -
src/wp-includes/class-wp-customize-manager.php
965 965 966 966 /* Control Types (custom control classes) */ 967 967 $this->register_control_type( 'WP_Customize_Color_Control' ); 968 $this->register_control_type( 'WP_Customize_Upload_Control' ); 969 $this->register_control_type( 'WP_Customize_Image_Control' ); 968 970 969 971 /* Site Title & Tagline */ 970 972