Changeset 33154
- Timestamp:
- 07/10/2015 09:32:23 PM (10 years ago)
- Location:
- trunk/src
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/admin-ajax.php
r32677 r33154 63 63 'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail', 64 64 'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post', 65 'press-this-add-category', 65 'press-this-add-category', 'crop-image', 66 66 ); 67 67 -
trunk/src/wp-admin/css/customize-controls.css
r33153 r33154 752 752 .customize-control-image .current, 753 753 .customize-control-background .current, 754 .customize-control-cropped_image .current, 755 .customize-control-site_icon .current, 754 756 .customize-control-header .current { 755 757 margin-bottom: 8px; … … 787 789 .customize-control-background .default-button, 788 790 .customize-control-background .upload-button, 791 .customize-control-cropped_image .remove-button, 792 .customize-control-cropped_image .default-button, 793 .customize-control-cropped_image .upload-button, 794 .customize-control-site_icon .remove-button, 795 .customize-control-site_icon .default-button, 796 .customize-control-site_icon .upload-button, 789 797 .customize-control-header button.new, 790 798 .customize-control-header button.remove { … … 798 806 .customize-control-image .current .container, 799 807 .customize-control-background .current .container, 808 .customize-control-cropped_image .current .container, 809 .customize-control-site_icon .current .container, 800 810 .customize-control-header .current .container { 801 811 overflow: hidden; … … 809 819 .customize-control-upload .current .container, 810 820 .customize-control-background .current .container, 821 .customize-control-cropped_image .current .container, 822 .customize-control-site_icon .current .container, 811 823 .customize-control-image .current .container { 812 824 min-height: 40px; … … 817 829 .customize-control-image .placeholder, 818 830 .customize-control-background .placeholder, 831 .customize-control-cropped_image .placeholder, 832 .customize-control-site_icon .placeholder, 819 833 .customize-control-header .placeholder { 820 834 width: 100%; … … 828 842 .customize-control-image .inner, 829 843 .customize-control-background .inner, 844 .customize-control-cropped_image .inner, 845 .customize-control-site_icon .inner, 830 846 .customize-control-header .inner { 831 847 display: none; … … 841 857 .customize-control-upload .inner, 842 858 .customize-control-background .inner, 859 .customize-control-cropped_image .inner, 860 .customize-control-site_icon .inner, 843 861 .customize-control-image .inner { 844 862 display: block; … … 850 868 .customize-control-image .inner, 851 869 .customize-control-background .inner, 870 .customize-control-cropped_image .inner, 871 .customize-control-site_icon .inner, 852 872 .customize-control-header .inner, 853 873 .customize-control-header .inner .dashicons { … … 953 973 .customize-control-image .actions, 954 974 .customize-control-background .actions, 975 .customize-control-cropped_image .actions, 976 .customize-control-site_icon .actions, 955 977 .customize-control-header .actions { 956 978 margin-bottom: 32px; … … 971 993 .customize-control-image img, 972 994 .customize-control-background img, 995 .customize-control-cropped_image img, 996 .customize-control-site_icon img, 973 997 .customize-control-header img { 974 998 width: 100%; … … 985 1009 .customize-control-background .remove-button, 986 1010 .customize-control-background .default-button, 1011 .customize-control-cropped_image .remove-button, 1012 .customize-control-cropped_image .default-button, 1013 .customize-control-site_icon .remove-button, 1014 .customize-control-site_icon .default-button, 987 1015 .customize-control-header .remove { 988 1016 float: left; … … 994 1022 .customize-control-image .upload-button, 995 1023 .customize-control-background .upload-button, 1024 .customize-control-cropped_image .upload-button, 1025 .customize-control-site_icon .upload-button, 996 1026 .customize-control-header .new { 997 1027 float: right; -
trunk/src/wp-admin/includes/ajax-actions.php
r32965 r33154 3053 3053 $GLOBALS['wp_press_this']->add_category(); 3054 3054 } 3055 3056 /** 3057 * AJAX handler for cropping an image. 3058 * 3059 * @since 4.3.0 3060 * 3061 * @global WP_Site_Icon $wp_site_icon 3062 */ 3063 function wp_ajax_crop_image() { 3064 $attachment_id = absint( $_POST['id'] ); 3065 3066 check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' ); 3067 if ( ! current_user_can( 'customize' ) ) { 3068 wp_send_json_error(); 3069 } 3070 3071 $context = str_replace( '_', '-', $_POST['context'] ); 3072 $data = array_map( 'absint', $_POST['cropDetails'] ); 3073 $cropped = wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] ); 3074 3075 if ( ! $cropped || is_wp_error( $cropped ) ) { 3076 wp_send_json_error( array( 'message' => __( 'Image could not be processed.' ) ) ); 3077 } 3078 3079 switch ( $context ) { 3080 case 'site-icon': 3081 require_once ABSPATH . '/wp-admin/includes/class-wp-site-icon.php'; 3082 global $wp_site_icon; 3083 3084 /** This filter is documented in wp-admin/custom-header.php */ 3085 $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. 3086 $object = $wp_site_icon->create_attachment_object( $cropped, $attachment_id ); 3087 unset( $object['ID'] ); 3088 3089 // Update the attachment. 3090 add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); 3091 $attachment_id = $wp_site_icon->insert_attachment( $object, $cropped ); 3092 remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); 3093 3094 // Additional sizes in wp_prepare_attachment_for_js(). 3095 add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) ); 3096 break; 3097 3098 default: 3099 3100 /** 3101 * Filters the attachment id for a cropped image. 3102 * 3103 * @since 4.3.0 3104 * 3105 * @param int $attachment_id The ID of the cropped image. 3106 * @param string $context The feature requesting the cropped image. 3107 */ 3108 $attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', 0, $context ); 3109 3110 if ( ! $attachment_id ) { 3111 wp_send_json_error(); 3112 } 3113 } 3114 3115 wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) ); 3116 } -
trunk/src/wp-admin/includes/class-wp-site-icon.php
r33084 r33154 275 275 <div class="site-icon-crop-preview-shell hide-if-no-js"> 276 276 <h3><?php _e( 'Preview' ); ?></h3> 277 <strong><?php _e( 'As your favicon' ); ?></strong>277 <strong><?php _e( 'As a browser icon' ); ?></strong> 278 278 <div class="site-icon-crop-favicon-preview-shell"> 279 279 <img src="images/browser.png" class="site-icon-browser-preview" width="182" height="" alt="<?php esc_attr_e( 'Browser Chrome' ); ?>"/> … … 285 285 </div> 286 286 287 <strong><?php _e( 'As a mobileicon' ); ?></strong>287 <strong><?php _e( 'As an app icon' ); ?></strong> 288 288 <div class="site-icon-crop-preview-homeicon"> 289 289 <img src="<?php echo esc_url( $url ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' ); ?>"/> … … 506 506 // ensure that we only resize the image into 507 507 foreach ( $sizes as $name => $size_array ) { 508 if ( $size_array['crop']) {508 if ( isset( $size_array['crop'] ) ) { 509 509 $only_crop_sizes[ $name ] = $size_array; 510 510 } -
trunk/src/wp-admin/js/customize-controls.js
r33153 r33154 1837 1837 1838 1838 /** 1839 * A control for selecting and cropping an image. 1840 * 1841 * @class 1842 * @augments wp.customize.MediaControl 1843 * @augments wp.customize.Control 1844 * @augments wp.customize.Class 1845 */ 1846 api.CroppedImageControl = api.MediaControl.extend({ 1847 1848 /** 1849 * Open the media modal to the library state. 1850 */ 1851 openFrame: function( event ) { 1852 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 1853 return; 1854 } 1855 1856 this.initFrame(); 1857 this.frame.setState( 'library' ).open(); 1858 }, 1859 1860 /** 1861 * Create a media modal select frame, and store it so the instance can be reused when needed. 1862 */ 1863 initFrame: function() { 1864 var l10n = _wpMediaViewsL10n; 1865 1866 this.frame = wp.media({ 1867 button: { 1868 text: l10n.select, 1869 close: false 1870 }, 1871 states: [ 1872 new wp.media.controller.Library({ 1873 title: this.params.button_labels.frame_title, 1874 library: wp.media.query({ type: 'image' }), 1875 multiple: false, 1876 date: false, 1877 priority: 20, 1878 suggestedWidth: this.params.width, 1879 suggestedHeight: this.params.height 1880 }), 1881 new wp.media.controller.customizeImageCropper({ 1882 imgSelectOptions: this.calculateImageSelectOptions, 1883 control: this 1884 }) 1885 ] 1886 }); 1887 1888 this.frame.on( 'select', this.onSelect, this ); 1889 this.frame.on( 'cropped', this.onCropped, this ); 1890 this.frame.on( 'skippedcrop', this.onSkippedCrop, this ); 1891 }, 1892 1893 /** 1894 * After an image is selected in the media modal, switch to the cropper 1895 * state if the image isn't the right size. 1896 */ 1897 onSelect: function() { 1898 var attachment = this.frame.state().get( 'selection' ).first().toJSON(); 1899 1900 if ( this.params.width === attachment.width && this.params.height === attachment.height && ! this.params.flex_width && ! this.params.flex_height ) { 1901 this.setImageFromAttachment( attachment ); 1902 this.frame.close(); 1903 } else { 1904 this.frame.setState( 'cropper' ); 1905 } 1906 }, 1907 1908 /** 1909 * After the image has been cropped, apply the cropped image data to the setting. 1910 * 1911 * @param {object} croppedImage Cropped attachment data. 1912 */ 1913 onCropped: function( croppedImage ) { 1914 this.setImageFromAttachment( croppedImage ); 1915 }, 1916 1917 /** 1918 * Returns a set of options, computed from the attached image data and 1919 * control-specific data, to be fed to the imgAreaSelect plugin in 1920 * wp.media.view.Cropper. 1921 * 1922 * @param {wp.media.model.Attachment} attachment 1923 * @param {wp.media.controller.Cropper} controller 1924 * @returns {Object} Options 1925 */ 1926 calculateImageSelectOptions: function( attachment, controller ) { 1927 var control = controller.get( 'control' ), 1928 flexWidth = !! parseInt( control.params.flex_width, 10 ), 1929 flexHeight = !! parseInt( control.params.flex_height, 10 ), 1930 realWidth = attachment.get( 'width' ), 1931 realHeight = attachment.get( 'height' ), 1932 xInit = parseInt( control.params.width, 10 ), 1933 yInit = parseInt( control.params.height, 10 ), 1934 ratio = xInit / yInit, 1935 xImg = realWidth, 1936 yImg = realHeight, 1937 imgSelectOptions; 1938 1939 controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); 1940 1941 if ( xImg / yImg > ratio ) { 1942 yInit = yImg; 1943 xInit = yInit * ratio; 1944 } else { 1945 xInit = xImg; 1946 yInit = xInit / ratio; 1947 } 1948 1949 imgSelectOptions = { 1950 handles: true, 1951 keys: true, 1952 instance: true, 1953 persistent: true, 1954 imageWidth: realWidth, 1955 imageHeight: realHeight, 1956 x1: 0, 1957 y1: 0, 1958 x2: xInit, 1959 y2: yInit 1960 }; 1961 1962 if ( flexHeight === false && flexWidth === false ) { 1963 imgSelectOptions.aspectRatio = xInit + ':' + yInit; 1964 } 1965 if ( flexHeight === false ) { 1966 imgSelectOptions.maxHeight = yInit; 1967 } 1968 if ( flexWidth === false ) { 1969 imgSelectOptions.maxWidth = xInit; 1970 } 1971 1972 return imgSelectOptions; 1973 }, 1974 1975 /** 1976 * Return whether the image must be cropped, based on required dimensions. 1977 * 1978 * @param {bool} flexW 1979 * @param {bool} flexH 1980 * @param {int} dstW 1981 * @param {int} dstH 1982 * @param {int} imgW 1983 * @param {int} imgH 1984 * @return {bool} 1985 */ 1986 mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) { 1987 if ( true === flexW && true === flexH ) { 1988 return false; 1989 } 1990 1991 if ( true === flexW && dstH === imgH ) { 1992 return false; 1993 } 1994 1995 if ( true === flexH && dstW === imgW ) { 1996 return false; 1997 } 1998 1999 if ( dstW === imgW && dstH === imgH ) { 2000 return false; 2001 } 2002 2003 if ( imgW <= dstW ) { 2004 return false; 2005 } 2006 2007 return true; 2008 }, 2009 2010 /** 2011 * If cropping was skipped, apply the image data directly to the setting. 2012 */ 2013 onSkippedCrop: function() { 2014 var attachment = this.frame.state().get( 'selection' ).first().toJSON(); 2015 this.setImageFromAttachment( attachment ); 2016 }, 2017 2018 /** 2019 * Updates the setting and re-renders the control UI. 2020 * 2021 * @param {object} attachment 2022 */ 2023 setImageFromAttachment: function( attachment ) { 2024 this.params.attachment = attachment; 2025 2026 // Set the Customizer setting; the callback takes care of rendering. 2027 this.setting( attachment.id ); 2028 } 2029 }); 2030 2031 /** 2032 * A control for selecting and cropping Site Icons. 2033 * 2034 * @class 2035 * @augments wp.customize.CroppedImageControl 2036 * @augments wp.customize.MediaControl 2037 * @augments wp.customize.Control 2038 * @augments wp.customize.Class 2039 */ 2040 api.SiteIconControl = api.CroppedImageControl.extend({ 2041 /** 2042 * Updates the setting and re-renders the control UI. 2043 * 2044 * @param {object} attachment 2045 */ 2046 setImageFromAttachment: function( attachment ) { 2047 var icon = typeof attachment.sizes['site_icon-32'] !== 'undefined' ? attachment.sizes['site_icon-32'] : attachment.sizes.thumbnail; 2048 2049 this.params.attachment = attachment; 2050 2051 // Set the Customizer setting; the callback takes care of rendering. 2052 this.setting( attachment.id ); 2053 2054 2055 // Update the icon in-browser. 2056 $( 'link[rel="icon"]' ).attr( 'href', icon.url ); 2057 }, 2058 2059 /** 2060 * Called when the "Remove" link is clicked. Empties the setting. 2061 * 2062 * @param {object} event jQuery Event object 2063 */ 2064 removeFile: function( event ) { 2065 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 2066 return; 2067 } 2068 event.preventDefault(); 2069 2070 this.params.attachment = {}; 2071 this.setting( '' ); 2072 this.renderContent(); // Not bound to setting change when emptying. 2073 $( 'link[rel="icon"]' ).attr( 'href', '' ); 2074 } 2075 }); 2076 2077 /** 1839 2078 * @class 1840 2079 * @augments wp.customize.Control … … 2696 2935 2697 2936 api.controlConstructor = { 2698 color: api.ColorControl, 2699 media: api.MediaControl, 2700 upload: api.UploadControl, 2701 image: api.ImageControl, 2702 header: api.HeaderControl, 2703 background: api.BackgroundControl, 2704 theme: api.ThemeControl 2937 color: api.ColorControl, 2938 media: api.MediaControl, 2939 upload: api.UploadControl, 2940 image: api.ImageControl, 2941 cropped_image: api.CroppedImageControl, 2942 site_icon: api.SiteIconControl, 2943 header: api.HeaderControl, 2944 background: api.BackgroundControl, 2945 theme: api.ThemeControl 2705 2946 }; 2706 2947 api.panelConstructor = {}; -
trunk/src/wp-admin/options-general.php
r33075 r33154 164 164 165 165 <?php endif; ?> 166 <p class="description"><?php _e( ' Site Icon creates a favicon and app icons for your site.' )?></p>166 <p class="description"><?php _e( 'The Site Icon is used as a browser and app icon for your site.' ); ?></p> 167 167 </td> 168 168 </tr> -
trunk/src/wp-includes/class-wp-customize-control.php
r33090 r33154 1002 1002 1003 1003 /** 1004 * Customize Cropped Image Control class. 1005 * 1006 * @since 4.3.0 1007 * 1008 * @see WP_Customize_Image_Control 1009 */ 1010 class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control { 1011 1012 /** 1013 * Control type. 1014 * 1015 * @since 4.3.0 1016 * 1017 * @access public 1018 * @var string 1019 */ 1020 public $type = 'cropped_image'; 1021 1022 /** 1023 * Suggested width for cropped image. 1024 * 1025 * @since 4.3.0 1026 * 1027 * @access public 1028 * @var int 1029 */ 1030 public $width = 150; 1031 1032 /** 1033 * Suggested height for cropped image. 1034 * 1035 * @since 4.3.0 1036 * 1037 * @access public 1038 * @var int 1039 */ 1040 public $height = 150; 1041 1042 /** 1043 * Whether the width is flexible. 1044 * 1045 * @since 4.3.0 1046 * 1047 * @access public 1048 * @var bool 1049 */ 1050 public $flex_width = false; 1051 1052 /** 1053 * Whether the height is flexible. 1054 * 1055 * @since 4.3.0 1056 * 1057 * @access public 1058 * @var bool 1059 */ 1060 public $flex_height = false; 1061 1062 /** 1063 * Enqueue control related scripts/styles. 1064 * 1065 * @since 4.3.0 1066 * 1067 * @access public 1068 */ 1069 public function enqueue() { 1070 wp_enqueue_script( 'customize-views' ); 1071 1072 parent::enqueue(); 1073 } 1074 1075 /** 1076 * Refresh the parameters passed to the JavaScript via JSON. 1077 * 1078 * @since 4.3.0 1079 * 1080 * @access public 1081 * @uses WP_Customize_Image_Control::to_json() 1082 * @see WP_Customize_Control::to_json() 1083 */ 1084 public function to_json() { 1085 parent::to_json(); 1086 1087 $this->json['width'] = absint( $this->width ); 1088 $this->json['height'] = absint( $this->height ); 1089 $this->json['flex_width'] = absint( $this->flex_width ); 1090 $this->json['flex_height'] = absint( $this->flex_height ); 1091 } 1092 1093 } 1094 1095 /** 1096 * Customize Site Icon control class. 1097 * 1098 * Used only for custom functionality in JavaScript. 1099 * 1100 * @since 4.3.0 1101 * 1102 * @see WP_Customize_Cropped_Image_Control 1103 */ 1104 class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control { 1105 1106 /** 1107 * Control type. 1108 * 1109 * @since 4.3.0 1110 * 1111 * @access public 1112 * @var string 1113 */ 1114 public $type = 'site_icon'; 1115 1116 /** 1117 * Constructor. 1118 * 1119 * @since 4.3.0 1120 * 1121 * @param WP_Customize_Manager $manager 1122 * @param string $id 1123 * @param array $args 1124 */ 1125 public function __construct( $manager, $id, $args = array() ) { 1126 parent::__construct( $manager, $id, $args ); 1127 add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 ); 1128 } 1129 } 1130 1131 /** 1004 1132 * Customize Header Image Control class. 1005 1133 * -
trunk/src/wp-includes/class-wp-customize-manager.php
r32964 r33154 1279 1279 $this->register_control_type( 'WP_Customize_Image_Control' ); 1280 1280 $this->register_control_type( 'WP_Customize_Background_Image_Control' ); 1281 $this->register_control_type( 'WP_Customize_Cropped_Image_Control' ); 1282 $this->register_control_type( 'WP_Customize_Site_Icon_Control' ); 1281 1283 $this->register_control_type( 'WP_Customize_Theme_Control' ); 1282 1284 … … 1325 1327 } 1326 1328 1327 /* Site Title & Tagline*/1329 /* Site Identity */ 1328 1330 1329 1331 $this->add_section( 'title_tagline', array( 1330 'title' => __( 'Site Title & Tagline' ),1332 'title' => __( 'Site Identity' ), 1331 1333 'priority' => 20, 1332 1334 ) ); … … 1353 1355 'section' => 'title_tagline', 1354 1356 ) ); 1357 1358 $icon = wp_get_attachment_image_src( absint( get_option( 'site_icon' ) ), 'full' ); 1359 $this->add_setting( 'site_icon', array( 1360 'default' => $icon[0] ? $icon[0] : '', 1361 'type' => 'option', 1362 'capability' => 'manage_options', 1363 'transport' => 'postMessage', // Previewed with JS in the Customizer controls window. 1364 ) ); 1365 1366 $this->add_control( new WP_Customize_Site_Icon_Control( $this, 'site_icon', array( 1367 'label' => __( 'Site Icon' ), 1368 'description' => __( 'The Site Icon is used as a browser and app icon for your site. Icons must be square, and at least 512px wide and tall.' ), 1369 'section' => 'title_tagline', 1370 'priority' => 60, 1371 'height' => 512, 1372 'width' => 512, 1373 ) ) ); 1355 1374 1356 1375 /* Colors */ … … 1376 1395 'section' => 'title_tagline', 1377 1396 'type' => 'checkbox', 1397 'priority' => 40, 1378 1398 ) ); 1379 1399 -
trunk/src/wp-includes/general-template.php
r32994 r33154 2446 2446 */ 2447 2447 function wp_site_icon() { 2448 if ( ! has_site_icon() ) {2448 if ( ! has_site_icon() && ! is_customize_preview() ) { 2449 2449 return; 2450 2450 } -
trunk/src/wp-includes/js/customize-views.js
r31471 r33154 4 4 var api = wp.customize; 5 5 6 /** 7 * Use a custom ajax action for cropped image controls. 8 */ 9 wp.media.controller.customizeImageCropper = wp.media.controller.Cropper.extend( { 10 doCrop: function( attachment ) { 11 var cropDetails = attachment.get( 'cropDetails' ), 12 control = this.get( 'control' ); 13 14 cropDetails.dst_width = control.params.width; 15 cropDetails.dst_height = control.params.height; 16 17 return wp.ajax.post( 'crop-image', { 18 wp_customize: 'on', 19 nonce: attachment.get( 'nonces' ).edit, 20 id: attachment.get( 'id' ), 21 context: control.id, 22 cropDetails: cropDetails 23 } ); 24 } 25 } ); 6 26 7 27 /**
Note: See TracChangeset
for help on using the changeset viewer.