wp/wp-admin/js/site-icon.js
changeset 21 48c4eec2b7e6
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
       
     1 /**
       
     2  * Handle the site icon setting in options-general.php.
       
     3  *
       
     4  * @since 6.5.0
       
     5  * @output wp-admin/js/site-icon.js
       
     6  */
       
     7 
       
     8 /* global jQuery, wp */
       
     9 
       
    10 ( function ( $ ) {
       
    11 	var $chooseButton = $( '#choose-from-library-button' ),
       
    12 		$iconPreview = $( '#site-icon-preview' ),
       
    13 		$browserIconPreview = $( '#browser-icon-preview' ),
       
    14 		$appIconPreview = $( '#app-icon-preview' ),
       
    15 		$hiddenDataField = $( '#site_icon_hidden_field' ),
       
    16 		$removeButton = $( '#js-remove-site-icon' ),
       
    17 		frame;
       
    18 
       
    19 	/**
       
    20 	 * Calculate image selection options based on the attachment dimensions.
       
    21 	 *
       
    22 	 * @since 6.5.0
       
    23 	 *
       
    24 	 * @param {Object} attachment The attachment object representing the image.
       
    25 	 * @return {Object} The image selection options.
       
    26 	 */
       
    27 	function calculateImageSelectOptions( attachment ) {
       
    28 		var realWidth = attachment.get( 'width' ),
       
    29 			realHeight = attachment.get( 'height' ),
       
    30 			xInit = 512,
       
    31 			yInit = 512,
       
    32 			ratio = xInit / yInit,
       
    33 			xImg = xInit,
       
    34 			yImg = yInit,
       
    35 			x1,
       
    36 			y1,
       
    37 			imgSelectOptions;
       
    38 
       
    39 		if ( realWidth / realHeight > ratio ) {
       
    40 			yInit = realHeight;
       
    41 			xInit = yInit * ratio;
       
    42 		} else {
       
    43 			xInit = realWidth;
       
    44 			yInit = xInit / ratio;
       
    45 		}
       
    46 
       
    47 		x1 = ( realWidth - xInit ) / 2;
       
    48 		y1 = ( realHeight - yInit ) / 2;
       
    49 
       
    50 		imgSelectOptions = {
       
    51 			aspectRatio: xInit + ':' + yInit,
       
    52 			handles: true,
       
    53 			keys: true,
       
    54 			instance: true,
       
    55 			persistent: true,
       
    56 			imageWidth: realWidth,
       
    57 			imageHeight: realHeight,
       
    58 			minWidth: xImg > xInit ? xInit : xImg,
       
    59 			minHeight: yImg > yInit ? yInit : yImg,
       
    60 			x1: x1,
       
    61 			y1: y1,
       
    62 			x2: xInit + x1,
       
    63 			y2: yInit + y1,
       
    64 		};
       
    65 
       
    66 		return imgSelectOptions;
       
    67 	}
       
    68 
       
    69 	/**
       
    70 	 * Initializes the media frame for selecting or cropping an image.
       
    71 	 *
       
    72 	 * @since 6.5.0
       
    73 	 */
       
    74 	$chooseButton.on( 'click', function () {
       
    75 		var $el = $( this );
       
    76 
       
    77 		// Create the media frame.
       
    78 		frame = wp.media( {
       
    79 			button: {
       
    80 				// Set the text of the button.
       
    81 				text: $el.data( 'update' ),
       
    82 
       
    83 				// Don't close, we might need to crop.
       
    84 				close: false,
       
    85 			},
       
    86 			states: [
       
    87 				new wp.media.controller.Library( {
       
    88 					title: $el.data( 'choose-text' ),
       
    89 					library: wp.media.query( { type: 'image' } ),
       
    90 					date: false,
       
    91 					suggestedWidth: $el.data( 'size' ),
       
    92 					suggestedHeight: $el.data( 'size' ),
       
    93 				} ),
       
    94 				new wp.media.controller.SiteIconCropper( {
       
    95 					control: {
       
    96 						params: {
       
    97 							width: $el.data( 'size' ),
       
    98 							height: $el.data( 'size' ),
       
    99 						},
       
   100 					},
       
   101 					imgSelectOptions: calculateImageSelectOptions,
       
   102 				} ),
       
   103 			],
       
   104 		} );
       
   105 
       
   106 		frame.on( 'cropped', function ( attachment ) {
       
   107 			$hiddenDataField.val( attachment.id );
       
   108 			switchToUpdate( attachment );
       
   109 			frame.close();
       
   110 
       
   111 			// Start over with a frame that is so fresh and so clean clean.
       
   112 			frame = null;
       
   113 		} );
       
   114 
       
   115 		// When an image is selected, run a callback.
       
   116 		frame.on( 'select', function () {
       
   117 			// Grab the selected attachment.
       
   118 			var attachment = frame.state().get( 'selection' ).first();
       
   119 
       
   120 			if (
       
   121 				attachment.attributes.height === $el.data( 'size' ) &&
       
   122 				$el.data( 'size' ) === attachment.attributes.width
       
   123 			) {
       
   124 				switchToUpdate( attachment.attributes );
       
   125 				frame.close();
       
   126 
       
   127 				// Set the value of the hidden input to the attachment id.
       
   128 				$hiddenDataField.val( attachment.id );
       
   129 			} else {
       
   130 				frame.setState( 'cropper' );
       
   131 			}
       
   132 		} );
       
   133 
       
   134 		frame.open();
       
   135 	} );
       
   136 
       
   137 	/**
       
   138 	 * Update the UI when a site icon is selected.
       
   139 	 *
       
   140 	 * @since 6.5.0
       
   141 	 *
       
   142 	 * @param {array} attributes The attributes for the attachment.
       
   143 	 */
       
   144 	function switchToUpdate( attributes ) {
       
   145 		var i18nAppAlternativeString, i18nBrowserAlternativeString;
       
   146 
       
   147 		if ( attributes.alt ) {
       
   148 			i18nAppAlternativeString = wp.i18n.sprintf(
       
   149 				/* translators: %s: The selected image alt text. */
       
   150 				wp.i18n.__( 'App icon preview: Current image: %s' ),
       
   151 				attributes.alt
       
   152 			);
       
   153 			i18nBrowserAlternativeString = wp.i18n.sprintf(
       
   154 				/* translators: %s: The selected image alt text. */
       
   155 				wp.i18n.__( 'Browser icon preview: Current image: %s' ),
       
   156 				attributes.alt
       
   157 			);
       
   158 		} else {
       
   159 			i18nAppAlternativeString = wp.i18n.sprintf(
       
   160 				/* translators: %s: The selected image filename. */
       
   161 				wp.i18n.__(
       
   162 					'App icon preview: The current image has no alternative text. The file name is: %s'
       
   163 				),
       
   164 				attributes.filename
       
   165 			);
       
   166 			i18nBrowserAlternativeString = wp.i18n.sprintf(
       
   167 				/* translators: %s: The selected image filename. */
       
   168 				wp.i18n.__(
       
   169 					'Browser icon preview: The current image has no alternative text. The file name is: %s'
       
   170 				),
       
   171 				attributes.filename
       
   172 			);
       
   173 		}
       
   174 
       
   175 		// Set site-icon-img src and alternative text to app icon preview.
       
   176 		$appIconPreview.attr( {
       
   177 			src: attributes.url,
       
   178 			alt: i18nAppAlternativeString,
       
   179 		} );
       
   180 
       
   181 		// Set site-icon-img src and alternative text to browser preview.
       
   182 		$browserIconPreview.attr( {
       
   183 			src: attributes.url,
       
   184 			alt: i18nBrowserAlternativeString,
       
   185 		} );
       
   186 
       
   187 		// Remove hidden class from icon preview div and remove button.
       
   188 		$iconPreview.removeClass( 'hidden' );
       
   189 		$removeButton.removeClass( 'hidden' );
       
   190 
       
   191 		// If the choose button is not in the update state, swap the classes.
       
   192 		if ( $chooseButton.attr( 'data-state' ) !== '1' ) {
       
   193 			$chooseButton.attr( {
       
   194 				class: $chooseButton.attr( 'data-alt-classes' ),
       
   195 				'data-alt-classes': $chooseButton.attr( 'class' ),
       
   196 				'data-state': '1',
       
   197 			} );
       
   198 		}
       
   199 
       
   200 		// Swap the text of the choose button.
       
   201 		$chooseButton.text( $chooseButton.attr( 'data-update-text' ) );
       
   202 	}
       
   203 
       
   204 	/**
       
   205 	 * Handles the click event of the remove button.
       
   206 	 *
       
   207 	 * @since 6.5.0
       
   208 	 */
       
   209 	$removeButton.on( 'click', function () {
       
   210 		$hiddenDataField.val( 'false' );
       
   211 		$( this ).toggleClass( 'hidden' );
       
   212 		$iconPreview.toggleClass( 'hidden' );
       
   213 		$browserIconPreview.attr( {
       
   214 			src: '',
       
   215 			alt: '',
       
   216 		} );
       
   217 		$appIconPreview.attr( {
       
   218 			src: '',
       
   219 			alt: '',
       
   220 		} );
       
   221 
       
   222 		/**
       
   223 		 * Resets state to the button, for correct visual style and state.
       
   224 		 * Updates the text of the button.
       
   225 		 * Sets focus state to the button.
       
   226 		 */
       
   227 		$chooseButton
       
   228 			.attr( {
       
   229 				class: $chooseButton.attr( 'data-alt-classes' ),
       
   230 				'data-alt-classes': $chooseButton.attr( 'class' ),
       
   231 				'data-state': '',
       
   232 			} )
       
   233 			.text( $chooseButton.attr( 'data-choose-text' ) )
       
   234 			.trigger( 'focus' );
       
   235 	} );
       
   236 } )( jQuery );