|
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 ); |