WordPress.org

Make WordPress Core

Ticket #16434: 16434.23.diff

File 16434.23.diff, 41.5 KB (added by obenland, 3 years ago)
  • src/wp-admin/admin-ajax.php

     
    6262        'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
    6363        'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail',
    6464        'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post',
    65         'press-this-add-category', 'crop-image',
     65        'press-this-add-category', 'crop-image', 'set-site-icon',
    6666);
    6767
    6868// Deprecated
  • src/wp-admin/css/site-icon.css

     
    22  28.0 - Site Icon
    33------------------------------------------------------------------------------*/
    44
     5#site-icon[src=""],
     6#site-icon[src=""] ~ p .remove-site-icon {
     7        display: none;
     8}
     9
    510.site-icon-image {
    611        float: left;
    712        margin: 0 20px 0 0;
  • src/wp-admin/includes/ajax-actions.php

     
    30883088                        $attachment_id = $wp_site_icon->insert_attachment( $object, $cropped );
    30893089                        remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
    30903090
    3091                         // Additional sizes in wp_prepare_attachment_for_js().
    3092                         add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
     3091                        if ( isset( $_POST['customize'] ) && 'on' == $_POST['customize'] ) {
     3092                                // Additional sizes in wp_prepare_attachment_for_js().
     3093                                add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
     3094                        } else {
     3095                                update_option( 'site_icon', $attachment_id );
     3096                        }
    30933097                        break;
    30943098
    30953099                default:
     
    31523156
    31533157        wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) );
    31543158}
     3159
     3160
     3161/**
     3162 * AJAX handler for saving a Site Icon.
     3163 *
     3164 * @since 4.3.0
     3165 */
     3166function wp_ajax_set_site_icon() {
     3167        $attachment_id = absint( $_POST['id'] );
     3168
     3169        check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' );
     3170        if ( ! current_user_can( 'manage_options' ) ) {
     3171                wp_send_json_error();
     3172        }
     3173
     3174        if ( update_option( 'site_icon', $attachment_id ) ) {
     3175                wp_send_json_success();
     3176        } else {
     3177                wp_send_json_error();
     3178        }
     3179}
  • src/wp-admin/js/customize-controls.js

     
    20382038         * @augments wp.customize.Class
    20392039         */
    20402040        api.SiteIconControl = api.CroppedImageControl.extend({
     2041
     2042                /**
     2043                 * Create a media modal select frame, and store it so the instance can be reused when needed.
     2044                 */
     2045                initFrame: function() {
     2046                        var l10n = _wpMediaViewsL10n;
     2047
     2048                        this.frame = wp.media({
     2049                                button: {
     2050                                        text: l10n.select,
     2051                                        close: false
     2052                                },
     2053                                states: [
     2054                                        new wp.media.controller.Library({
     2055                                                title: this.params.button_labels.frame_title,
     2056                                                library: wp.media.query({ type: 'image' }),
     2057                                                multiple: false,
     2058                                                date: false,
     2059                                                priority: 20,
     2060                                                suggestedWidth: this.params.width,
     2061                                                suggestedHeight: this.params.height
     2062                                        }),
     2063                                        new wp.media.controller.SiteIconCropper({
     2064                                                imgSelectOptions: this.calculateImageSelectOptions,
     2065                                                control: this
     2066                                        })
     2067                                ]
     2068                        });
     2069
     2070                        this.frame.on( 'select', this.onSelect, this );
     2071                        this.frame.on( 'cropped', this.onCropped, this );
     2072                        this.frame.on( 'skippedcrop', this.onSkippedCrop, this );
     2073                },
     2074
    20412075                /**
    20422076                 * Updates the setting and re-renders the control UI.
    20432077                 *
  • src/wp-admin/js/site-icon.js

     
    11(function($) {
    2         var frame;
     2        var frame, siteIcon;
    33
    44        $( function() {
    55                // Build the choose from library frame.
     
    77                        var $el = $(this);
    88                        event.preventDefault();
    99
    10                         // If the media frame already exists, reopen it.
    11                         if ( frame ) {
    12                                 frame.open();
    13                                 return;
    14                         }
    15 
    1610                        // Create the media frame.
    1711                        frame = wp.media({
    1812                                // Customize the submit button.
    1913                                button: {
    2014                                        // Set the text of the button.
    21                                         text: $el.data('update'),
    22                                         // Tell the button not to close the modal, since we're
    23                                         // going to refresh the page when the image is selected.
     15                                        text: $el.data( 'update' ),
     16
     17                                        // Don't close the modal, we're going to refresh the page when the image is selected.
    2418                                        close: false
    2519                                },
    2620                                states: [
     21                                        new wp.media.controller.SiteIconCropper({
     22                                                imgSelectOptions: siteIcon.calculateImageSelectOptions
     23                                        }),
    2724                                        new wp.media.controller.Library({
    2825                                                title: $el.data( 'choose' ),
    2926                                                library: wp.media.query({ type: 'image' }),
     
    3532                        });
    3633
    3734                        // When an image is selected, run a callback.
    38                         frame.on( 'select', function() {
    39                                 // Grab the selected attachment.
    40                                 var attachment = frame.state().get('selection').first(),
    41                                         link = $el.data('updateLink');
     35                        frame.on( 'select', siteIcon.imageSelected );
    4236
    43                                 // Tell the browser to navigate to the crop step.
    44                                 window.location = link + '&file=' + attachment.id;
    45                         });
     37                        // After the image has been cropped, apply the cropped image data to the setting.
     38                        frame.on( 'cropped', siteIcon.setImageFromAttachment );
    4639
    4740                        frame.open();
    4841                });
    4942        });
     43
     44        siteIcon = {
     45
     46                imageSelected: function() {
     47                        var attachment = frame.state().get( 'selection' ).first().toJSON(),
     48                                min_size   = $( '#choose-from-library-link' ).data( 'size' );
     49
     50                        if ( min_size === attachment.width && min_size === attachment.height ) {
     51                                siteIcon.setImageFromAttachment( attachment );
     52                                siteIcon.setSiteIcon( attachment );
     53                        } else {
     54                                frame.setState( 'cropper' );
     55                        }
     56                },
     57
     58                setImageFromAttachment: function( attachment ) {
     59                        $( '#site-icon').attr( 'src', attachment.sizes.thumbnail.url );
     60
     61                        if ( frame ) {
     62                                frame.close();
     63                        }
     64                },
     65
     66                setSiteIcon: function( attachment ) {
     67                        return wp.ajax.post( 'set-site-icon', {
     68                                nonce: attachment.nonces.edit,
     69                                id: attachment.id
     70                        } );
     71                },
     72
     73                /**
     74                 * Returns a set of options, computed from the attached image data and
     75                 * control-specific data, to be fed to the imgAreaSelect plugin in
     76                 * wp.media.view.Cropper.
     77                 *
     78                 * @param {wp.media.model.Attachment} attachment
     79                 * @param {wp.media.controller.Cropper} controller
     80                 * @returns {Object} Options
     81                 */
     82                calculateImageSelectOptions: function( attachment, controller ) {
     83                        var $el        = $( '#choose-from-library-link' ),
     84                                realWidth  = attachment.get( 'width' ),
     85                                realHeight = attachment.get( 'height' ),
     86                                xInit = parseInt( $el.data( 'size' ), 10),
     87                                yInit = parseInt( $el.data( 'size' ), 10),
     88                                ratio = xInit / yInit;
     89
     90                        controller.set( 'canSkipCrop', ( xInit === realWidth && yInit === realHeight ) || ( realWidth < xInit ) );
     91
     92                        if (realWidth / realHeight > ratio) {
     93                                yInit = realHeight;
     94                                xInit = yInit * ratio;
     95                        } else {
     96                                xInit = realWidth;
     97                                yInit = xInit / ratio;
     98                        }
     99
     100                        return {
     101                                handles: true,
     102                                keys: true,
     103                                instance: true,
     104                                persistent: true,
     105                                imageWidth: realWidth,
     106                                imageHeight: realHeight,
     107                                aspectRatio: xInit + ':' + yInit,
     108                                maxHeight: yInit,
     109                                maxWidth: xInit,
     110                                x1: 0,
     111                                y1: 0,
     112                                x2: xInit,
     113                                y2: yInit
     114                        };
     115                }
     116        };
    50117}(jQuery));
  • src/wp-admin/options-general.php

     
    128128<th scope="row"><?php _e( 'Site Icon' ); ?></th>
    129129<td>
    130130        <?php
    131         $upload_url = admin_url( 'options-general.php?page=site-icon' );
    132         $update_url = esc_url( add_query_arg( array(
    133                 'page'   => 'site-icon',
    134                 'action' => 'crop_site_icon',
    135         ), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) );
    136 
    137         wp_enqueue_media();
    138         wp_enqueue_script( 'site-icon' );
    139 
    140         if ( has_site_icon() ) :
     131                $upload_url = admin_url( 'options-general.php?page=site-icon' );
    141132                $remove_url = add_query_arg( array(
    142133                        'action' => 'remove_site_icon',
    143134                ), wp_nonce_url( admin_url( 'options-general.php' ), 'remove-site-icon' ) );
     135
     136                wp_enqueue_media();
     137                wp_enqueue_script( 'site-icon' );
    144138        ?>
    145139
    146         <img class="avatar avatar-150" src="<?php site_icon_url( null, 150 ); ?>" height="150" width="150" alt="" />
     140        <img id="site-icon" class="avatar avatar-150" src="<?php site_icon_url( null, 150 ); ?>" height="150" width="150" alt="" />
    147141        <p class="hide-if-no-js">
    148                 <button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( $GLOBALS['wp_site_icon']->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"><?php _e( 'Update Site Icon' ); ?></button>
    149                 <a href="<?php echo esc_url( $remove_url ); ?>"><?php _e( 'Remove Site Icon' ); ?></a>
     142                <button type="button" id="choose-from-library-link" class="button" data-size="512" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>" aria-label="<?php esc_attr_e( 'Choose an image from your media library' ); ?>" aria-describedby="site-icon-description"><?php _e( 'Choose Image' ); ?></button>
     143                <a class="remove-site-icon" href="<?php echo esc_url( $remove_url ); ?>"><?php _e( 'Remove Site Icon' ); ?></a>
    150144        </p>
    151145        <p class="hide-if-js">
    152                 <a href="<?php echo esc_url( $upload_url ); ?>" class="button"><?php _e( 'Update Site Icon' ); ?></a>
    153                 <a href="<?php echo esc_url( $remove_url ); ?>"><?php _e( 'Remove Site Icon' ); ?></a>
    154         </p>
    155 
    156         <?php else : ?>
    157 
    158         <p class="hide-if-no-js">
    159                 <button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( $GLOBALS['wp_site_icon']->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>" aria-label="<?php esc_attr_e( 'Choose an image from your media library' ); ?>" aria-describedby="site-icon-description"><?php _e( 'Choose Image' ); ?></button>
     146                <a class="button" href="<?php echo esc_url( $upload_url ); ?>"><?php _e( 'Choose Image' ); ?></a>
     147                <a class="remove-site-icon" href="<?php echo esc_url( $remove_url ); ?>"><?php _e( 'Remove Site Icon' ); ?></a>
    160148        </p>
    161         <a class="button hide-if-js" href="<?php echo esc_url( $upload_url ); ?>"><?php _e( 'Add a Site Icon' ); ?></a>
    162 
    163         <?php endif; ?>
    164149        <p id="site-icon-description" class="description"><?php _e( 'The Site Icon is used as a browser and app icon for your site.' ); ?></p>
    165150</td>
    166151</tr>
  • src/wp-includes/css/media-views.css

     
    696696        height: 100%;
    697697}
    698698
     699.media-frame-content .crop-content.site-icon {
     700        margin-right: 300px;
     701}
     702
    699703.media-frame-content .crop-content .crop-image {
    700704        display: block;
    701705        margin: auto;
  • src/wp-includes/js/media/controllers/customize-image-cropper.js

     
     1/*globals wp */
     2
     3/**
     4 * wp.media.controller.Cropper
     5 *
     6 * A state for cropping an image.
     7 *
     8 * @class
     9 * @augments wp.media.controller.State
     10 * @augments Backbone.Model
     11 */
     12var CustomizeImageCropper;
     13
     14CustomizeImageCropper = wp.media.controller.Cropper.extend({
     15        doCrop: function( attachment ) {
     16                var cropDetails = attachment.get( 'cropDetails' ),
     17                        control = this.get( 'control' );
     18
     19                cropDetails.dst_width  = control.params.width;
     20                cropDetails.dst_height = control.params.height;
     21
     22                return wp.ajax.post( 'crop-image', {
     23                        wp_customize: 'on',
     24                        nonce: attachment.get( 'nonces' ).edit,
     25                        id: attachment.get( 'id' ),
     26                        context: control.id,
     27                        cropDetails: cropDetails
     28                } );
     29        }
     30});
     31
     32module.exports = CustomizeImageCropper;
  • src/wp-includes/js/media/controllers/site-icon-cropper.js

     
     1/*globals wp, Backbone, jQuery */
     2
     3/**
     4 * wp.media.controller.Cropper
     5 *
     6 * A state for cropping an image.
     7 *
     8 * @class
     9 * @augments wp.media.controller.State
     10 * @augments Backbone.Model
     11 */
     12var $ = jQuery,
     13        SiteIconCropper;
     14
     15SiteIconCropper = wp.media.controller.Cropper.extend({
     16        activate: function() {
     17                this.frame.on( 'content:create:crop', this.createCropContent, this );
     18                this.frame.on( 'close', this.removeCropper, this );
     19                this.set('selection', new Backbone.Collection(this.frame._selection.single));
     20        },
     21
     22        createCropContent: function() {
     23                this.cropperView = new wp.media.view.SiteIconCropper({
     24                        controller: this,
     25                        attachment: this.get('selection').first()
     26                });
     27                this.cropperView.on('image-loaded', this.createCropToolbar, this);
     28                this.frame.content.set(this.cropperView);
     29
     30        },
     31
     32        doCrop: function( attachment ) {
     33                var cropDetails = attachment.get( 'cropDetails' ),
     34                        $el = $( '#choose-from-library-link' );
     35
     36                cropDetails.dst_width  = $el.data( 'size' );
     37                cropDetails.dst_height = $el.data( 'size' );
     38
     39                return wp.ajax.post( 'crop-image', {
     40                        nonce: attachment.get( 'nonces' ).edit,
     41                        id: attachment.get( 'id' ),
     42                        context: 'site-icon',
     43                        cropDetails: cropDetails
     44                } );
     45        }
     46});
     47
     48module.exports = SiteIconCropper;
  • src/wp-includes/js/media/views/site-icon-cropper.js

     
     1/*globals wp, _ */
     2
     3/**
     4 * wp.media.view.Cropper
     5 *
     6 * Uses the imgAreaSelect plugin to allow a user to crop an image.
     7 *
     8 * Takes imgAreaSelect options from
     9 * wp.customize.HeaderControl.calculateImageSelectOptions via
     10 * wp.customize.HeaderControl.openMM.
     11 *
     12 * @class
     13 * @augments wp.media.View
     14 * @augments wp.Backbone.View
     15 * @augments Backbone.View
     16 */
     17var View = wp.media.view,
     18        SiteIconCropper;
     19
     20SiteIconCropper = View.Cropper.extend({
     21        className: 'crop-content site-icon',
     22
     23        onImageLoad: function() {
     24                var imgOptions = this.controller.get('imgSelectOptions');
     25                if (typeof imgOptions === 'function') {
     26                        imgOptions = imgOptions(this.options.attachment, this.controller);
     27                }
     28
     29                imgOptions = _.extend(imgOptions, {parent: this.$el});
     30                this.trigger('image-loaded');
     31                this.controller.imgSelect = this.$image.imgAreaSelect(imgOptions);
     32
     33                this.sidebar = new wp.media.view.Sidebar({
     34                        controller: this.controller
     35                });
     36                this.sidebar.set( 'preview', new wp.media.view.SiteIconPreview({
     37                        controller: this.controller,
     38                        attachment: this.options.attachment
     39                }) );
     40
     41                this.controller.cropperView.views.add( this.sidebar );
     42        }
     43});
     44
     45module.exports = SiteIconCropper;
  • src/wp-includes/js/media/views/site-icon-preview.js

     
     1/*globals wp, jQuery */
     2
     3/**
     4 * wp.media.view.Cropper
     5 *
     6 * Uses the imgAreaSelect plugin to allow a user to crop an image.
     7 *
     8 * Takes imgAreaSelect options from
     9 * wp.customize.HeaderControl.calculateImageSelectOptions via
     10 * wp.customize.HeaderControl.openMM.
     11 *
     12 * @class
     13 * @augments wp.media.View
     14 * @augments wp.Backbone.View
     15 * @augments Backbone.View
     16 */
     17var View = wp.media.View,
     18        $ = jQuery,
     19        SiteIconPreview;
     20
     21SiteIconPreview = View.extend({
     22        className: 'site-icon-preview',
     23        template: wp.template( 'site-icon-preview' ),
     24
     25        ready: function() {
     26                this.controller.imgSelect.setOptions({
     27                        onInit: this.updatePreview,
     28                        onSelectChange: this.updatePreview
     29                });
     30        },
     31
     32        prepare: function() {
     33                return {
     34                        url: this.options.attachment.get('url')
     35                };
     36        },
     37
     38        updatePreview: function(img, coords) {
     39                var rx = 64 / coords.width,
     40                        ry = 64 / coords.height,
     41                        preview_rx = 16 / coords.width,
     42                        preview_ry = 16 / coords.height;
     43
     44                $( '#preview-homeicon' ).css({
     45                        width: Math.round(rx * this.imageWidth ) + 'px',
     46                        height: Math.round(ry * this.imageHeight ) + 'px',
     47                        marginLeft: '-' + Math.round(rx * coords.x1) + 'px',
     48                        marginTop: '-' + Math.round(ry * coords.y1) + 'px'
     49                });
     50
     51                $( '#preview-favicon' ).css({
     52                        width: Math.round( preview_rx * this.imageWidth ) + 'px',
     53                        height: Math.round( preview_ry * this.imageHeight ) + 'px',
     54                        marginLeft: '-' + Math.round( preview_rx * coords.x1 ) + 'px',
     55                        marginTop: '-' + Math.floor( preview_ry* coords.y1 ) + 'px'
     56                });
     57        }
     58});
     59
     60module.exports = SiteIconPreview;
  • src/wp-includes/js/media/views.manifest.js

     
    9090media.controller.MediaLibrary = require( './controllers/media-library.js' );
    9191media.controller.Embed = require( './controllers/embed.js' );
    9292media.controller.Cropper = require( './controllers/cropper.js' );
     93media.controller.CustomizeImageCropper = require( './controllers/customize-image-cropper.js' );
     94media.controller.SiteIconCropper = require( './controllers/site-icon-cropper.js' );
    9395
    9496media.View = require( './views/view.js' );
    9597media.view.Frame = require( './views/frame.js' );
     
    143145media.view.EmbedImage = require( './views/embed/image.js' );
    144146media.view.ImageDetails = require( './views/image-details.js' );
    145147media.view.Cropper = require( './views/cropper.js' );
     148media.view.SiteIconCropper = require( './views/site-icon-cropper.js' );
     149media.view.SiteIconPreview = require( './views/site-icon-preview.js' );
    146150media.view.EditImage = require( './views/edit-image.js' );
    147151media.view.Spinner = require( './views/spinner.js' );
  • src/wp-includes/js/media-views.js

     
    387387/*globals wp */
    388388
    389389/**
     390 * wp.media.controller.Cropper
     391 *
     392 * A state for cropping an image.
     393 *
     394 * @class
     395 * @augments wp.media.controller.State
     396 * @augments Backbone.Model
     397 */
     398var CustomizeImageCropper;
     399
     400CustomizeImageCropper = wp.media.controller.Cropper.extend({
     401        doCrop: function( attachment ) {
     402                var cropDetails = attachment.get( 'cropDetails' ),
     403                        control = this.get( 'control' );
     404
     405                cropDetails.dst_width  = control.params.width;
     406                cropDetails.dst_height = control.params.height;
     407
     408                return wp.ajax.post( 'crop-image', {
     409                        wp_customize: 'on',
     410                        nonce: attachment.get( 'nonces' ).edit,
     411                        id: attachment.get( 'id' ),
     412                        context: control.id,
     413                        cropDetails: cropDetails
     414                } );
     415        }
     416});
     417
     418module.exports = CustomizeImageCropper;
     419
     420},{}],5:[function(require,module,exports){
     421/*globals wp */
     422
     423/**
    390424 * wp.media.controller.EditImage
    391425 *
    392426 * A state for editing (cropping, etc.) an image.
     
    461495
    462496module.exports = EditImage;
    463497
    464 },{}],5:[function(require,module,exports){
     498},{}],6:[function(require,module,exports){
    465499/*globals wp, _, Backbone */
    466500
    467501/**
     
    599633
    600634module.exports = Embed;
    601635
    602 },{}],6:[function(require,module,exports){
     636},{}],7:[function(require,module,exports){
    603637/*globals wp, _ */
    604638
    605639/**
     
    723757
    724758module.exports = FeaturedImage;
    725759
    726 },{}],7:[function(require,module,exports){
     760},{}],8:[function(require,module,exports){
    727761/*globals wp, _ */
    728762
    729763/**
     
    816850
    817851module.exports = GalleryAdd;
    818852
    819 },{}],8:[function(require,module,exports){
     853},{}],9:[function(require,module,exports){
    820854/*globals wp */
    821855
    822856/**
     
    960994
    961995module.exports = GalleryEdit;
    962996
    963 },{}],9:[function(require,module,exports){
     997},{}],10:[function(require,module,exports){
    964998/*globals wp, _ */
    965999
    9661000/**
     
    10241058
    10251059module.exports = ImageDetails;
    10261060
    1027 },{}],10:[function(require,module,exports){
     1061},{}],11:[function(require,module,exports){
    10281062/*globals wp, _, Backbone */
    10291063
    10301064/**
     
    12981332
    12991333module.exports = Library;
    13001334
    1301 },{}],11:[function(require,module,exports){
     1335},{}],12:[function(require,module,exports){
    13021336/*globals wp, _ */
    13031337
    13041338/**
     
    13501384
    13511385module.exports = MediaLibrary;
    13521386
    1353 },{}],12:[function(require,module,exports){
     1387},{}],13:[function(require,module,exports){
    13541388/*globals Backbone, _ */
    13551389
    13561390/**
     
    15311565
    15321566module.exports = Region;
    15331567
    1534 },{}],13:[function(require,module,exports){
     1568},{}],14:[function(require,module,exports){
    15351569/*globals wp, _ */
    15361570
    15371571/**
     
    16411675
    16421676module.exports = ReplaceImage;
    16431677
    1644 },{}],14:[function(require,module,exports){
     1678},{}],15:[function(require,module,exports){
     1679/*globals wp, Backbone, jQuery */
     1680
     1681/**
     1682 * wp.media.controller.Cropper
     1683 *
     1684 * A state for cropping an image.
     1685 *
     1686 * @class
     1687 * @augments wp.media.controller.State
     1688 * @augments Backbone.Model
     1689 */
     1690var $ = jQuery,
     1691        SiteIconCropper;
     1692
     1693SiteIconCropper = wp.media.controller.Cropper.extend({
     1694        activate: function() {
     1695                this.frame.on( 'content:create:crop', this.createCropContent, this );
     1696                this.frame.on( 'close', this.removeCropper, this );
     1697                this.set('selection', new Backbone.Collection(this.frame._selection.single));
     1698        },
     1699
     1700        createCropContent: function() {
     1701                this.cropperView = new wp.media.view.SiteIconCropper({
     1702                        controller: this,
     1703                        attachment: this.get('selection').first()
     1704                });
     1705                this.cropperView.on('image-loaded', this.createCropToolbar, this);
     1706                this.frame.content.set(this.cropperView);
     1707
     1708        },
     1709
     1710        doCrop: function( attachment ) {
     1711                var cropDetails = attachment.get( 'cropDetails' ),
     1712                        $el = $( '#choose-from-library-link' );
     1713
     1714                cropDetails.dst_width  = $el.data( 'size' );
     1715                cropDetails.dst_height = $el.data( 'size' );
     1716
     1717                return wp.ajax.post( 'crop-image', {
     1718                        nonce: attachment.get( 'nonces' ).edit,
     1719                        id: attachment.get( 'id' ),
     1720                        context: 'site-icon',
     1721                        cropDetails: cropDetails
     1722                } );
     1723        }
     1724});
     1725
     1726module.exports = SiteIconCropper;
     1727
     1728},{}],16:[function(require,module,exports){
    16451729/*globals _, Backbone */
    16461730
    16471731/**
     
    17671851
    17681852module.exports = StateMachine;
    17691853
    1770 },{}],15:[function(require,module,exports){
     1854},{}],17:[function(require,module,exports){
    17711855/*globals _, Backbone */
    17721856
    17731857/**
     
    20102094
    20112095module.exports = State;
    20122096
    2013 },{}],16:[function(require,module,exports){
     2097},{}],18:[function(require,module,exports){
    20142098/*globals _ */
    20152099
    20162100/**
     
    20782162
    20792163module.exports = selectionSync;
    20802164
    2081 },{}],17:[function(require,module,exports){
     2165},{}],19:[function(require,module,exports){
    20822166/*globals wp, jQuery, _, Backbone */
    20832167
    20842168var media = wp.media,
     
    21712255media.controller.MediaLibrary = require( './controllers/media-library.js' );
    21722256media.controller.Embed = require( './controllers/embed.js' );
    21732257media.controller.Cropper = require( './controllers/cropper.js' );
     2258media.controller.CustomizeImageCropper = require( './controllers/customize-image-cropper.js' );
     2259media.controller.SiteIconCropper = require( './controllers/site-icon-cropper.js' );
    21742260
    21752261media.View = require( './views/view.js' );
    21762262media.view.Frame = require( './views/frame.js' );
     
    22242310media.view.EmbedImage = require( './views/embed/image.js' );
    22252311media.view.ImageDetails = require( './views/image-details.js' );
    22262312media.view.Cropper = require( './views/cropper.js' );
     2313media.view.SiteIconCropper = require( './views/site-icon-cropper.js' );
     2314media.view.SiteIconPreview = require( './views/site-icon-preview.js' );
    22272315media.view.EditImage = require( './views/edit-image.js' );
    22282316media.view.Spinner = require( './views/spinner.js' );
    22292317
    2230 },{"./controllers/collection-add.js":1,"./controllers/collection-edit.js":2,"./controllers/cropper.js":3,"./controllers/edit-image.js":4,"./controllers/embed.js":5,"./controllers/featured-image.js":6,"./controllers/gallery-add.js":7,"./controllers/gallery-edit.js":8,"./controllers/image-details.js":9,"./controllers/library.js":10,"./controllers/media-library.js":11,"./controllers/region.js":12,"./controllers/replace-image.js":13,"./controllers/state-machine.js":14,"./controllers/state.js":15,"./utils/selection-sync.js":16,"./views/attachment-compat.js":18,"./views/attachment-filters.js":19,"./views/attachment-filters/all.js":20,"./views/attachment-filters/date.js":21,"./views/attachment-filters/uploaded.js":22,"./views/attachment.js":23,"./views/attachment/details.js":24,"./views/attachment/edit-library.js":25,"./views/attachment/edit-selection.js":26,"./views/attachment/library.js":27,"./views/attachment/selection.js":28,"./views/attachments.js":29,"./views/attachments/browser.js":30,"./views/attachments/selection.js":31,"./views/button-group.js":32,"./views/button.js":33,"./views/cropper.js":34,"./views/edit-image.js":35,"./views/embed.js":36,"./views/embed/image.js":37,"./views/embed/link.js":38,"./views/embed/url.js":39,"./views/focus-manager.js":40,"./views/frame.js":41,"./views/frame/image-details.js":42,"./views/frame/post.js":43,"./views/frame/select.js":44,"./views/iframe.js":45,"./views/image-details.js":46,"./views/label.js":47,"./views/media-frame.js":48,"./views/menu-item.js":49,"./views/menu.js":50,"./views/modal.js":51,"./views/priority-list.js":52,"./views/router-item.js":53,"./views/router.js":54,"./views/search.js":55,"./views/selection.js":56,"./views/settings.js":57,"./views/settings/attachment-display.js":58,"./views/settings/gallery.js":59,"./views/settings/playlist.js":60,"./views/sidebar.js":61,"./views/spinner.js":62,"./views/toolbar.js":63,"./views/toolbar/embed.js":64,"./views/toolbar/select.js":65,"./views/uploader/editor.js":66,"./views/uploader/inline.js":67,"./views/uploader/status-error.js":68,"./views/uploader/status.js":69,"./views/uploader/window.js":70,"./views/view.js":71}],18:[function(require,module,exports){
     2318},{"./controllers/collection-add.js":1,"./controllers/collection-edit.js":2,"./controllers/cropper.js":3,"./controllers/customize-image-cropper.js":4,"./controllers/edit-image.js":5,"./controllers/embed.js":6,"./controllers/featured-image.js":7,"./controllers/gallery-add.js":8,"./controllers/gallery-edit.js":9,"./controllers/image-details.js":10,"./controllers/library.js":11,"./controllers/media-library.js":12,"./controllers/region.js":13,"./controllers/replace-image.js":14,"./controllers/site-icon-cropper.js":15,"./controllers/state-machine.js":16,"./controllers/state.js":17,"./utils/selection-sync.js":18,"./views/attachment-compat.js":20,"./views/attachment-filters.js":21,"./views/attachment-filters/all.js":22,"./views/attachment-filters/date.js":23,"./views/attachment-filters/uploaded.js":24,"./views/attachment.js":25,"./views/attachment/details.js":26,"./views/attachment/edit-library.js":27,"./views/attachment/edit-selection.js":28,"./views/attachment/library.js":29,"./views/attachment/selection.js":30,"./views/attachments.js":31,"./views/attachments/browser.js":32,"./views/attachments/selection.js":33,"./views/button-group.js":34,"./views/button.js":35,"./views/cropper.js":36,"./views/edit-image.js":37,"./views/embed.js":38,"./views/embed/image.js":39,"./views/embed/link.js":40,"./views/embed/url.js":41,"./views/focus-manager.js":42,"./views/frame.js":43,"./views/frame/image-details.js":44,"./views/frame/post.js":45,"./views/frame/select.js":46,"./views/iframe.js":47,"./views/image-details.js":48,"./views/label.js":49,"./views/media-frame.js":50,"./views/menu-item.js":51,"./views/menu.js":52,"./views/modal.js":53,"./views/priority-list.js":54,"./views/router-item.js":55,"./views/router.js":56,"./views/search.js":57,"./views/selection.js":58,"./views/settings.js":59,"./views/settings/attachment-display.js":60,"./views/settings/gallery.js":61,"./views/settings/playlist.js":62,"./views/sidebar.js":63,"./views/site-icon-cropper.js":64,"./views/site-icon-preview.js":65,"./views/spinner.js":66,"./views/toolbar.js":67,"./views/toolbar/embed.js":68,"./views/toolbar/select.js":69,"./views/uploader/editor.js":70,"./views/uploader/inline.js":71,"./views/uploader/status-error.js":72,"./views/uploader/status.js":73,"./views/uploader/window.js":74,"./views/view.js":75}],20:[function(require,module,exports){
    22312319/*globals _ */
    22322320
    22332321/**
     
    23142402
    23152403module.exports = AttachmentCompat;
    23162404
    2317 },{}],19:[function(require,module,exports){
     2405},{}],21:[function(require,module,exports){
    23182406/*globals _, jQuery */
    23192407
    23202408/**
     
    23932481
    23942482module.exports = AttachmentFilters;
    23952483
    2396 },{}],20:[function(require,module,exports){
     2484},{}],22:[function(require,module,exports){
    23972485/*globals wp */
    23982486
    23992487/**
     
    24852573
    24862574module.exports = All;
    24872575
    2488 },{}],21:[function(require,module,exports){
     2576},{}],23:[function(require,module,exports){
    24892577/*globals wp, _ */
    24902578
    24912579/**
     
    25282616
    25292617module.exports = DateFilter;
    25302618
    2531 },{}],22:[function(require,module,exports){
     2619},{}],24:[function(require,module,exports){
    25322620/*globals wp */
    25332621
    25342622/**
     
    25892677
    25902678module.exports = Uploaded;
    25912679
    2592 },{}],23:[function(require,module,exports){
     2680},{}],25:[function(require,module,exports){
    25932681/*globals wp, _, jQuery */
    25942682
    25952683/**
     
    31373225
    31383226module.exports = Attachment;
    31393227
    3140 },{}],24:[function(require,module,exports){
     3228},{}],26:[function(require,module,exports){
    31413229/*globals wp, _ */
    31423230
    31433231/**
     
    32773365
    32783366module.exports = Details;
    32793367
    3280 },{}],25:[function(require,module,exports){
     3368},{}],27:[function(require,module,exports){
    32813369/*globals wp */
    32823370
    32833371/**
     
    32973385
    32983386module.exports = EditLibrary;
    32993387
    3300 },{}],26:[function(require,module,exports){
     3388},{}],28:[function(require,module,exports){
    33013389/*globals wp */
    33023390
    33033391/**
     
    33183406
    33193407module.exports = EditSelection;
    33203408
    3321 },{}],27:[function(require,module,exports){
     3409},{}],29:[function(require,module,exports){
    33223410/*globals wp */
    33233411
    33243412/**
     
    33383426
    33393427module.exports = Library;
    33403428
    3341 },{}],28:[function(require,module,exports){
     3429},{}],30:[function(require,module,exports){
    33423430/*globals wp */
    33433431
    33443432/**
     
    33623450
    33633451module.exports = Selection;
    33643452
    3365 },{}],29:[function(require,module,exports){
     3453},{}],31:[function(require,module,exports){
    33663454/*globals wp, _, jQuery */
    33673455
    33683456/**
     
    36633751
    36643752module.exports = Attachments;
    36653753
    3666 },{}],30:[function(require,module,exports){
     3754},{}],32:[function(require,module,exports){
    36673755/*globals wp, _, jQuery */
    36683756
    36693757/**
     
    41094197
    41104198module.exports = AttachmentsBrowser;
    41114199
    4112 },{}],31:[function(require,module,exports){
     4200},{}],33:[function(require,module,exports){
    41134201/*globals wp, _ */
    41144202
    41154203/**
     
    41414229
    41424230module.exports = Selection;
    41434231
    4144 },{}],32:[function(require,module,exports){
     4232},{}],34:[function(require,module,exports){
    41454233/*globals _, Backbone */
    41464234
    41474235/**
     
    41894277
    41904278module.exports = ButtonGroup;
    41914279
    4192 },{}],33:[function(require,module,exports){
     4280},{}],35:[function(require,module,exports){
    41934281/*globals _, Backbone */
    41944282
    41954283/**
     
    42774365
    42784366module.exports = Button;
    42794367
    4280 },{}],34:[function(require,module,exports){
     4368},{}],36:[function(require,module,exports){
    42814369/*globals wp, _, jQuery */
    42824370
    42834371/**
     
    43464434
    43474435module.exports = Cropper;
    43484436
    4349 },{}],35:[function(require,module,exports){
     4437},{}],37:[function(require,module,exports){
    43504438/*globals wp, _ */
    43514439
    43524440/**
     
    44044492
    44054493module.exports = EditImage;
    44064494
    4407 },{}],36:[function(require,module,exports){
     4495},{}],38:[function(require,module,exports){
    44084496/**
    44094497 * wp.media.view.Embed
    44104498 *
     
    44684556
    44694557module.exports = Embed;
    44704558
    4471 },{}],37:[function(require,module,exports){
     4559},{}],39:[function(require,module,exports){
    44724560/*globals wp */
    44734561
    44744562/**
     
    45034591
    45044592module.exports = EmbedImage;
    45054593
    4506 },{}],38:[function(require,module,exports){
     4594},{}],40:[function(require,module,exports){
    45074595/*globals wp, _, jQuery */
    45084596
    45094597/**
     
    45944682
    45954683module.exports = EmbedLink;
    45964684
    4597 },{}],39:[function(require,module,exports){
     4685},{}],41:[function(require,module,exports){
    45984686/*globals wp, _, jQuery */
    45994687
    46004688/**
     
    46754763
    46764764module.exports = EmbedUrl;
    46774765
    4678 },{}],40:[function(require,module,exports){
     4766},{}],42:[function(require,module,exports){
    46794767/**
    46804768 * wp.media.view.FocusManager
    46814769 *
     
    47214809
    47224810module.exports = FocusManager;
    47234811
    4724 },{}],41:[function(require,module,exports){
     4812},{}],43:[function(require,module,exports){
    47254813/*globals _, Backbone */
    47264814
    47274815/**
     
    48894977
    48904978module.exports = Frame;
    48914979
    4892 },{}],42:[function(require,module,exports){
     4980},{}],44:[function(require,module,exports){
    48934981/*globals wp */
    48944982
    48954983/**
     
    50685156
    50695157module.exports = ImageDetails;
    50705158
    5071 },{}],43:[function(require,module,exports){
     5159},{}],45:[function(require,module,exports){
    50725160/*globals wp, _ */
    50735161
    50745162/**
     
    58055893
    58065894module.exports = Post;
    58075895
    5808 },{}],44:[function(require,module,exports){
     5896},{}],46:[function(require,module,exports){
    58095897/*globals wp, _ */
    58105898
    58115899/**
     
    59786066
    59796067module.exports = Select;
    59806068
    5981 },{}],45:[function(require,module,exports){
     6069},{}],47:[function(require,module,exports){
    59826070/**
    59836071 * wp.media.view.Iframe
    59846072 *
     
    60026090
    60036091module.exports = Iframe;
    60046092
    6005 },{}],46:[function(require,module,exports){
     6093},{}],48:[function(require,module,exports){
    60066094/*globals wp, _, jQuery */
    60076095
    60086096/**
     
    61726260
    61736261module.exports = ImageDetails;
    61746262
    6175 },{}],47:[function(require,module,exports){
     6263},{}],49:[function(require,module,exports){
    61766264/**
    61776265 * wp.media.view.Label
    61786266 *
     
    61986286
    61996287module.exports = Label;
    62006288
    6201 },{}],48:[function(require,module,exports){
     6289},{}],50:[function(require,module,exports){
    62026290/*globals wp, _, jQuery */
    62036291
    62046292/**
     
    64476535
    64486536module.exports = MediaFrame;
    64496537
    6450 },{}],49:[function(require,module,exports){
     6538},{}],51:[function(require,module,exports){
    64516539/*globals jQuery */
    64526540
    64536541/**
     
    65216609
    65226610module.exports = MenuItem;
    65236611
    6524 },{}],50:[function(require,module,exports){
     6612},{}],52:[function(require,module,exports){
    65256613/**
    65266614 * wp.media.view.Menu
    65276615 *
     
    66386726
    66396727module.exports = Menu;
    66406728
    6641 },{}],51:[function(require,module,exports){
     6729},{}],53:[function(require,module,exports){
    66426730/*globals wp, _, jQuery */
    66436731
    66446732/**
     
    68536941
    68546942module.exports = Modal;
    68556943
    6856 },{}],52:[function(require,module,exports){
     6944},{}],54:[function(require,module,exports){
    68576945/*globals _, Backbone */
    68586946
    68596947/**
     
    69527040
    69537041module.exports = PriorityList;
    69547042
    6955 },{}],53:[function(require,module,exports){
     7043},{}],55:[function(require,module,exports){
    69567044/**
    69577045 * wp.media.view.RouterItem
    69587046 *
     
    69767064
    69777065module.exports = RouterItem;
    69787066
    6979 },{}],54:[function(require,module,exports){
     7067},{}],56:[function(require,module,exports){
    69807068/*globals wp */
    69817069
    69827070/**
     
    70157103
    70167104module.exports = Router;
    70177105
    7018 },{}],55:[function(require,module,exports){
     7106},{}],57:[function(require,module,exports){
    70197107/*globals wp */
    70207108
    70217109/**
     
    70657153
    70667154module.exports = Search;
    70677155
    7068 },{}],56:[function(require,module,exports){
     7156},{}],58:[function(require,module,exports){
    70697157/*globals wp, _, Backbone */
    70707158
    70717159/**
     
    71507238
    71517239module.exports = Selection;
    71527240
    7153 },{}],57:[function(require,module,exports){
     7241},{}],59:[function(require,module,exports){
    71547242/*globals _, Backbone */
    71557243
    71567244/**
     
    72737361
    72747362module.exports = Settings;
    72757363
    7276 },{}],58:[function(require,module,exports){
     7364},{}],60:[function(require,module,exports){
    72777365/*globals wp, _ */
    72787366
    72797367/**
     
    73697457
    73707458module.exports = AttachmentDisplay;
    73717459
    7372 },{}],59:[function(require,module,exports){
     7460},{}],61:[function(require,module,exports){
    73737461/*globals wp */
    73747462
    73757463/**
     
    73887476
    73897477module.exports = Gallery;
    73907478
    7391 },{}],60:[function(require,module,exports){
     7479},{}],62:[function(require,module,exports){
    73927480/*globals wp */
    73937481
    73947482/**
     
    74077495
    74087496module.exports = Playlist;
    74097497
    7410 },{}],61:[function(require,module,exports){
     7498},{}],63:[function(require,module,exports){
    74117499/**
    74127500 * wp.media.view.Sidebar
    74137501 *
     
    74237511
    74247512module.exports = Sidebar;
    74257513
    7426 },{}],62:[function(require,module,exports){
     7514},{}],64:[function(require,module,exports){
     7515/*globals wp, _ */
     7516
     7517/**
     7518 * wp.media.view.Cropper
     7519 *
     7520 * Uses the imgAreaSelect plugin to allow a user to crop an image.
     7521 *
     7522 * Takes imgAreaSelect options from
     7523 * wp.customize.HeaderControl.calculateImageSelectOptions via
     7524 * wp.customize.HeaderControl.openMM.
     7525 *
     7526 * @class
     7527 * @augments wp.media.View
     7528 * @augments wp.Backbone.View
     7529 * @augments Backbone.View
     7530 */
     7531var View = wp.media.view,
     7532        SiteIconCropper;
     7533
     7534SiteIconCropper = View.Cropper.extend({
     7535        className: 'crop-content site-icon',
     7536
     7537        onImageLoad: function() {
     7538                var imgOptions = this.controller.get('imgSelectOptions');
     7539                if (typeof imgOptions === 'function') {
     7540                        imgOptions = imgOptions(this.options.attachment, this.controller);
     7541                }
     7542
     7543                imgOptions = _.extend(imgOptions, {parent: this.$el});
     7544                this.trigger('image-loaded');
     7545                this.controller.imgSelect = this.$image.imgAreaSelect(imgOptions);
     7546
     7547                this.sidebar = new wp.media.view.Sidebar({
     7548                        controller: this.controller
     7549                });
     7550                this.sidebar.set( 'preview', new wp.media.view.SiteIconPreview({
     7551                        controller: this.controller,
     7552                        attachment: this.options.attachment
     7553                }) );
     7554
     7555                this.controller.cropperView.views.add( this.sidebar );
     7556        }
     7557});
     7558
     7559module.exports = SiteIconCropper;
     7560
     7561},{}],65:[function(require,module,exports){
     7562/*globals wp, jQuery */
     7563
     7564/**
     7565 * wp.media.view.Cropper
     7566 *
     7567 * Uses the imgAreaSelect plugin to allow a user to crop an image.
     7568 *
     7569 * Takes imgAreaSelect options from
     7570 * wp.customize.HeaderControl.calculateImageSelectOptions via
     7571 * wp.customize.HeaderControl.openMM.
     7572 *
     7573 * @class
     7574 * @augments wp.media.View
     7575 * @augments wp.Backbone.View
     7576 * @augments Backbone.View
     7577 */
     7578var View = wp.media.View,
     7579        $ = jQuery,
     7580        SiteIconPreview;
     7581
     7582SiteIconPreview = View.extend({
     7583        className: 'site-icon-preview',
     7584        template: wp.template( 'site-icon-preview' ),
     7585
     7586        ready: function() {
     7587                this.controller.imgSelect.setOptions({
     7588                        onInit: this.updatePreview,
     7589                        onSelectChange: this.updatePreview
     7590                });
     7591        },
     7592
     7593        prepare: function() {
     7594                return {
     7595                        url: this.options.attachment.get('url')
     7596                };
     7597        },
     7598
     7599        updatePreview: function(img, coords) {
     7600                var rx = 64 / coords.width,
     7601                        ry = 64 / coords.height,
     7602                        preview_rx = 16 / coords.width,
     7603                        preview_ry = 16 / coords.height;
     7604
     7605                $( '#preview-homeicon' ).css({
     7606                        width: Math.round(rx * this.imageWidth ) + 'px',
     7607                        height: Math.round(ry * this.imageHeight ) + 'px',
     7608                        marginLeft: '-' + Math.round(rx * coords.x1) + 'px',
     7609                        marginTop: '-' + Math.round(ry * coords.y1) + 'px'
     7610                });
     7611
     7612                $( '#preview-favicon' ).css({
     7613                        width: Math.round( preview_rx * this.imageWidth ) + 'px',
     7614                        height: Math.round( preview_ry * this.imageHeight ) + 'px',
     7615                        marginLeft: '-' + Math.round( preview_rx * coords.x1 ) + 'px',
     7616                        marginTop: '-' + Math.floor( preview_ry* coords.y1 ) + 'px'
     7617                });
     7618        }
     7619});
     7620
     7621module.exports = SiteIconPreview;
     7622
     7623},{}],66:[function(require,module,exports){
    74277624/*globals _ */
    74287625
    74297626/**
     
    74607657
    74617658module.exports = Spinner;
    74627659
    7463 },{}],63:[function(require,module,exports){
     7660},{}],67:[function(require,module,exports){
    74647661/*globals _, Backbone */
    74657662
    74667663/**
     
    76227819
    76237820module.exports = Toolbar;
    76247821
    7625 },{}],64:[function(require,module,exports){
     7822},{}],68:[function(require,module,exports){
    76267823/*globals wp, _ */
    76277824
    76287825/**
     
    76617858
    76627859module.exports = Embed;
    76637860
    7664 },{}],65:[function(require,module,exports){
     7861},{}],69:[function(require,module,exports){
    76657862/*globals wp, _ */
    76667863
    76677864/**
     
    77337930
    77347931module.exports = Select;
    77357932
    7736 },{}],66:[function(require,module,exports){
     7933},{}],70:[function(require,module,exports){
    77377934/*globals wp, _, jQuery */
    77387935
    77397936/**
     
    79568153
    79578154module.exports = EditorUploader;
    79588155
    7959 },{}],67:[function(require,module,exports){
     8156},{}],71:[function(require,module,exports){
    79608157/*globals wp, _ */
    79618158
    79628159/**
     
    80898286
    80908287module.exports = UploaderInline;
    80918288
    8092 },{}],68:[function(require,module,exports){
     8289},{}],72:[function(require,module,exports){
    80938290/*globals wp */
    80948291
    80958292/**
     
    81078304
    81088305module.exports = UploaderStatusError;
    81098306
    8110 },{}],69:[function(require,module,exports){
     8307},{}],73:[function(require,module,exports){
    81118308/*globals wp, _ */
    81128309
    81138310/**
     
    82478444
    82488445module.exports = UploaderStatus;
    82498446
    8250 },{}],70:[function(require,module,exports){
     8447},{}],74:[function(require,module,exports){
    82518448/*globals wp, _, jQuery */
    82528449
    82538450/**
     
    83608557
    83618558module.exports = UploaderWindow;
    83628559
    8363 },{}],71:[function(require,module,exports){
     8560},{}],75:[function(require,module,exports){
    83648561/*globals wp */
    83658562
    83668563/**
     
    84288625
    84298626module.exports = View;
    84308627
    8431 },{}]},{},[17]);
     8628},{}]},{},[19]);
  • src/wp-includes/media-template.php

     
    12431243                <div class="upload-errors"></div>
    12441244        </script>
    12451245
     1246        <script type="text/html" id="tmpl-site-icon-preview">
     1247                <h2><?php _e( 'Preview' ); ?></h2>
     1248                <strong><?php _e( 'As a browser icon' ); ?></strong>
     1249                <div class="site-icon-crop-favicon-preview-shell">
     1250                        <img src="images/browser.png" class="site-icon-browser-preview" width="182" height="" alt=""/>
     1251
     1252                        <div class="site-icon-crop-preview-favicon">
     1253                                <img id="preview-favicon" src="{{ data.url }}" alt="<?php esc_attr_e( 'Preview as a browser icon' ); ?>"/>
     1254                        </div>
     1255                        <span class="site-icon-browser-title"><?php bloginfo( 'name' ); ?></span>
     1256                </div>
     1257
     1258                <strong><?php _e( 'As an app icon' ); ?></strong>
     1259                <div class="site-icon-crop-preview-homeicon">
     1260                        <img id="preview-homeicon" src="{{ data.url }}" alt="<?php esc_attr_e( 'Preview as an app icon' ); ?>"/>
     1261                </div>
     1262        </script>
     1263
    12461264        <?php
    12471265
    12481266        /**