Ticket #16434: 16434.16.diff
File 16434.16.diff, 21.7 KB (added by , 9 years ago) |
---|
-
src/wp-admin/admin-ajax.php
62 62 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs', 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 68 68 // Deprecated -
src/wp-admin/css/customize-controls.css
771 771 .customize-control-upload .current, 772 772 .customize-control-image .current, 773 773 .customize-control-background .current, 774 .customize-control-cropped_image .current, 775 .customize-control-site_icon .current, 774 776 .customize-control-header .current { 775 777 margin-bottom: 8px; 776 778 } … … 806 808 .customize-control-background .remove-button, 807 809 .customize-control-background .default-button, 808 810 .customize-control-background .upload-button, 811 .customize-control-cropped_image .remove-button, 812 .customize-control-cropped_image .default-button, 813 .customize-control-cropped_image .upload-button, 814 .customize-control-site_icon .remove-button, 815 .customize-control-site_icon .default-button, 816 .customize-control-site_icon .upload-button, 809 817 .customize-control-header button.new, 810 818 .customize-control-header button.remove { 811 819 white-space: normal; … … 817 825 .customize-control-upload .current .container, 818 826 .customize-control-image .current .container, 819 827 .customize-control-background .current .container, 828 .customize-control-cropped_image .current .container, 829 .customize-control-site_icon .current .container, 820 830 .customize-control-header .current .container { 821 831 overflow: hidden; 822 832 -webkit-border-radius: 2px; … … 828 838 .customize-control-media .current .container, 829 839 .customize-control-upload .current .container, 830 840 .customize-control-background .current .container, 841 .customize-control-cropped_image .current .container, 842 .customize-control-site_icon .current .container, 831 843 .customize-control-image .current .container { 832 844 min-height: 40px; 833 845 } … … 836 848 .customize-control-upload .placeholder, 837 849 .customize-control-image .placeholder, 838 850 .customize-control-background .placeholder, 851 .customize-control-cropped_image .placeholder, 852 .customize-control-site_icon .placeholder, 839 853 .customize-control-header .placeholder { 840 854 width: 100%; 841 855 position: relative; … … 847 861 .customize-control-upload .inner, 848 862 .customize-control-image .inner, 849 863 .customize-control-background .inner, 864 .customize-control-cropped_image .inner, 865 .customize-control-site_icon .inner, 850 866 .customize-control-header .inner { 851 867 display: none; 852 868 position: absolute; … … 860 876 .customize-control-media .inner, 861 877 .customize-control-upload .inner, 862 878 .customize-control-background .inner, 879 .customize-control-cropped_image .inner, 880 .customize-control-site_icon .inner, 863 881 .customize-control-image .inner { 864 882 display: block; 865 883 min-height: 40px; … … 869 887 .customize-control-upload .inner, 870 888 .customize-control-image .inner, 871 889 .customize-control-background .inner, 890 .customize-control-cropped_image .inner, 891 .customize-control-site_icon .inner, 872 892 .customize-control-header .inner, 873 893 .customize-control-header .inner .dashicons { 874 894 line-height: 20px; … … 972 992 .customize-control-upload .actions, 973 993 .customize-control-image .actions, 974 994 .customize-control-background .actions, 995 .customize-control-cropped_image .actions, 996 .customize-control-site_icon .actions, 975 997 .customize-control-header .actions { 976 998 margin-bottom: 32px; 977 999 } … … 990 1012 .customize-control-upload img, 991 1013 .customize-control-image img, 992 1014 .customize-control-background img, 1015 .customize-control-cropped_image img, 1016 .customize-control-site_icon img, 993 1017 .customize-control-header img { 994 1018 width: 100%; 995 1019 -webkit-border-radius: 2px; … … 1004 1028 .customize-control-image .default-button, 1005 1029 .customize-control-background .remove-button, 1006 1030 .customize-control-background .default-button, 1031 .customize-control-cropped_image .remove-button, 1032 .customize-control-cropped_image .default-button, 1033 .customize-control-site_icon .remove-button, 1034 .customize-control-site_icon .default-button, 1007 1035 .customize-control-header .remove { 1008 1036 float: left; 1009 1037 margin-right: 3px; … … 1013 1041 .customize-control-upload .upload-button, 1014 1042 .customize-control-image .upload-button, 1015 1043 .customize-control-background .upload-button, 1044 .customize-control-cropped_image .upload-button, 1045 .customize-control-site_icon .upload-button, 1016 1046 .customize-control-header .new { 1017 1047 float: right; 1018 1048 } -
src/wp-admin/includes/ajax-actions.php
3052 3052 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 = $_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 add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) ); 3095 break; 3096 3097 default: 3098 3099 /** 3100 * Filters the attachment id for a cropped image. 3101 * 3102 * @since 4.3.0 3103 * 3104 * @param int $attachment_id The ID of the cropped image. 3105 * @param string $context The feature requesting the cropped image. 3106 */ 3107 $attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', 0, $context ); 3108 } 3109 3110 if ( ! $attachment_id ) { 3111 wp_send_json_error(); 3112 } 3113 3114 wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) ); 3115 } -
src/wp-admin/includes/class-wp-site-icon.php
274 274 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' ); ?>"/> 280 280 … … 284 284 <span class="site-icon-browser-title"><?php bloginfo( 'name' ); ?></span> 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' ); ?>"/> 290 290 </div> … … 505 505 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 } 511 511 } -
src/wp-admin/js/customize-controls.js
1836 1836 }); 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 * Open the media modal to the library state. 1849 */ 1850 openFrame: function( event ) { 1851 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 1852 return; 1853 } 1854 1855 this.initFrame(); 1856 this.frame.setState( 'library' ).open(); 1857 }, 1858 1859 /** 1860 * Create a media modal select frame, and store it so the instance can be reused when needed. 1861 */ 1862 initFrame: function() { 1863 var l10n = _wpMediaViewsL10n; 1864 1865 this.frame = wp.media({ 1866 button: { 1867 text: l10n.selectAndCrop, 1868 close: false 1869 }, 1870 states: [ 1871 new wp.media.controller.Library({ 1872 title: this.params.button_labels.frame_title, 1873 library: wp.media.query({ type: 'image' }), 1874 multiple: false, 1875 date: false, 1876 priority: 20, 1877 suggestedWidth: this.params.width, 1878 suggestedHeight: this.params.height 1879 }), 1880 new wp.media.controller.customizeImageCropper({ 1881 imgSelectOptions: this.calculateImageSelectOptions, 1882 control: this 1883 }) 1884 ] 1885 }); 1886 1887 this.frame.on( 'select', this.onSelect, this ); 1888 this.frame.on( 'cropped', this.onCropped, this ); 1889 this.frame.on( 'skippedcrop', this.onSkippedCrop, this ); 1890 }, 1891 1892 /** 1893 * After an image is selected in the media modal, 1894 * switch to the cropper state. 1895 */ 1896 onSelect: function() { 1897 this.frame.setState( 'cropper' ); 1898 }, 1899 1900 /** 1901 * After the image has been cropped, apply the cropped image data to the setting. 1902 * 1903 * @param {object} croppedImage Cropped attachment data. 1904 */ 1905 onCropped: function( croppedImage ) { 1906 this.setImageFromAttachment( croppedImage ); 1907 }, 1908 1909 /** 1910 * Returns a set of options, computed from the attached image data and 1911 * control-specific data, to be fed to the imgAreaSelect plugin in 1912 * wp.media.view.Cropper. 1913 * 1914 * @param {wp.media.model.Attachment} attachment 1915 * @param {wp.media.controller.Cropper} controller 1916 * @returns {Object} Options 1917 */ 1918 calculateImageSelectOptions: function( attachment, controller ) { 1919 var control = controller.get( 'control' ), 1920 xInit = parseInt( control.params.width, 10 ), 1921 yInit = parseInt( control.params.height, 10 ), 1922 flexWidth = !! parseInt( control.params.flex_width, 10 ), 1923 flexHeight = !! parseInt( control.params.flex_height, 10 ), 1924 realWidth = attachment.get( 'width' ), 1925 realHeight = attachment.get( 'height' ), 1926 ratio = xInit / yInit, 1927 xImg = realWidth, 1928 yImg = realHeight, 1929 imgSelectOptions; 1930 1931 controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); 1932 1933 if ( xImg / yImg > ratio ) { 1934 yInit = yImg; 1935 xInit = yInit * ratio; 1936 } else { 1937 xInit = xImg; 1938 yInit = xInit / ratio; 1939 } 1940 1941 imgSelectOptions = { 1942 handles: true, 1943 keys: true, 1944 instance: true, 1945 persistent: true, 1946 imageWidth: realWidth, 1947 imageHeight: realHeight, 1948 x1: 0, 1949 y1: 0, 1950 x2: xInit, 1951 y2: yInit 1952 }; 1953 1954 if ( flexHeight === false && flexWidth === false ) { 1955 imgSelectOptions.aspectRatio = xInit + ':' + yInit; 1956 } 1957 if ( flexHeight === false ) { 1958 imgSelectOptions.maxHeight = yInit; 1959 } 1960 if ( flexWidth === false ) { 1961 imgSelectOptions.maxWidth = xInit; 1962 } 1963 1964 return imgSelectOptions; 1965 }, 1966 1967 /** 1968 * Return whether the image must be cropped, based on required dimensions. 1969 */ 1970 mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ) { 1971 if ( flexW === true && flexH === true ) { 1972 return false; 1973 } 1974 1975 if ( flexW === true && dstH === imgH ) { 1976 return false; 1977 } 1978 1979 if ( flexH === true && dstW === imgW ) { 1980 return false; 1981 } 1982 1983 if ( dstW === imgW && dstH === imgH ) { 1984 return false; 1985 } 1986 1987 if ( imgW <= dstW ) { 1988 return false; 1989 } 1990 1991 return true; 1992 }, 1993 1994 /** 1995 * If cropping was skipped, apply the image data directly to the setting. 1996 */ 1997 onSkippedCrop: function() { 1998 var attachment = this.frame.state().get( 'selection' ).first().toJSON(); 1999 this.setImageFromAttachment( attachment ); 2000 }, 2001 2002 /** 2003 * Updates the setting and re-renders the control UI. 2004 * 2005 * @param {object} attachment 2006 */ 2007 setImageFromAttachment: function( attachment ) { 2008 this.params.attachment = attachment; 2009 2010 // Set the Customizer setting; the callback takes care of rendering. 2011 this.setting( attachment.id ); 2012 } 2013 }); 2014 2015 /** 2016 * A control for selecting and cropping Site Icons. 2017 * 2018 * @class 2019 * @augments wp.customize.CroppedImageControl 2020 * @augments wp.customize.MediaControl 2021 * @augments wp.customize.Control 2022 * @augments wp.customize.Class 2023 */ 2024 api.SiteIconControl = api.CroppedImageControl.extend({ 2025 /** 2026 * Updates the setting and re-renders the control UI. 2027 * 2028 * @param {object} attachment 2029 */ 2030 setImageFromAttachment: function( attachment ) { 2031 var icon = typeof attachment.sizes['site_icon-32'] !== 'undefined' ? attachment.sizes['site_icon-32'] : attachment.sizes.thumbnail; 2032 2033 this.params.attachment = attachment; 2034 2035 // Set the Customizer setting; the callback takes care of rendering. 2036 this.setting( attachment.id ); 2037 2038 2039 // Update the icon in-browser. 2040 $( 'link[rel="icon"]' ).attr( 'href', icon.url ); 2041 }, 2042 2043 /** 2044 * Called when the "Remove" link is clicked. Empties the setting. 2045 * 2046 * @param {object} event jQuery Event object 2047 */ 2048 removeFile: function( event ) { 2049 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 2050 return; 2051 } 2052 event.preventDefault(); 2053 2054 this.params.attachment = {}; 2055 this.setting( '' ); 2056 this.renderContent(); // Not bound to setting change when emptying. 2057 $( 'link[rel="icon"]' ).attr( 'href', '' ); 2058 } 2059 }); 2060 2061 /** 1839 2062 * @class 1840 2063 * @augments wp.customize.Control 1841 2064 * @augments wp.customize.Class … … 2695 2918 }); 2696 2919 2697 2920 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 2921 color: api.ColorControl, 2922 media: api.MediaControl, 2923 upload: api.UploadControl, 2924 image: api.ImageControl, 2925 cropped_image: api.CroppedImageControl, 2926 site_icon: api.SiteIconControl, 2927 header: api.HeaderControl, 2928 background: api.BackgroundControl, 2929 theme: api.ThemeControl 2705 2930 }; 2706 2931 api.panelConstructor = {}; 2707 2932 api.sectionConstructor = { -
src/wp-admin/options-general.php
163 163 <a class="button hide-if-js" href="<?php echo esc_url( $upload_url ); ?>"><?php _e( 'Add a Site Icon' ); ?></a> 164 164 165 165 <?php endif; ?> 166 <p class="description"><?php _e( ' Site Icon creates a favicon and app iconsfor 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> 169 169 <?php if ( !is_multisite() ) { ?> -
src/wp-includes/class-wp-customize-control.php
1001 1001 } 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 * @access public 1014 * @var string 1015 */ 1016 public $type = 'cropped_image'; 1017 1018 /** 1019 * @access public 1020 * @var int 1021 */ 1022 public $width = 150; 1023 1024 /** 1025 * @access public 1026 * @var int 1027 */ 1028 public $height = 150; 1029 1030 /** 1031 * @access public 1032 * @var bool 1033 */ 1034 public $flex_width = false; 1035 1036 /** 1037 * @access public 1038 * @var bool 1039 */ 1040 public $flex_height = false; 1041 1042 /** 1043 * Enqueue control related scripts/styles. 1044 * 1045 * @access public 1046 */ 1047 public function enqueue() { 1048 wp_enqueue_script( 'customize-views' ); 1049 1050 parent::enqueue(); 1051 } 1052 1053 /** 1054 * Refresh the parameters passed to the JavaScript via JSON. 1055 * 1056 * @since 4.3.0 1057 * @access public 1058 * @uses WP_Customize_Image_Control::to_json() 1059 * 1060 * @see WP_Customize_Control::to_json() 1061 */ 1062 public function to_json() { 1063 parent::to_json(); 1064 1065 $this->json['width'] = absint( $this->width ); 1066 $this->json['height'] = absint( $this->height ); 1067 $this->json['flex_width'] = absint( $this->flex_width ); 1068 $this->json['flex_height'] = absint( $this->flex_height ); 1069 } 1070 1071 } 1072 1073 /** 1074 * Customize Site Icon control class. 1075 * 1076 * Used only for custom functionality in JavaScript. 1077 * 1078 * @since 4.3.0 1079 * 1080 * @see WP_Customize_Cropped_Image_Control 1081 */ 1082 class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control { 1083 1084 /** 1085 * @access public 1086 * @var string 1087 */ 1088 public $type = 'site_icon'; 1089 1090 /** 1091 * Constructor. 1092 * 1093 * @since 4.3.0 1094 * 1095 * @param WP_Customize_Manager $manager 1096 * @param string $id 1097 * @param array $args 1098 */ 1099 public function __construct( $manager, $id, $args = array() ) { 1100 parent::__construct( $manager, $id, $args ); 1101 add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 ); 1102 } 1103 } 1104 1105 /** 1004 1106 * Customize Header Image Control class. 1005 1107 * 1006 1108 * @since 3.4.0 -
src/wp-includes/class-wp-customize-manager.php
1278 1278 $this->register_control_type( 'WP_Customize_Upload_Control' ); 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 1283 1285 /* Themes */ … … 1324 1326 ) ) ); 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 ) ); 1333 1335 … … 1353 1355 'section' => 'title_tagline', 1354 1356 ) ); 1355 1357 1358 $icon = wp_get_attachment_image_src( absint( get_option( 'site_icon' ) ), 'medium' ); 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 ) ) ); 1374 1356 1375 /* Colors */ 1357 1376 1358 1377 $this->add_section( 'colors', array( … … 1375 1394 'label' => __( 'Display Header Text' ), 1376 1395 'section' => 'title_tagline', 1377 1396 'type' => 'checkbox', 1397 'priority' => 40, 1378 1398 ) ); 1379 1399 1380 1400 $this->add_control( new WP_Customize_Color_Control( $this, 'header_textcolor', array( -
src/wp-includes/general-template.php
2445 2445 * @link http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon. 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 } 2451 2451 -
src/wp-includes/js/customize-views.js
3 3 if ( ! wp || ! wp.customize ) { return; } 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.params.type, 22 cropDetails: cropDetails 23 } ); 24 } 25 } ); 6 26 7 27 /** 8 28 * wp.customize.HeaderTool.CurrentView