From 9fe59ced578169572f00d14a065aed22da165cab Mon Sep 17 00:00:00 2001 From: Konstantin Obenland Date: Mon, 20 Jul 2015 15:56:19 +0000 Subject: [PATCH] Site Icon: Add crop preview to the media modal. * Monkey patches imgAreaSelect library to support touch events. * Removes Settings version of Site Icon since it would have been the same flow. * Removes default value for Customizer setting - there is no default favicon. Fixes #16434. git-svn-id: https://develop.svn.wordpress.org/trunk@33329 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/site-icon.css | 63 +-- src/wp-admin/includes/class-wp-site-icon.php | 404 ------------------ src/wp-admin/js/customize-controls.js | 34 ++ src/wp-admin/js/site-icon-crop.js | 53 --- src/wp-admin/js/site-icon.js | 50 --- src/wp-admin/options-general.php | 40 -- .../class-wp-customize-manager.php | 2 - src/wp-includes/css/media-views.css | 11 +- src/wp-includes/js/customize-views.js | 21 - .../js/imgareaselect/jquery.imgareaselect.js | 77 ++-- .../imgareaselect/jquery.imgareaselect.min.js | 2 +- src/wp-includes/js/media-views.js | 330 +++++++++++--- .../controllers/customize-image-cropper.js | 34 ++ .../js/media/controllers/site-icon-cropper.js | 49 +++ src/wp-includes/js/media/views.manifest.js | 4 + .../js/media/views/site-icon-cropper.js | 43 ++ .../js/media/views/site-icon-preview.js | 56 +++ src/wp-includes/media-template.php | 18 + src/wp-includes/script-loader.php | 3 - 19 files changed, 570 insertions(+), 724 deletions(-) delete mode 100644 src/wp-admin/js/site-icon-crop.js delete mode 100644 src/wp-admin/js/site-icon.js create mode 100644 src/wp-includes/js/media/controllers/customize-image-cropper.js create mode 100644 src/wp-includes/js/media/controllers/site-icon-cropper.js create mode 100644 src/wp-includes/js/media/views/site-icon-cropper.js create mode 100644 src/wp-includes/js/media/views/site-icon-preview.js diff --git a/src/wp-admin/css/site-icon.css b/src/wp-admin/css/site-icon.css index d91f292e8c..0e34f5dc9d 100644 --- a/src/wp-admin/css/site-icon.css +++ b/src/wp-admin/css/site-icon.css @@ -2,41 +2,15 @@ 28.0 - Site Icon ------------------------------------------------------------------------------*/ -.site-icon-image { - float: left; - margin: 0 20px 0 0; -} - -.site-icon-content { - overflow: hidden; - padding: 10px; - position: relative; -} - -.site-icon-crop-shell { - max-width: 720px; -} - -.site-icon-crop-wrapper { - float: left; -} - -.site-icon-crop-preview-shell { - float: right; - overflow: hidden; -} - -.site-icon-crop-preview-shell h2 { - padding-top: 0; -} - -.site-icon-crop-favicon-preview-shell { +.site-icon-preview .favicon-preview { margin-bottom: 20px; + overflow: hidden; position: relative; + max-width: 180px; } -.site-icon-crop-preview-favicon, -.site-icon-browser-title { +.site-icon-preview .favicon, +.site-icon-preview .browser-title { height: 16px; left: 88px; overflow: hidden; @@ -44,15 +18,15 @@ top: 16px; } -.site-icon-crop-preview-favicon { +.site-icon-preview .favicon { width: 16px; } -.site-icon-browser-title { +.site-icon-preview .browser-title { left: 109px; } -.site-icon-crop-preview-homeicon { +.site-icon-preview .app-icon-preview { background-color: #000; -webkit-border-radius: 16px; border-radius: 16px; @@ -60,24 +34,3 @@ overflow: hidden; width: 64px; } - -.site-icon-crop-shell .submit { - clear: both; -} - -@media only screen and (max-width: 768px) { - .site-icon-crop-wrapper, - .site-icon-crop-preview-shell { - float: none; - } - - .site-icon-crop-wrapper { - max-width: 100%; - margin-bottom: 20px; - } - - .site-icon-crop-wrapper img { - max-width: 100%; - height: auto; - } -} diff --git a/src/wp-admin/includes/class-wp-site-icon.php b/src/wp-admin/includes/class-wp-site-icon.php index e37ab9206f..d3578d812f 100644 --- a/src/wp-admin/includes/class-wp-site-icon.php +++ b/src/wp-admin/includes/class-wp-site-icon.php @@ -65,371 +65,10 @@ class WP_Site_Icon { * @access public */ public function __construct() { - - // Add the favicon to the backend. - add_action( 'admin_menu', array( $this, 'admin_menu_upload_site_icon' ) ); - - add_action( 'admin_action_set_site_icon', array( $this, 'set_site_icon' ) ); - add_action( 'admin_action_remove_site_icon', array( $this, 'remove_site_icon' ) ); - add_action( 'delete_attachment', array( $this, 'delete_attachment_data' ), 10, 1 ); add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 10, 4 ); } - /** - * Adds a hidden upload page. - * - * There is no need to access it directly. - * - * @since 4.3.0 - * @access public - */ - public function admin_menu_upload_site_icon() { - $hook = add_submenu_page( null, __( 'Site Icon' ), __( 'Site Icon' ), 'manage_options', 'site-icon', array( $this, 'upload_site_icon_page' ) ); - - add_action( "load-$hook", array( $this, 'add_upload_settings' ) ); - add_action( "load-$hook", array( $this, 'maybe_skip_cropping' ) ); - add_action( "admin_print_scripts-$hook", array( $this, 'enqueue_scripts' ) ); - } - - /** - * Adds scripts to admin settings pages. - * - * @since 4.3.0 - * @access public - */ - public function enqueue_scripts() { - wp_enqueue_style( 'jcrop' ); - wp_enqueue_script( 'site-icon-crop' ); - } - - /** - * Loads the settings when the admin is initialized. - * - * @since 4.3.0 - * @access public - */ - public function add_upload_settings() { - add_settings_section( 'site-icon-upload', false, false, 'site-icon-upload' ); - add_settings_field( 'site-icon-upload', __( 'Upload Image' ), array( $this, 'upload_field' ), 'site-icon-upload', 'site-icon-upload', array( - 'label_for' => 'site-icon-upload', - ) ); - } - - /** - * Removes the site icon. - * - * @since 4.3.0 - * @access public - */ - public function remove_site_icon() { - check_admin_referer( 'remove-site-icon' ); - - $this->delete_site_icon(); - - add_settings_error( 'site-icon', 'icon-removed', __( 'Site Icon removed.' ), 'updated' ); - } - - /** - * Handle uploading a site icon. - * - * Uploading a site_icon is a 3 step process - * - * 1. Select the file to upload - * 2. Crop the file - * 3. Confirmation - * - * @since 4.3.0 - * @access public - */ - public function upload_site_icon_page() { - $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'select_site_icon'; - - switch ( $action ) { - case 'select_site_icon': - $this->select_page(); - break; - - case 'crop_site_icon': - $this->crop_page(); - break; - - default: - wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) ); - exit; - } - } - - /** - * Displays the site_icon form to upload the image. - * - * @since 4.3.0 - * @access public - */ - public function select_page() { - ?> -
-

- - -
- 'site-icon', - 'action' => 'crop_site_icon', - ), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) ); - ?> -

- - -

-
- - - -

- $this->min_size" ); ?> -

- -
- get_upload_data(); - - if ( $image_size[0] == $image_size[1] && $image_size[0] == $this->min_size ) { - // No cropping required. - - $url = add_query_arg( array( - 'attachment_id' => $attachment_id, - 'skip-cropping' => true, - 'create-new-attachment' => true, - 'action' => 'set_site_icon', - ), wp_nonce_url( admin_url( 'options-general.php' ), 'set-site-icon' ) ); - - wp_safe_redirect( $url ); - die(); - } - } - - /** - * Handles the image crop admin view. - * - * @since 4.3.0 - * @access public - */ - public function crop_page() { - check_admin_referer( 'crop-site-icon' ); - - list( $attachment_id, $url, $image_size ) = $this->get_upload_data(); - - if ( $image_size[0] < $this->min_size ) { - add_settings_error( 'site-icon', 'too-small', sprintf( __( 'The selected image is smaller than %upx in width.' ), $this->min_size ) ); - - // back to step one - $this->select_page(); - - return; - } - - if ( $image_size[1] < $this->min_size ) { - add_settings_error( 'site-icon', 'too-small', sprintf( __( 'The selected image is smaller than %upx in height.' ), $this->min_size ) ); - - // Back to step one. - $this->select_page(); - - return; - } - - wp_localize_script( 'site-icon-crop', 'wpSiteIconCropData', array( - 'init_x' => 0, - 'init_y' => 0, - 'init_size' => $this->min_size, - 'min_size' => $this->min_size, - 'width' => $image_size[0], - 'height' => $image_size[1], - ) ); - ?> - -
-

- - -
-
-

-

- -
- <?php esc_attr_e( 'Image to be cropped' ); ?> -
- -
-

- -
- - -
- <?php esc_attr_e( 'Preview as a browser icon' ); ?> -
- -
- - -
- <?php esc_attr_e( 'Preview as an app icon' ); ?> -
-
- - - - - - - - - - - - - -

- - - -

-
-
-
- update_attachment_metadata( $attachment_id, $image_url ); - remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) ); - - } else { - // Delete any existing site icon images. - $this->delete_site_icon(); - - if ( empty( $_REQUEST['skip-cropping'] ) ) { - $cropped = wp_crop_image( $attachment_id, $_REQUEST['crop-x'], $_REQUEST['crop-y'], $_REQUEST['crop-w'], $_REQUEST['crop-h'], $this->min_size, $this->min_size ); - - } elseif ( $create_new_attachement ) { - $cropped = _copy_image_file( $attachment_id ); - - } else { - $cropped = get_attached_file( $attachment_id ); - } - - if ( ! $cropped || is_wp_error( $cropped ) ) { - wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) ); - } - - $object = $this->create_attachment_object( $cropped, $attachment_id ); - - if ( $create_new_attachement ) { - unset( $object['ID'] ); - } - - // Update the attachment. - add_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) ); - $attachment_id = $this->insert_attachment( $object, $cropped ); - remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) ); - - // Save the site_icon data into option - update_option( 'site_icon', $attachment_id ); - } - - add_settings_error( 'site-icon', 'icon-updated', __( 'Site Icon updated.' ), 'updated' ); - } - - /** - * Handles uploading the file to be cropped in the second step. - * - * @since 4.3.0 - * @access public - */ - public function handle_upload() { - $uploaded_file = $_FILES['site-icon']; - $file_type = wp_check_filetype_and_ext( $uploaded_file['tmp_name'], $uploaded_file['name'] ); - if ( ! wp_match_mime_types( 'image', $file_type['type'] ) ) { - wp_die( __( 'The uploaded file is not a valid image. Please try again.' ) ); - } - - $file = wp_handle_upload( $uploaded_file, array( 'test_form' => false ) ); - - if ( isset( $file['error'] ) ) { - wp_die( $file['error'], __( 'Image Upload Error' ) ); - } - - $url = $file['url']; - $type = $file['type']; - $file = $file['file']; - $filename = basename( $file ); - - // Construct the object array - $object = array( - 'post_title' => $filename, - 'post_content' => $url, - 'post_mime_type' => $type, - 'guid' => $url, - 'context' => 'site-icon', - ); - - // Save the data - $attachment_id = wp_insert_attachment( $object, $file ); - - return compact( 'attachment_id', 'file', 'filename', 'url', 'type' ); - } - /** * Creates an attachment 'object'. * @@ -564,23 +203,6 @@ class WP_Site_Icon { return $sizes; } - /** - * Deletes all additional image sizes, used for site icons. - * - * @since 4.3.0 - * @access public - * - * @return bool Whether the site icon was successfully deleted. - */ - public function delete_site_icon() { - // We add the filter to make sure that we also delete all the added images. - add_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) ); - wp_delete_attachment( get_option( 'site_icon' ), true ); - remove_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) ); - - return delete_option( 'site_icon' ); - } - /** * Deletes the Site Icon when the image file is deleted. * @@ -619,32 +241,6 @@ class WP_Site_Icon { return $value; } - - /** - * Gets the data required to work with the uploaded image - * - * @since 4.3.0 - * @access private - * - * @return array containing the collected data - */ - private function get_upload_data() { - if ( isset( $_GET['file'] ) ) { - $attachment_id = absint( $_GET['file'] ); - $file = get_attached_file( $attachment_id, true ); - $url = wp_get_attachment_image_src( $attachment_id, 'full' ); - $url = $url[0]; - } else { - $upload = $this->handle_upload(); - $attachment_id = $upload['attachment_id']; - $file = $upload['file']; - $url = $upload['url']; - } - - $image_size = getimagesize( $file ); - - return array( $attachment_id, $url, $image_size ); - } } /** diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index f45e256b98..70652477d0 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -2038,6 +2038,40 @@ * @augments wp.customize.Class */ api.SiteIconControl = api.CroppedImageControl.extend({ + + /** + * Create a media modal select frame, and store it so the instance can be reused when needed. + */ + initFrame: function() { + var l10n = _wpMediaViewsL10n; + + this.frame = wp.media({ + button: { + text: l10n.select, + close: false + }, + states: [ + new wp.media.controller.Library({ + title: this.params.button_labels.frame_title, + library: wp.media.query({ type: 'image' }), + multiple: false, + date: false, + priority: 20, + suggestedWidth: this.params.width, + suggestedHeight: this.params.height + }), + new wp.media.controller.SiteIconCropper({ + imgSelectOptions: this.calculateImageSelectOptions, + control: this + }) + ] + }); + + this.frame.on( 'select', this.onSelect, this ); + this.frame.on( 'cropped', this.onCropped, this ); + this.frame.on( 'skippedcrop', this.onSkippedCrop, this ); + }, + /** * Updates the setting and re-renders the control UI. * diff --git a/src/wp-admin/js/site-icon-crop.js b/src/wp-admin/js/site-icon-crop.js deleted file mode 100644 index 7afea17441..0000000000 --- a/src/wp-admin/js/site-icon-crop.js +++ /dev/null @@ -1,53 +0,0 @@ -/* global wpSiteIconCropData, jQuery */ -(function($) { - var jcrop_api = {}, - siteIconCrop = { - - updateCoords : function ( coords ) { - $( '#crop-x' ).val( coords.x ); - $( '#crop-y' ).val( coords.y ); - $( '#crop-width' ).val( coords.w ); - $( '#crop-height' ).val( coords.h ); - - siteIconCrop.showPreview( coords ); - }, - - showPreview : function( coords ){ - var rx = 64 / coords.w, - ry = 64 / coords.h, - preview_rx = 16 / coords.w, - preview_ry = 16 / coords.h; - - $( '#preview-homeicon' ).css({ - width: Math.round(rx * wpSiteIconCropData.width ) + 'px', - height: Math.round(ry * wpSiteIconCropData.height ) + 'px', - marginLeft: '-' + Math.round(rx * coords.x) + 'px', - marginTop: '-' + Math.round(ry * coords.y) + 'px' - }); - - $( '#preview-favicon' ).css({ - width: Math.round( preview_rx * wpSiteIconCropData.width ) + 'px', - height: Math.round( preview_ry * wpSiteIconCropData.height ) + 'px', - marginLeft: '-' + Math.round( preview_rx * coords.x ) + 'px', - marginTop: '-' + Math.floor( preview_ry* coords.y ) + 'px' - }); - }, - - ready: function() { - jcrop_api = $.Jcrop( '#crop-image' ); - jcrop_api.setOptions({ - bgColor: 'transparent', - aspectRatio: 1, - onSelect: siteIconCrop.updateCoords, - onChange: siteIconCrop.updateCoords, - trueSize: [ wpSiteIconCropData.width, wpSiteIconCropData.height ], - minSize: [ wpSiteIconCropData.min_size, wpSiteIconCropData.min_size ] - }); - jcrop_api.animateTo([wpSiteIconCropData.init_x, wpSiteIconCropData.init_y, wpSiteIconCropData.init_size, wpSiteIconCropData.init_size]); - } - - }; - - siteIconCrop.ready(); - -})(jQuery); \ No newline at end of file diff --git a/src/wp-admin/js/site-icon.js b/src/wp-admin/js/site-icon.js deleted file mode 100644 index 1f31f312fd..0000000000 --- a/src/wp-admin/js/site-icon.js +++ /dev/null @@ -1,50 +0,0 @@ -(function($) { - var frame; - - $( function() { - // Build the choose from library frame. - $( '#choose-from-library-link' ).on( 'click', function( event ) { - var $el = $(this); - event.preventDefault(); - - // If the media frame already exists, reopen it. - if ( frame ) { - frame.open(); - return; - } - - // Create the media frame. - frame = wp.media({ - // Customize the submit button. - button: { - // Set the text of the button. - text: $el.data('update'), - // Tell the button not to close the modal, since we're - // going to refresh the page when the image is selected. - close: false - }, - states: [ - new wp.media.controller.Library({ - title: $el.data( 'choose' ), - library: wp.media.query({ type: 'image' }), - date: false, - suggestedWidth: $el.data( 'size' ), - suggestedHeight: $el.data( 'size' ) - }) - ] - }); - - // When an image is selected, run a callback. - frame.on( 'select', function() { - // Grab the selected attachment. - var attachment = frame.state().get('selection').first(), - link = $el.data('updateLink'); - - // Tell the browser to navigate to the crop step. - window.location = link + '&file=' + attachment.id; - }); - - frame.open(); - }); - }); -}(jQuery)); diff --git a/src/wp-admin/options-general.php b/src/wp-admin/options-general.php index edf0bbfcca..7f2a14ea4f 100644 --- a/src/wp-admin/options-general.php +++ b/src/wp-admin/options-general.php @@ -124,46 +124,6 @@ include( ABSPATH . 'wp-admin/admin-header.php' );

- - - - 'site-icon', - 'action' => 'crop_site_icon', - ), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) ); - - wp_enqueue_media(); - wp_enqueue_script( 'site-icon' ); - - if ( has_site_icon() ) : - $remove_url = add_query_arg( array( - 'action' => 'remove_site_icon', - ), wp_nonce_url( admin_url( 'options-general.php' ), 'remove-site-icon' ) ); - ?> - - -

- - -

-

- - -

- - - -

- -

- - - -

- - diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index a744bb3fc8..9cac338591 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -1357,9 +1357,7 @@ final class WP_Customize_Manager { 'section' => 'title_tagline', ) ); - $icon = wp_get_attachment_image_src( absint( get_option( 'site_icon' ) ), 'full' ); $this->add_setting( 'site_icon', array( - 'default' => $icon[0] ? $icon[0] : '', 'type' => 'option', 'capability' => 'manage_options', 'transport' => 'postMessage', // Previewed with JS in the Customizer controls window. diff --git a/src/wp-includes/css/media-views.css b/src/wp-includes/css/media-views.css index 8db350689d..2d4aba7453 100644 --- a/src/wp-includes/css/media-views.css +++ b/src/wp-includes/css/media-views.css @@ -696,6 +696,10 @@ height: 100%; } +.wp-customizer:not(.mobile) .media-frame-content .crop-content.site-icon { + margin-right: 300px; +} + .media-frame-content .crop-content .crop-image { display: block; margin: auto; @@ -2475,14 +2479,17 @@ @media only screen and (max-width: 480px) { .media-modal-close { - top: 5px; - right: 5px; + top: -5px; } .media-modal .media-frame-title { height: 40px; } + .wp-core-ui.wp-customizer .media-button { + margin-top: 13px; + } + .media-modal .media-frame-title h1, .media-frame:not(.hide-menu) .media-frame-title h1 { font-size: 18px; diff --git a/src/wp-includes/js/customize-views.js b/src/wp-includes/js/customize-views.js index 59b8c97b6e..e5d168de41 100644 --- a/src/wp-includes/js/customize-views.js +++ b/src/wp-includes/js/customize-views.js @@ -3,27 +3,6 @@ if ( ! wp || ! wp.customize ) { return; } var api = wp.customize; - /** - * Use a custom ajax action for cropped image controls. - */ - wp.media.controller.customizeImageCropper = wp.media.controller.Cropper.extend( { - doCrop: function( attachment ) { - var cropDetails = attachment.get( 'cropDetails' ), - control = this.get( 'control' ); - - cropDetails.dst_width = control.params.width; - cropDetails.dst_height = control.params.height; - - return wp.ajax.post( 'crop-image', { - wp_customize: 'on', - nonce: attachment.get( 'nonces' ).edit, - id: attachment.get( 'id' ), - context: control.id, - cropDetails: cropDetails - } ); - } - } ); - /** * wp.customize.HeaderTool.CurrentView * diff --git a/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js b/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js index cb4b923d76..f017895f15 100644 --- a/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js +++ b/src/wp-includes/js/imgareaselect/jquery.imgareaselect.js @@ -1,6 +1,6 @@ /* * imgAreaSelect jQuery plugin - * version 0.9.10 + * version 0.9.10-monkey * * Copyright (c) 2008-2013 Michal Wojciechowski (odyniec.net) * @@ -189,7 +189,7 @@ $.imgAreaSelect = function (img, options) { * @return Viewport X */ function evX(event) { - return event.pageX - parOfs.left; + return max(event.pageX || 0, touchCoords(event).x) - parOfs.left; } /** @@ -200,7 +200,23 @@ $.imgAreaSelect = function (img, options) { * @return Viewport Y */ function evY(event) { - return event.pageY - parOfs.top; + return max(event.pageY || 0, touchCoords(event).y) - parOfs.top; + } + + /** + * Get X and Y coordinates of a touch event + * + * @param event + * The event object + * @return Coordinates object + */ + function touchCoords(event) { + var oev = event.originalEvent || {}; + + if (oev.touches && oev.touches.length) + return { x: oev.touches[0].pageX, y: oev.touches[0].pageY }; + else + return { x: 0, y: 0 }; } /** @@ -486,8 +502,8 @@ $.imgAreaSelect = function (img, options) { if (options.autoHide || selection.width * selection.height == 0) hide($box.add($outer), function () { $(this).hide(); }); - $(document).unbind('mousemove', selectingMouseMove); - $box.mousemove(areaMouseMove); + $(document).off('mousemove touchmove', selectingMouseMove); + $box.on('mousemove touchmove', areaMouseMove); options.onSelectEnd(img, getSelection()); } @@ -500,7 +516,14 @@ $.imgAreaSelect = function (img, options) { * @return false */ function areaMouseDown(event) { - if (event.which != 1) return false; + if (event.type == 'mousedown' && event.which != 1) return false; + + /* + * With mobile browsers, there is no "moving the pointer over" action, + * so we need to simulate one mousemove event happening prior to + * mousedown/touchstart. + */ + areaMouseMove(event); adjust(); @@ -511,22 +534,22 @@ $.imgAreaSelect = function (img, options) { x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); - $(document).mousemove(selectingMouseMove) - .one('mouseup', docMouseUp); - $box.unbind('mousemove', areaMouseMove); + $(document).on('mousemove touchmove', selectingMouseMove) + .one('mouseup touchend', docMouseUp); + $box.off('mousemove touchmove', areaMouseMove); } else if (options.movable) { startX = left + selection.x1 - evX(event); startY = top + selection.y1 - evY(event); - $box.unbind('mousemove', areaMouseMove); + $box.off('mousemove touchmove', areaMouseMove); - $(document).mousemove(movingMouseMove) - .one('mouseup', function () { + $(document).on('mousemove touchmove', movingMouseMove) + .one('mouseup touchend', function () { options.onSelectEnd(img, getSelection()); - $(document).unbind('mousemove', movingMouseMove); - $box.mousemove(areaMouseMove); + $(document).off('mousemove touchmove', movingMouseMove); + $box.on('mousemove touchmove', areaMouseMove); }); } else @@ -676,7 +699,7 @@ $.imgAreaSelect = function (img, options) { * Start selection */ function startSelection() { - $(document).unbind('mousemove', startSelection); + $(document).off('mousemove touchmove', startSelection); adjust(); x2 = x1; @@ -691,9 +714,10 @@ $.imgAreaSelect = function (img, options) { shown = true; - $(document).unbind('mouseup', cancelSelection) - .mousemove(selectingMouseMove).one('mouseup', docMouseUp); - $box.unbind('mousemove', areaMouseMove); + $(document).off('mouseup touchend', cancelSelection) + .on('mousemove touchmove', selectingMouseMove) + .one('mouseup touchend', docMouseUp); + $box.off('mousemove touchmove', areaMouseMove); options.onSelectStart(img, getSelection()); } @@ -702,8 +726,8 @@ $.imgAreaSelect = function (img, options) { * Cancel selection */ function cancelSelection() { - $(document).unbind('mousemove', startSelection) - .unbind('mouseup', cancelSelection); + $(document).off('mousemove touchmove', startSelection) + .off('mouseup touchend', cancelSelection); hide($box.add($outer)); setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); @@ -731,7 +755,8 @@ $.imgAreaSelect = function (img, options) { startY = y1 = evY(event); /* Selection will start when the mouse is moved */ - $(document).mousemove(startSelection).mouseup(cancelSelection); + $(document).on({ 'mousemove touchmove': startSelection, + 'mouseup touchend': cancelSelection }); return false; } @@ -989,20 +1014,22 @@ $.imgAreaSelect = function (img, options) { if (options.disable || options.enable === false) { /* Disable the plugin */ - $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); - $(window).unbind('resize', windowResize); + $box.off({ 'mousemove touchmove': areaMouseMove, + 'mousedown touchstart': areaMouseDown }); + $(window).off('resize', windowResize); } else { if (options.enable || options.disable === false) { /* Enable the plugin */ if (options.resizable || options.movable) - $box.mousemove(areaMouseMove).mousedown(areaMouseDown); + $box.on({ 'mousemove touchmove': areaMouseMove, + 'mousedown touchstart': areaMouseDown }); $(window).resize(windowResize); } if (!options.persistent) - $img.add($outer).mousedown(imgMouseDown); + $img.add($outer).on('mousedown touchstart', imgMouseDown); } options.enable = options.disable = undefined; diff --git a/src/wp-includes/js/imgareaselect/jquery.imgareaselect.min.js b/src/wp-includes/js/imgareaselect/jquery.imgareaselect.min.js index 04babcc572..c57fd24505 100644 --- a/src/wp-includes/js/imgareaselect/jquery.imgareaselect.min.js +++ b/src/wp-includes/js/imgareaselect/jquery.imgareaselect.min.js @@ -1 +1 @@ -(function($){var abs=Math.abs,max=Math.max,min=Math.min,round=Math.round;function div(){return $('
')}$.imgAreaSelect=function(img,options){var $img=$(img),imgLoaded,$box=div(),$area=div(),$border=div().add(div()).add(div()).add(div()),$outer=div().add(div()).add(div()).add(div()),$handles=$([]),$areaOpera,left,top,imgOfs={left:0,top:0},imgWidth,imgHeight,$parent,parOfs={left:0,top:0},zIndex=0,position='absolute',startX,startY,scaleX,scaleY,resize,minWidth,minHeight,maxWidth,maxHeight,aspectRatio,shown,x1,y1,x2,y2,selection={x1:0,y1:0,x2:0,y2:0,width:0,height:0},docElem=document.documentElement,ua=navigator.userAgent,$p,d,i,o,w,h,adjusted;function viewX(x){return x+imgOfs.left-parOfs.left}function viewY(y){return y+imgOfs.top-parOfs.top}function selX(x){return x-imgOfs.left+parOfs.left}function selY(y){return y-imgOfs.top+parOfs.top}function evX(event){return event.pageX-parOfs.left}function evY(event){return event.pageY-parOfs.top}function getSelection(noScale){var sx=noScale||scaleX,sy=noScale||scaleY;return{x1:round(selection.x1*sx),y1:round(selection.y1*sy),x2:round(selection.x2*sx),y2:round(selection.y2*sy),width:round(selection.x2*sx)-round(selection.x1*sx),height:round(selection.y2*sy)-round(selection.y1*sy)}}function setSelection(x1,y1,x2,y2,noScale){var sx=noScale||scaleX,sy=noScale||scaleY;selection={x1:round(x1/sx||0),y1:round(y1/sy||0),x2:round(x2/sx||0),y2:round(y2/sy||0)};selection.width=selection.x2-selection.x1;selection.height=selection.y2-selection.y1}function adjust(){if(!imgLoaded||!$img.width())return;imgOfs={left:round($img.offset().left),top:round($img.offset().top)};imgWidth=$img.innerWidth();imgHeight=$img.innerHeight();imgOfs.top+=($img.outerHeight()-imgHeight)>>1;imgOfs.left+=($img.outerWidth()-imgWidth)>>1;minWidth=round(options.minWidth/scaleX)||0;minHeight=round(options.minHeight/scaleY)||0;maxWidth=round(min(options.maxWidth/scaleX||1<<24,imgWidth));maxHeight=round(min(options.maxHeight/scaleY||1<<24,imgHeight));if($().jquery=='1.3.2'&&position=='fixed'&&!docElem['getBoundingClientRect']){imgOfs.top+=max(document.body.scrollTop,docElem.scrollTop);imgOfs.left+=max(document.body.scrollLeft,docElem.scrollLeft)}parOfs=/absolute|relative/.test($parent.css('position'))?{left:round($parent.offset().left)-$parent.scrollLeft(),top:round($parent.offset().top)-$parent.scrollTop()}:position=='fixed'?{left:$(document).scrollLeft(),top:$(document).scrollTop()}:{left:0,top:0};left=viewX(0);top=viewY(0);if(selection.x2>imgWidth||selection.y2>imgHeight)doResize()}function update(resetKeyPress){if(!shown)return;$box.css({left:viewX(selection.x1),top:viewY(selection.y1)}).add($area).width(w=selection.width).height(h=selection.height);$area.add($border).add($handles).css({left:0,top:0});$border.width(max(w-$border.outerWidth()+$border.innerWidth(),0)).height(max(h-$border.outerHeight()+$border.innerHeight(),0));$($outer[0]).css({left:left,top:top,width:selection.x1,height:imgHeight});$($outer[1]).css({left:left+selection.x1,top:top,width:w,height:selection.y1});$($outer[2]).css({left:left+selection.x2,top:top,width:imgWidth-selection.x2,height:imgHeight});$($outer[3]).css({left:left+selection.x1,top:top+selection.y2,width:w,height:imgHeight-selection.y2});w-=$handles.outerWidth();h-=$handles.outerHeight();switch($handles.length){case 8:$($handles[4]).css({left:w>>1});$($handles[5]).css({left:w,top:h>>1});$($handles[6]).css({left:w>>1,top:h});$($handles[7]).css({top:h>>1});case 4:$handles.slice(1,3).css({left:w});$handles.slice(2,4).css({top:h})}if(resetKeyPress!==false){if($.imgAreaSelect.onKeyPress!=docKeyPress)$(document).unbind($.imgAreaSelect.keyPress,$.imgAreaSelect.onKeyPress);if(options.keys)$(document)[$.imgAreaSelect.keyPress]($.imgAreaSelect.onKeyPress=docKeyPress)}if(msie&&$border.outerWidth()-$border.innerWidth()==2){$border.css('margin',0);setTimeout(function(){$border.css('margin','auto')},0)}}function doUpdate(resetKeyPress){adjust();update(resetKeyPress);x1=viewX(selection.x1);y1=viewY(selection.y1);x2=viewX(selection.x2);y2=viewY(selection.y2)}function hide($elem,fn){options.fadeSpeed?$elem.fadeOut(options.fadeSpeed,fn):$elem.hide()}function areaMouseMove(event){var x=selX(evX(event))-selection.x1,y=selY(evY(event))-selection.y1;if(!adjusted){adjust();adjusted=true;$box.one('mouseout',function(){adjusted=false})}resize='';if(options.resizable){if(y<=options.resizeMargin)resize='n';else if(y>=selection.height-options.resizeMargin)resize='s';if(x<=options.resizeMargin)resize+='w';else if(x>=selection.width-options.resizeMargin)resize+='e'}$box.css('cursor',resize?resize+'-resize':options.movable?'move':'');if($areaOpera)$areaOpera.toggle()}function docMouseUp(event){$('body').css('cursor','');if(options.autoHide||selection.width*selection.height==0)hide($box.add($outer),function(){$(this).hide()});$(document).unbind('mousemove',selectingMouseMove);$box.mousemove(areaMouseMove);options.onSelectEnd(img,getSelection())}function areaMouseDown(event){if(event.which!=1)return false;adjust();if(resize){$('body').css('cursor',resize+'-resize');x1=viewX(selection[/w/.test(resize)?'x2':'x1']);y1=viewY(selection[/n/.test(resize)?'y2':'y1']);$(document).mousemove(selectingMouseMove).one('mouseup',docMouseUp);$box.unbind('mousemove',areaMouseMove)}else if(options.movable){startX=left+selection.x1-evX(event);startY=top+selection.y1-evY(event);$box.unbind('mousemove',areaMouseMove);$(document).mousemove(movingMouseMove).one('mouseup',function(){options.onSelectEnd(img,getSelection());$(document).unbind('mousemove',movingMouseMove);$box.mousemove(areaMouseMove)})}else $img.mousedown(event);return false}function fixAspectRatio(xFirst){if(aspectRatio)if(xFirst){x2=max(left,min(left+imgWidth,x1+abs(y2-y1)*aspectRatio*(x2>x1||-1)));y2=round(max(top,min(top+imgHeight,y1+abs(x2-x1)/aspectRatio*(y2>y1||-1))));x2=round(x2)}else{y2=max(top,min(top+imgHeight,y1+abs(x2-x1)/aspectRatio*(y2>y1||-1)));x2=round(max(left,min(left+imgWidth,x1+abs(y2-y1)*aspectRatio*(x2>x1||-1))));y2=round(y2)}}function doResize(){x1=min(x1,left+imgWidth);y1=min(y1,top+imgHeight);if(abs(x2-x1)left+imgWidth)x1=left+imgWidth-minWidth}if(abs(y2-y1)top+imgHeight)y1=top+imgHeight-minHeight}x2=max(left,min(x2,left+imgWidth));y2=max(top,min(y2,top+imgHeight));fixAspectRatio(abs(x2-x1)maxWidth){x2=x1-maxWidth*(x2maxHeight){y2=y1-maxHeight*(y2=0)$handles.width(5).height(5);if(o=options.borderWidth)$handles.css({borderWidth:o,borderStyle:'solid'});styleOptions($handles,{borderColor1:'border-color',borderColor2:'background-color',borderOpacity:'opacity'})}scaleX=options.imageWidth/imgWidth||1;scaleY=options.imageHeight/imgHeight||1;if(newOptions.x1!=null){setSelection(newOptions.x1,newOptions.y1,newOptions.x2,newOptions.y2);newOptions.show=!newOptions.hide}if(newOptions.keys)options.keys=$.extend({shift:1,ctrl:'resize'},newOptions.keys);$outer.addClass(options.classPrefix+'-outer');$area.addClass(options.classPrefix+'-selection');for(i=0;i++<4;)$($border[i-1]).addClass(options.classPrefix+'-border'+i);styleOptions($area,{selectionColor:'background-color',selectionOpacity:'opacity'});styleOptions($border,{borderOpacity:'opacity',borderWidth:'border-width'});styleOptions($outer,{outerColor:'background-color',outerOpacity:'opacity'});if(o=options.borderColor1)$($border[0]).css({borderStyle:'solid',borderColor:o});if(o=options.borderColor2)$($border[1]).css({borderStyle:'dashed',borderColor:o});$box.append($area.add($border).add($areaOpera)).append($handles);if(msie){if(o=($outer.css('filter')||'').match(/opacity=(\d+)/))$outer.css('opacity',o[1]/100);if(o=($border.css('filter')||'').match(/opacity=(\d+)/))$border.css('opacity',o[1]/100)}if(newOptions.hide)hide($box.add($outer));else if(newOptions.show&&imgLoaded){shown=true;$box.add($outer).fadeIn(options.fadeSpeed||0);doUpdate()}aspectRatio=(d=(options.aspectRatio||'').split(/:/))[0]/d[1];$img.add($outer).unbind('mousedown',imgMouseDown);if(options.disable||options.enable===false){$box.unbind('mousemove',areaMouseMove).unbind('mousedown',areaMouseDown);$(window).unbind('resize',windowResize)}else{if(options.enable||options.disable===false){if(options.resizable||options.movable)$box.mousemove(areaMouseMove).mousedown(areaMouseDown);$(window).resize(windowResize)}if(!options.persistent)$img.add($outer).mousedown(imgMouseDown)}options.enable=options.disable=undefined}this.remove=function(){setOptions({disable:true});$box.add($outer).remove()};this.getOptions=function(){return options};this.setOptions=setOptions;this.getSelection=getSelection;this.setSelection=setSelection;this.cancelSelection=cancelSelection;this.update=doUpdate;var msie=(/msie ([\w.]+)/i.exec(ua)||[])[1],opera=/opera/i.test(ua),safari=/webkit/i.test(ua)&&!/chrome/i.test(ua);$p=$img;while($p.length){zIndex=max(zIndex,!isNaN($p.css('z-index'))?$p.css('z-index'):zIndex);if($p.css('position')=='fixed')position='fixed';$p=$p.parent(':not(body)')}zIndex=options.zIndex||zIndex;if(msie)$img.attr('unselectable','on');$.imgAreaSelect.keyPress=msie||safari?'keydown':'keypress';if(opera)$areaOpera=div().css({width:'100%',height:'100%',position:'absolute',zIndex:zIndex+2||2});$box.add($outer).css({visibility:'hidden',position:position,overflow:'hidden',zIndex:zIndex||'0'});$box.css({zIndex:zIndex+2||2});$area.add($border).css({position:'absolute',fontSize:0});img.complete||img.readyState=='complete'||!$img.is('img')?imgLoad():$img.one('load',imgLoad);if(!imgLoaded&&msie&&msie>=7)img.src=img.src};$.fn.imgAreaSelect=function(options){options=options||{};this.each(function(){if($(this).data('imgAreaSelect')){if(options.remove){$(this).data('imgAreaSelect').remove();$(this).removeData('imgAreaSelect')}else $(this).data('imgAreaSelect').setOptions(options)}else if(!options.remove){if(options.enable===undefined&&options.disable===undefined)options.enable=true;$(this).data('imgAreaSelect',new $.imgAreaSelect(this,options))}});if(options.instance)return $(this).data('imgAreaSelect');return this}})(jQuery); \ No newline at end of file +!function(e){function t(){return e("
")}var o=Math.abs,i=Math.max,s=Math.min,n=Math.round;e.imgAreaSelect=function(r,c){function d(e){return e+gt.left-vt.left}function a(e){return e+gt.top-vt.top}function u(e){return e-gt.left+vt.left}function l(e){return e-gt.top+vt.top}function h(e){return i(e.pageX||0,m(e).x)-vt.left}function f(e){return i(e.pageY||0,m(e).y)-vt.top}function m(e){var t=e.originalEvent||{};return t.touches&&t.touches.length?{x:t.touches[0].pageX,y:t.touches[0].pageY}:{x:0,y:0}}function p(e){var t=e||B,o=e||Q;return{x1:n(wt.x1*t),y1:n(wt.y1*o),x2:n(wt.x2*t),y2:n(wt.y2*o),width:n(wt.x2*t)-n(wt.x1*t),height:n(wt.y2*o)-n(wt.y1*o)}}function y(e,t,o,i,s){var r=s||B,c=s||Q;wt={x1:n(e/r||0),y1:n(t/c||0),x2:n(o/r||0),y2:n(i/c||0)},wt.width=wt.x2-wt.x1,wt.height=wt.y2-wt.y1}function g(){T&<.width()&&(gt={left:n(lt.offset().left),top:n(lt.offset().top)},R=lt.innerWidth(),X=lt.innerHeight(),gt.top+=lt.outerHeight()-X>>1,gt.left+=lt.outerWidth()-R>>1,G=n(c.minWidth/B)||0,J=n(c.minHeight/Q)||0,U=n(s(c.maxWidth/B||1<<24,R)),V=n(s(c.maxHeight/Q||1<<24,X)),"1.3.2"!=e().jquery||"fixed"!=xt||St.getBoundingClientRect||(gt.top+=i(document.body.scrollTop,St.scrollTop),gt.left+=i(document.body.scrollLeft,St.scrollLeft)),vt=/absolute|relative/.test(Y.css("position"))?{left:n(Y.offset().left)-Y.scrollLeft(),top:n(Y.offset().top)-Y.scrollTop()}:"fixed"==xt?{left:e(document).scrollLeft(),top:e(document).scrollTop()}:{left:0,top:0},j=d(0),D=a(0),(wt.x2>R||wt.y2>X)&&C())}function v(t){if(_){switch(ht.css({left:d(wt.x1),top:a(wt.y1)}).add(ft).width(dt=wt.width).height(at=wt.height),ft.add(mt).add(yt).css({left:0,top:0}),mt.width(i(dt-mt.outerWidth()+mt.innerWidth(),0)).height(i(at-mt.outerHeight()+mt.innerHeight(),0)),e(pt[0]).css({left:j,top:D,width:wt.x1,height:X}),e(pt[1]).css({left:j+wt.x1,top:D,width:dt,height:wt.y1}),e(pt[2]).css({left:j+wt.x2,top:D,width:R-wt.x2,height:X}),e(pt[3]).css({left:j+wt.x1,top:D+wt.y2,width:dt,height:X-wt.y2}),dt-=yt.outerWidth(),at-=yt.outerHeight(),yt.length){case 8:e(yt[4]).css({left:dt>>1}),e(yt[5]).css({left:dt,top:at>>1}),e(yt[6]).css({left:dt>>1,top:at}),e(yt[7]).css({top:at>>1});case 4:yt.slice(1,3).css({left:dt}),yt.slice(2,4).css({top:at})}t!==!1&&(e.imgAreaSelect.onKeyPress!=kt&&e(document).unbind(e.imgAreaSelect.keyPress,e.imgAreaSelect.onKeyPress),c.keys&&e(document)[e.imgAreaSelect.keyPress](e.imgAreaSelect.onKeyPress=kt)),Ct&&mt.outerWidth()-mt.innerWidth()==2&&(mt.css("margin",0),setTimeout(function(){mt.css("margin","auto")},0))}}function b(e){g(),v(e),et=d(wt.x1),tt=a(wt.y1),ot=d(wt.x2),it=a(wt.y2)}function x(e,t){c.fadeSpeed?e.fadeOut(c.fadeSpeed,t):e.hide()}function w(e){var t=u(h(e))-wt.x1,o=l(f(e))-wt.y1;ut||(g(),ut=!0,ht.one("mouseout",function(){ut=!1})),F="",c.resizable&&(o<=c.resizeMargin?F="n":o>=wt.height-c.resizeMargin&&(F="s"),t<=c.resizeMargin?F+="w":t>=wt.width-c.resizeMargin&&(F+="e")),ht.css("cursor",F?F+"-resize":c.movable?"move":""),L&&L.toggle()}function S(){e("body").css("cursor",""),(c.autoHide||wt.width*wt.height==0)&&x(ht.add(pt),function(){e(this).hide()}),e(document).off("mousemove touchmove",A),ht.on("mousemove touchmove",w),c.onSelectEnd(r,p())}function z(t){return"mousedown"==t.type&&1!=t.which?!1:(w(t),g(),F?(e("body").css("cursor",F+"-resize"),et=d(wt[/w/.test(F)?"x2":"x1"]),tt=a(wt[/n/.test(F)?"y2":"y1"]),e(document).on("mousemove touchmove",A).one("mouseup touchend",S),ht.off("mousemove touchmove",w)):c.movable?($=j+wt.x1-h(t),q=D+wt.y1-f(t),ht.off("mousemove touchmove",w),e(document).on("mousemove touchmove",I).one("mouseup touchend",function(){c.onSelectEnd(r,p()),e(document).off("mousemove touchmove",I),ht.on("mousemove touchmove",w)})):lt.mousedown(t),!1)}function k(e){Z&&(e?(ot=i(j,s(j+R,et+o(it-tt)*Z*(ot>et||-1))),it=n(i(D,s(D+X,tt+o(ot-et)/Z*(it>tt||-1)))),ot=n(ot)):(it=i(D,s(D+X,tt+o(ot-et)/Z*(it>tt||-1))),ot=n(i(j,s(j+R,et+o(it-tt)*Z*(ot>et||-1)))),it=n(it)))}function C(){et=s(et,j+R),tt=s(tt,D+X),o(ot-et)ot||-1),j>ot?et=j+G:ot>j+R&&(et=j+R-G)),o(it-tt)it||-1),D>it?tt=D+J:it>D+X&&(tt=D+X-J)),ot=i(j,s(ot,j+R)),it=i(D,s(it,D+X)),k(o(ot-et)U&&(ot=et-U*(et>ot||-1),k()),o(it-tt)>V&&(it=tt-V*(tt>it||-1),k(!0)),wt={x1:u(s(et,ot)),x2:u(i(et,ot)),y1:l(s(tt,it)),y2:l(i(tt,it)),width:o(ot-et),height:o(it-tt)},v(),c.onSelectChange(r,p())}function A(e){return ot=/w|e|^$/.test(F)||Z?h(e):d(wt.x2),it=/n|s|^$/.test(F)||Z?f(e):a(wt.y2),C(),!1}function W(t,o){ot=(et=t)+wt.width,it=(tt=o)+wt.height,e.extend(wt,{x1:u(et),y1:l(tt),x2:u(ot),y2:l(it)}),v(),c.onSelectChange(r,p())}function I(e){return et=i(j,s($+h(e),j+R-wt.width)),tt=i(D,s(q+f(e),D+X-wt.height)),W(et,tt),e.preventDefault(),!1}function K(){e(document).off("mousemove touchmove",K),g(),ot=et,it=tt,C(),F="",pt.is(":visible")||ht.add(pt).hide().fadeIn(c.fadeSpeed||0),_=!0,e(document).off("mouseup touchend",P).on("mousemove touchmove",A).one("mouseup touchend",S),ht.off("mousemove touchmove",w),c.onSelectStart(r,p())}function P(){e(document).off("mousemove touchmove",K).off("mouseup touchend",P),x(ht.add(pt)),y(u(et),l(tt),u(et),l(tt)),this instanceof e.imgAreaSelect||(c.onSelectChange(r,p()),c.onSelectEnd(r,p()))}function N(t){return 1!=t.which||pt.is(":animated")?!1:(g(),$=et=h(t),q=tt=f(t),e(document).on({"mousemove touchmove":K,"mouseup touchend":P}),!1)}function H(){b(!1)}function M(){T=!0,O(c=e.extend({classPrefix:"imgareaselect",movable:!0,parent:"body",resizable:!0,resizeMargin:10,onInit:function(){},onSelectStart:function(){},onSelectChange:function(){},onSelectEnd:function(){}},c)),ht.add(pt).css({visibility:""}),c.show&&(_=!0,g(),v(),ht.add(pt).hide().fadeIn(c.fadeSpeed||0)),setTimeout(function(){c.onInit(r,p())},0)}function E(e,t){for(var o in t)void 0!==c[o]&&e.css(t[o],c[o])}function O(o){if(o.parent&&(Y=e(o.parent)).append(ht.add(pt)),e.extend(c,o),g(),null!=o.handles){for(yt.remove(),yt=e([]),rt=o.handles?"corners"==o.handles?4:8:0;rt--;)yt=yt.add(t());yt.addClass(c.classPrefix+"-handle").css({position:"absolute",fontSize:0,zIndex:bt+1||1}),!parseInt(yt.css("width"))>=0&&yt.width(5).height(5),(ct=c.borderWidth)&&yt.css({borderWidth:ct,borderStyle:"solid"}),E(yt,{borderColor1:"border-color",borderColor2:"background-color",borderOpacity:"opacity"})}for(B=c.imageWidth/R||1,Q=c.imageHeight/X||1,null!=o.x1&&(y(o.x1,o.y1,o.x2,o.y2),o.show=!o.hide),o.keys&&(c.keys=e.extend({shift:1,ctrl:"resize"},o.keys)),pt.addClass(c.classPrefix+"-outer"),ft.addClass(c.classPrefix+"-selection"),rt=0;rt++<4;)e(mt[rt-1]).addClass(c.classPrefix+"-border"+rt);E(ft,{selectionColor:"background-color",selectionOpacity:"opacity"}),E(mt,{borderOpacity:"opacity",borderWidth:"border-width"}),E(pt,{outerColor:"background-color",outerOpacity:"opacity"}),(ct=c.borderColor1)&&e(mt[0]).css({borderStyle:"solid",borderColor:ct}),(ct=c.borderColor2)&&e(mt[1]).css({borderStyle:"dashed",borderColor:ct}),ht.append(ft.add(mt).add(L)).append(yt),Ct&&((ct=(pt.css("filter")||"").match(/opacity=(\d+)/))&&pt.css("opacity",ct[1]/100),(ct=(mt.css("filter")||"").match(/opacity=(\d+)/))&&mt.css("opacity",ct[1]/100)),o.hide?x(ht.add(pt)):o.show&&T&&(_=!0,ht.add(pt).fadeIn(c.fadeSpeed||0),b()),Z=(nt=(c.aspectRatio||"").split(/:/))[0]/nt[1],lt.add(pt).unbind("mousedown",N),c.disable||c.enable===!1?(ht.off({"mousemove touchmove":w,"mousedown touchstart":z}),e(window).off("resize",H)):((c.enable||c.disable===!1)&&((c.resizable||c.movable)&&ht.on({"mousemove touchmove":w,"mousedown touchstart":z}),e(window).resize(H)),c.persistent||lt.add(pt).on("mousedown touchstart",N)),c.enable=c.disable=void 0}var T,L,j,D,R,X,Y,$,q,B,Q,F,G,J,U,V,Z,_,et,tt,ot,it,st,nt,rt,ct,dt,at,ut,lt=e(r),ht=t(),ft=t(),mt=t().add(t()).add(t()).add(t()),pt=t().add(t()).add(t()).add(t()),yt=e([]),gt={left:0,top:0},vt={left:0,top:0},bt=0,xt="absolute",wt={x1:0,y1:0,x2:0,y2:0,width:0,height:0},St=document.documentElement,zt=navigator.userAgent,kt=function(e){var t,o,n=c.keys,r=e.keyCode;if(t=isNaN(n.alt)||!e.altKey&&!e.originalEvent.altKey?!isNaN(n.ctrl)&&e.ctrlKey?n.ctrl:!isNaN(n.shift)&&e.shiftKey?n.shift:isNaN(n.arrows)?10:n.arrows:n.alt,"resize"==n.arrows||"resize"==n.shift&&e.shiftKey||"resize"==n.ctrl&&e.ctrlKey||"resize"==n.alt&&(e.altKey||e.originalEvent.altKey)){switch(r){case 37:t=-t;case 39:o=i(et,ot),et=s(et,ot),ot=i(o+t,et),k();break;case 38:t=-t;case 40:o=i(tt,it),tt=s(tt,it),it=i(o+t,tt),k(!0);break;default:return}C()}else switch(et=s(et,ot),tt=s(tt,it),r){case 37:W(i(et-t,j),tt);break;case 38:W(et,i(tt-t,D));break;case 39:W(et+s(t,R-u(ot)),tt);break;case 40:W(et,tt+s(t,X-l(it)));break;default:return}return!1};this.remove=function(){O({disable:!0}),ht.add(pt).remove()},this.getOptions=function(){return c},this.setOptions=O,this.getSelection=p,this.setSelection=y,this.cancelSelection=P,this.update=b;var Ct=(/msie ([\w.]+)/i.exec(zt)||[])[1],At=/opera/i.test(zt),Wt=/webkit/i.test(zt)&&!/chrome/i.test(zt);for(st=lt;st.length;)bt=i(bt,isNaN(st.css("z-index"))?bt:st.css("z-index")),"fixed"==st.css("position")&&(xt="fixed"),st=st.parent(":not(body)");bt=c.zIndex||bt,Ct&<.attr("unselectable","on"),e.imgAreaSelect.keyPress=Ct||Wt?"keydown":"keypress",At&&(L=t().css({width:"100%",height:"100%",position:"absolute",zIndex:bt+2||2})),ht.add(pt).css({visibility:"hidden",position:xt,overflow:"hidden",zIndex:bt||"0"}),ht.css({zIndex:bt+2||2}),ft.add(mt).css({position:"absolute",fontSize:0}),r.complete||"complete"==r.readyState||!lt.is("img")?M():lt.one("load",M),!T&&Ct&&Ct>=7&&(r.src=r.src)},e.fn.imgAreaSelect=function(t){return t=t||{},this.each(function(){e(this).data("imgAreaSelect")?t.remove?(e(this).data("imgAreaSelect").remove(),e(this).removeData("imgAreaSelect")):e(this).data("imgAreaSelect").setOptions(t):t.remove||(void 0===t.enable&&void 0===t.disable&&(t.enable=!0),e(this).data("imgAreaSelect",new e.imgAreaSelect(this,t)))}),t.instance?e(this).data("imgAreaSelect"):this}}(jQuery); \ No newline at end of file diff --git a/src/wp-includes/js/media-views.js b/src/wp-includes/js/media-views.js index 44e1df2c84..a0548516e0 100644 --- a/src/wp-includes/js/media-views.js +++ b/src/wp-includes/js/media-views.js @@ -386,6 +386,42 @@ module.exports = Cropper; },{}],4:[function(require,module,exports){ /*globals wp */ +/** + * wp.media.controller.CustomizeImageCropper + * + * A state for cropping an image. + * + * @class + * @augments wp.media.controller.Cropper + * @augments wp.media.controller.State + * @augments Backbone.Model + */ +var Controller = wp.media.controller, + CustomizeImageCropper; + +CustomizeImageCropper = Controller.Cropper.extend({ + doCrop: function( attachment ) { + var cropDetails = attachment.get( 'cropDetails' ), + control = this.get( 'control' ); + + cropDetails.dst_width = control.params.width; + cropDetails.dst_height = control.params.height; + + return wp.ajax.post( 'crop-image', { + wp_customize: 'on', + nonce: attachment.get( 'nonces' ).edit, + id: attachment.get( 'id' ), + context: control.id, + cropDetails: cropDetails + } ); + } +}); + +module.exports = CustomizeImageCropper; + +},{}],5:[function(require,module,exports){ +/*globals wp */ + /** * wp.media.controller.EditImage * @@ -461,7 +497,7 @@ EditImage = wp.media.controller.State.extend({ module.exports = EditImage; -},{}],5:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ /*globals wp, _, Backbone */ /** @@ -599,7 +635,7 @@ Embed = wp.media.controller.State.extend({ module.exports = Embed; -},{}],6:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ /*globals wp, _ */ /** @@ -723,7 +759,7 @@ FeaturedImage = Library.extend({ module.exports = FeaturedImage; -},{}],7:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ /*globals wp, _ */ /** @@ -816,7 +852,7 @@ GalleryAdd = Library.extend({ module.exports = GalleryAdd; -},{}],8:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ /*globals wp */ /** @@ -960,7 +996,7 @@ GalleryEdit = Library.extend({ module.exports = GalleryEdit; -},{}],9:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ /*globals wp, _ */ /** @@ -1024,7 +1060,7 @@ ImageDetails = State.extend({ module.exports = ImageDetails; -},{}],10:[function(require,module,exports){ +},{}],11:[function(require,module,exports){ /*globals wp, _, Backbone */ /** @@ -1298,7 +1334,7 @@ _.extend( Library.prototype, wp.media.selectionSync ); module.exports = Library; -},{}],11:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ /*globals wp, _ */ /** @@ -1350,7 +1386,7 @@ MediaLibrary = Library.extend({ module.exports = MediaLibrary; -},{}],12:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ /*globals Backbone, _ */ /** @@ -1531,7 +1567,7 @@ _.extend( Region.prototype, { module.exports = Region; -},{}],13:[function(require,module,exports){ +},{}],14:[function(require,module,exports){ /*globals wp, _ */ /** @@ -1641,7 +1677,58 @@ ReplaceImage = Library.extend({ module.exports = ReplaceImage; -},{}],14:[function(require,module,exports){ +},{}],15:[function(require,module,exports){ +/*globals wp, Backbone */ + +/** + * wp.media.controller.SiteIconCropper + * + * A state for cropping a Site Icon. + * + * @class + * @augments wp.media.controller.Cropper + * @augments wp.media.controller.State + * @augments Backbone.Model + */ +var Controller = wp.media.controller, + SiteIconCropper; + +SiteIconCropper = Controller.Cropper.extend({ + activate: function() { + this.frame.on( 'content:create:crop', this.createCropContent, this ); + this.frame.on( 'close', this.removeCropper, this ); + this.set('selection', new Backbone.Collection(this.frame._selection.single)); + }, + + createCropContent: function() { + this.cropperView = new wp.media.view.SiteIconCropper({ + controller: this, + attachment: this.get('selection').first() + }); + this.cropperView.on('image-loaded', this.createCropToolbar, this); + this.frame.content.set(this.cropperView); + + }, + + doCrop: function( attachment ) { + var cropDetails = attachment.get( 'cropDetails' ), + control = this.get( 'control' ); + + cropDetails.dst_width = control.params.width; + cropDetails.dst_height = control.params.height; + + return wp.ajax.post( 'crop-image', { + nonce: attachment.get( 'nonces' ).edit, + id: attachment.get( 'id' ), + context: 'site-icon', + cropDetails: cropDetails + } ); + } +}); + +module.exports = SiteIconCropper; + +},{}],16:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -1767,7 +1854,7 @@ _.each([ 'on', 'off', 'trigger' ], function( method ) { module.exports = StateMachine; -},{}],15:[function(require,module,exports){ +},{}],17:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -2010,7 +2097,7 @@ _.each(['toolbar','content'], function( region ) { module.exports = State; -},{}],16:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ /*globals _ */ /** @@ -2078,7 +2165,7 @@ var selectionSync = { module.exports = selectionSync; -},{}],17:[function(require,module,exports){ +},{}],19:[function(require,module,exports){ /*globals wp, jQuery, _, Backbone */ var media = wp.media, @@ -2171,6 +2258,8 @@ media.controller.EditImage = require( './controllers/edit-image.js' ); media.controller.MediaLibrary = require( './controllers/media-library.js' ); media.controller.Embed = require( './controllers/embed.js' ); media.controller.Cropper = require( './controllers/cropper.js' ); +media.controller.CustomizeImageCropper = require( './controllers/customize-image-cropper.js' ); +media.controller.SiteIconCropper = require( './controllers/site-icon-cropper.js' ); media.View = require( './views/view.js' ); media.view.Frame = require( './views/frame.js' ); @@ -2224,10 +2313,12 @@ media.view.EmbedLink = require( './views/embed/link.js' ); media.view.EmbedImage = require( './views/embed/image.js' ); media.view.ImageDetails = require( './views/image-details.js' ); media.view.Cropper = require( './views/cropper.js' ); +media.view.SiteIconCropper = require( './views/site-icon-cropper.js' ); +media.view.SiteIconPreview = require( './views/site-icon-preview.js' ); media.view.EditImage = require( './views/edit-image.js' ); media.view.Spinner = require( './views/spinner.js' ); -},{"./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){ +},{"./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){ /*globals _ */ /** @@ -2314,7 +2405,7 @@ AttachmentCompat = View.extend({ module.exports = AttachmentCompat; -},{}],19:[function(require,module,exports){ +},{}],21:[function(require,module,exports){ /*globals _, jQuery */ /** @@ -2393,7 +2484,7 @@ AttachmentFilters = wp.media.View.extend({ module.exports = AttachmentFilters; -},{}],20:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ /*globals wp */ /** @@ -2485,7 +2576,7 @@ All = wp.media.view.AttachmentFilters.extend({ module.exports = All; -},{}],21:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ /*globals wp, _ */ /** @@ -2528,7 +2619,7 @@ DateFilter = wp.media.view.AttachmentFilters.extend({ module.exports = DateFilter; -},{}],22:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ /*globals wp */ /** @@ -2589,7 +2680,7 @@ Uploaded = wp.media.view.AttachmentFilters.extend({ module.exports = Uploaded; -},{}],23:[function(require,module,exports){ +},{}],25:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -3137,7 +3228,7 @@ _.each({ module.exports = Attachment; -},{}],24:[function(require,module,exports){ +},{}],26:[function(require,module,exports){ /*globals wp, _ */ /** @@ -3277,7 +3368,7 @@ Details = Attachment.extend({ module.exports = Details; -},{}],25:[function(require,module,exports){ +},{}],27:[function(require,module,exports){ /*globals wp */ /** @@ -3297,7 +3388,7 @@ var EditLibrary = wp.media.view.Attachment.extend({ module.exports = EditLibrary; -},{}],26:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ /*globals wp */ /** @@ -3318,7 +3409,7 @@ var EditSelection = wp.media.view.Attachment.Selection.extend({ module.exports = EditSelection; -},{}],27:[function(require,module,exports){ +},{}],29:[function(require,module,exports){ /*globals wp */ /** @@ -3338,7 +3429,7 @@ var Library = wp.media.view.Attachment.extend({ module.exports = Library; -},{}],28:[function(require,module,exports){ +},{}],30:[function(require,module,exports){ /*globals wp */ /** @@ -3362,7 +3453,7 @@ var Selection = wp.media.view.Attachment.extend({ module.exports = Selection; -},{}],29:[function(require,module,exports){ +},{}],31:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -3663,7 +3754,7 @@ Attachments = View.extend({ module.exports = Attachments; -},{}],30:[function(require,module,exports){ +},{}],32:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -4109,7 +4200,7 @@ AttachmentsBrowser = View.extend({ module.exports = AttachmentsBrowser; -},{}],31:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ /*globals wp, _ */ /** @@ -4141,7 +4232,7 @@ Selection = Attachments.extend({ module.exports = Selection; -},{}],32:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -4189,7 +4280,7 @@ ButtonGroup = wp.media.View.extend({ module.exports = ButtonGroup; -},{}],33:[function(require,module,exports){ +},{}],35:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -4277,7 +4368,7 @@ var Button = wp.media.View.extend({ module.exports = Button; -},{}],34:[function(require,module,exports){ +},{}],36:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -4346,7 +4437,7 @@ Cropper = View.extend({ module.exports = Cropper; -},{}],35:[function(require,module,exports){ +},{}],37:[function(require,module,exports){ /*globals wp, _ */ /** @@ -4404,7 +4495,7 @@ EditImage = View.extend({ module.exports = EditImage; -},{}],36:[function(require,module,exports){ +},{}],38:[function(require,module,exports){ /** * wp.media.view.Embed * @@ -4468,7 +4559,7 @@ var Embed = wp.media.View.extend({ module.exports = Embed; -},{}],37:[function(require,module,exports){ +},{}],39:[function(require,module,exports){ /*globals wp */ /** @@ -4503,7 +4594,7 @@ EmbedImage = AttachmentDisplay.extend({ module.exports = EmbedImage; -},{}],38:[function(require,module,exports){ +},{}],40:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -4594,7 +4685,7 @@ EmbedLink = wp.media.view.Settings.extend({ module.exports = EmbedLink; -},{}],39:[function(require,module,exports){ +},{}],41:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -4675,7 +4766,7 @@ EmbedUrl = View.extend({ module.exports = EmbedUrl; -},{}],40:[function(require,module,exports){ +},{}],42:[function(require,module,exports){ /** * wp.media.view.FocusManager * @@ -4721,7 +4812,7 @@ var FocusManager = wp.media.View.extend({ module.exports = FocusManager; -},{}],41:[function(require,module,exports){ +},{}],43:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -4889,7 +4980,7 @@ _.extend( Frame.prototype, wp.media.controller.StateMachine.prototype ); module.exports = Frame; -},{}],42:[function(require,module,exports){ +},{}],44:[function(require,module,exports){ /*globals wp */ /** @@ -5068,7 +5159,7 @@ ImageDetails = Select.extend({ module.exports = ImageDetails; -},{}],43:[function(require,module,exports){ +},{}],45:[function(require,module,exports){ /*globals wp, _ */ /** @@ -5805,7 +5896,7 @@ Post = Select.extend({ module.exports = Post; -},{}],44:[function(require,module,exports){ +},{}],46:[function(require,module,exports){ /*globals wp, _ */ /** @@ -5978,7 +6069,7 @@ Select = MediaFrame.extend({ module.exports = Select; -},{}],45:[function(require,module,exports){ +},{}],47:[function(require,module,exports){ /** * wp.media.view.Iframe * @@ -6002,7 +6093,7 @@ var Iframe = wp.media.View.extend({ module.exports = Iframe; -},{}],46:[function(require,module,exports){ +},{}],48:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -6172,7 +6263,7 @@ ImageDetails = AttachmentDisplay.extend({ module.exports = ImageDetails; -},{}],47:[function(require,module,exports){ +},{}],49:[function(require,module,exports){ /** * wp.media.view.Label * @@ -6198,7 +6289,7 @@ var Label = wp.media.View.extend({ module.exports = Label; -},{}],48:[function(require,module,exports){ +},{}],50:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -6447,7 +6538,7 @@ _.each(['open','close','attach','detach','escape'], function( method ) { module.exports = MediaFrame; -},{}],49:[function(require,module,exports){ +},{}],51:[function(require,module,exports){ /*globals jQuery */ /** @@ -6521,7 +6612,7 @@ MenuItem = wp.media.View.extend({ module.exports = MenuItem; -},{}],50:[function(require,module,exports){ +},{}],52:[function(require,module,exports){ /** * wp.media.view.Menu * @@ -6638,7 +6729,7 @@ Menu = PriorityList.extend({ module.exports = Menu; -},{}],51:[function(require,module,exports){ +},{}],53:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -6853,7 +6944,7 @@ Modal = wp.media.View.extend({ module.exports = Modal; -},{}],52:[function(require,module,exports){ +},{}],54:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -6952,7 +7043,7 @@ var PriorityList = wp.media.View.extend({ module.exports = PriorityList; -},{}],53:[function(require,module,exports){ +},{}],55:[function(require,module,exports){ /** * wp.media.view.RouterItem * @@ -6976,7 +7067,7 @@ var RouterItem = wp.media.view.MenuItem.extend({ module.exports = RouterItem; -},{}],54:[function(require,module,exports){ +},{}],56:[function(require,module,exports){ /*globals wp */ /** @@ -7015,7 +7106,7 @@ Router = Menu.extend({ module.exports = Router; -},{}],55:[function(require,module,exports){ +},{}],57:[function(require,module,exports){ /*globals wp */ /** @@ -7065,7 +7156,7 @@ Search = wp.media.View.extend({ module.exports = Search; -},{}],56:[function(require,module,exports){ +},{}],58:[function(require,module,exports){ /*globals wp, _, Backbone */ /** @@ -7150,7 +7241,7 @@ Selection = wp.media.View.extend({ module.exports = Selection; -},{}],57:[function(require,module,exports){ +},{}],59:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -7273,7 +7364,7 @@ Settings = View.extend({ module.exports = Settings; -},{}],58:[function(require,module,exports){ +},{}],60:[function(require,module,exports){ /*globals wp, _ */ /** @@ -7369,7 +7460,7 @@ AttachmentDisplay = Settings.extend({ module.exports = AttachmentDisplay; -},{}],59:[function(require,module,exports){ +},{}],61:[function(require,module,exports){ /*globals wp */ /** @@ -7388,7 +7479,7 @@ var Gallery = wp.media.view.Settings.extend({ module.exports = Gallery; -},{}],60:[function(require,module,exports){ +},{}],62:[function(require,module,exports){ /*globals wp */ /** @@ -7407,7 +7498,7 @@ var Playlist = wp.media.view.Settings.extend({ module.exports = Playlist; -},{}],61:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ /** * wp.media.view.Sidebar * @@ -7423,7 +7514,110 @@ var Sidebar = wp.media.view.PriorityList.extend({ module.exports = Sidebar; -},{}],62:[function(require,module,exports){ +},{}],64:[function(require,module,exports){ +/*globals wp, _ */ + +/** + * wp.media.view.SiteIconCropper + * + * Uses the imgAreaSelect plugin to allow a user to crop a Site Icon. + * + * Takes imgAreaSelect options from + * wp.customize.SiteIconControl.calculateImageSelectOptions. + * + * @class + * @augments wp.media.view.Cropper + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +var View = wp.media.view, + SiteIconCropper; + +SiteIconCropper = View.Cropper.extend({ + className: 'crop-content site-icon', + + ready: function () { + View.Cropper.prototype.ready.apply( this, arguments ); + + this.$( '.crop-image' ).on( 'load', _.bind( this.addSidebar, this ) ); + }, + + addSidebar: function() { + this.sidebar = new wp.media.view.Sidebar({ + controller: this.controller + }); + + this.sidebar.set( 'preview', new wp.media.view.SiteIconPreview({ + controller: this.controller, + attachment: this.options.attachment + }) ); + + this.controller.cropperView.views.add( this.sidebar ); + } +}); + +module.exports = SiteIconCropper; + +},{}],65:[function(require,module,exports){ +/*globals wp, jQuery */ + +/** + * wp.media.view.SiteIconPreview + * + * Shows a preview of the Site Icon as a favicon and app icon while cropping. + * + * @class + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +var View = wp.media.View, + $ = jQuery, + SiteIconPreview; + +SiteIconPreview = View.extend({ + className: 'site-icon-preview', + template: wp.template( 'site-icon-preview' ), + + ready: function() { + this.controller.imgSelect.setOptions({ + onInit: this.updatePreview, + onSelectChange: this.updatePreview + }); + }, + + prepare: function() { + return { + url: this.options.attachment.get( 'url' ) + }; + }, + + updatePreview: function( img, coords ) { + var rx = 64 / coords.width, + ry = 64 / coords.height, + preview_rx = 16 / coords.width, + preview_ry = 16 / coords.height; + + $( '#preview-app-icon' ).css({ + width: Math.round(rx * this.imageWidth ) + 'px', + height: Math.round(ry * this.imageHeight ) + 'px', + marginLeft: '-' + Math.round(rx * coords.x1) + 'px', + marginTop: '-' + Math.round(ry * coords.y1) + 'px' + }); + + $( '#preview-favicon' ).css({ + width: Math.round( preview_rx * this.imageWidth ) + 'px', + height: Math.round( preview_ry * this.imageHeight ) + 'px', + marginLeft: '-' + Math.round( preview_rx * coords.x1 ) + 'px', + marginTop: '-' + Math.floor( preview_ry* coords.y1 ) + 'px' + }); + } +}); + +module.exports = SiteIconPreview; + +},{}],66:[function(require,module,exports){ /*globals _ */ /** @@ -7460,7 +7654,7 @@ var Spinner = wp.media.View.extend({ module.exports = Spinner; -},{}],63:[function(require,module,exports){ +},{}],67:[function(require,module,exports){ /*globals _, Backbone */ /** @@ -7622,7 +7816,7 @@ Toolbar = View.extend({ module.exports = Toolbar; -},{}],64:[function(require,module,exports){ +},{}],68:[function(require,module,exports){ /*globals wp, _ */ /** @@ -7661,7 +7855,7 @@ Embed = Select.extend({ module.exports = Embed; -},{}],65:[function(require,module,exports){ +},{}],69:[function(require,module,exports){ /*globals wp, _ */ /** @@ -7733,7 +7927,7 @@ Select = Toolbar.extend({ module.exports = Select; -},{}],66:[function(require,module,exports){ +},{}],70:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -7956,7 +8150,7 @@ EditorUploader = View.extend({ module.exports = EditorUploader; -},{}],67:[function(require,module,exports){ +},{}],71:[function(require,module,exports){ /*globals wp, _ */ /** @@ -8089,7 +8283,7 @@ UploaderInline = View.extend({ module.exports = UploaderInline; -},{}],68:[function(require,module,exports){ +},{}],72:[function(require,module,exports){ /*globals wp */ /** @@ -8107,7 +8301,7 @@ var UploaderStatusError = wp.media.View.extend({ module.exports = UploaderStatusError; -},{}],69:[function(require,module,exports){ +},{}],73:[function(require,module,exports){ /*globals wp, _ */ /** @@ -8247,7 +8441,7 @@ UploaderStatus = View.extend({ module.exports = UploaderStatus; -},{}],70:[function(require,module,exports){ +},{}],74:[function(require,module,exports){ /*globals wp, _, jQuery */ /** @@ -8360,7 +8554,7 @@ UploaderWindow = wp.media.View.extend({ module.exports = UploaderWindow; -},{}],71:[function(require,module,exports){ +},{}],75:[function(require,module,exports){ /*globals wp */ /** @@ -8428,4 +8622,4 @@ var View = wp.Backbone.View.extend({ module.exports = View; -},{}]},{},[17]); +},{}]},{},[19]); diff --git a/src/wp-includes/js/media/controllers/customize-image-cropper.js b/src/wp-includes/js/media/controllers/customize-image-cropper.js new file mode 100644 index 0000000000..d7c905520d --- /dev/null +++ b/src/wp-includes/js/media/controllers/customize-image-cropper.js @@ -0,0 +1,34 @@ +/*globals wp */ + +/** + * wp.media.controller.CustomizeImageCropper + * + * A state for cropping an image. + * + * @class + * @augments wp.media.controller.Cropper + * @augments wp.media.controller.State + * @augments Backbone.Model + */ +var Controller = wp.media.controller, + CustomizeImageCropper; + +CustomizeImageCropper = Controller.Cropper.extend({ + doCrop: function( attachment ) { + var cropDetails = attachment.get( 'cropDetails' ), + control = this.get( 'control' ); + + cropDetails.dst_width = control.params.width; + cropDetails.dst_height = control.params.height; + + return wp.ajax.post( 'crop-image', { + wp_customize: 'on', + nonce: attachment.get( 'nonces' ).edit, + id: attachment.get( 'id' ), + context: control.id, + cropDetails: cropDetails + } ); + } +}); + +module.exports = CustomizeImageCropper; diff --git a/src/wp-includes/js/media/controllers/site-icon-cropper.js b/src/wp-includes/js/media/controllers/site-icon-cropper.js new file mode 100644 index 0000000000..df2e594c8f --- /dev/null +++ b/src/wp-includes/js/media/controllers/site-icon-cropper.js @@ -0,0 +1,49 @@ +/*globals wp, Backbone */ + +/** + * wp.media.controller.SiteIconCropper + * + * A state for cropping a Site Icon. + * + * @class + * @augments wp.media.controller.Cropper + * @augments wp.media.controller.State + * @augments Backbone.Model + */ +var Controller = wp.media.controller, + SiteIconCropper; + +SiteIconCropper = Controller.Cropper.extend({ + activate: function() { + this.frame.on( 'content:create:crop', this.createCropContent, this ); + this.frame.on( 'close', this.removeCropper, this ); + this.set('selection', new Backbone.Collection(this.frame._selection.single)); + }, + + createCropContent: function() { + this.cropperView = new wp.media.view.SiteIconCropper({ + controller: this, + attachment: this.get('selection').first() + }); + this.cropperView.on('image-loaded', this.createCropToolbar, this); + this.frame.content.set(this.cropperView); + + }, + + doCrop: function( attachment ) { + var cropDetails = attachment.get( 'cropDetails' ), + control = this.get( 'control' ); + + cropDetails.dst_width = control.params.width; + cropDetails.dst_height = control.params.height; + + return wp.ajax.post( 'crop-image', { + nonce: attachment.get( 'nonces' ).edit, + id: attachment.get( 'id' ), + context: 'site-icon', + cropDetails: cropDetails + } ); + } +}); + +module.exports = SiteIconCropper; diff --git a/src/wp-includes/js/media/views.manifest.js b/src/wp-includes/js/media/views.manifest.js index ccc74abf6a..bc57228eb5 100644 --- a/src/wp-includes/js/media/views.manifest.js +++ b/src/wp-includes/js/media/views.manifest.js @@ -90,6 +90,8 @@ media.controller.EditImage = require( './controllers/edit-image.js' ); media.controller.MediaLibrary = require( './controllers/media-library.js' ); media.controller.Embed = require( './controllers/embed.js' ); media.controller.Cropper = require( './controllers/cropper.js' ); +media.controller.CustomizeImageCropper = require( './controllers/customize-image-cropper.js' ); +media.controller.SiteIconCropper = require( './controllers/site-icon-cropper.js' ); media.View = require( './views/view.js' ); media.view.Frame = require( './views/frame.js' ); @@ -143,5 +145,7 @@ media.view.EmbedLink = require( './views/embed/link.js' ); media.view.EmbedImage = require( './views/embed/image.js' ); media.view.ImageDetails = require( './views/image-details.js' ); media.view.Cropper = require( './views/cropper.js' ); +media.view.SiteIconCropper = require( './views/site-icon-cropper.js' ); +media.view.SiteIconPreview = require( './views/site-icon-preview.js' ); media.view.EditImage = require( './views/edit-image.js' ); media.view.Spinner = require( './views/spinner.js' ); diff --git a/src/wp-includes/js/media/views/site-icon-cropper.js b/src/wp-includes/js/media/views/site-icon-cropper.js new file mode 100644 index 0000000000..443d73d164 --- /dev/null +++ b/src/wp-includes/js/media/views/site-icon-cropper.js @@ -0,0 +1,43 @@ +/*globals wp, _ */ + +/** + * wp.media.view.SiteIconCropper + * + * Uses the imgAreaSelect plugin to allow a user to crop a Site Icon. + * + * Takes imgAreaSelect options from + * wp.customize.SiteIconControl.calculateImageSelectOptions. + * + * @class + * @augments wp.media.view.Cropper + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +var View = wp.media.view, + SiteIconCropper; + +SiteIconCropper = View.Cropper.extend({ + className: 'crop-content site-icon', + + ready: function () { + View.Cropper.prototype.ready.apply( this, arguments ); + + this.$( '.crop-image' ).on( 'load', _.bind( this.addSidebar, this ) ); + }, + + addSidebar: function() { + this.sidebar = new wp.media.view.Sidebar({ + controller: this.controller + }); + + this.sidebar.set( 'preview', new wp.media.view.SiteIconPreview({ + controller: this.controller, + attachment: this.options.attachment + }) ); + + this.controller.cropperView.views.add( this.sidebar ); + } +}); + +module.exports = SiteIconCropper; diff --git a/src/wp-includes/js/media/views/site-icon-preview.js b/src/wp-includes/js/media/views/site-icon-preview.js new file mode 100644 index 0000000000..fc230690a0 --- /dev/null +++ b/src/wp-includes/js/media/views/site-icon-preview.js @@ -0,0 +1,56 @@ +/*globals wp, jQuery */ + +/** + * wp.media.view.SiteIconPreview + * + * Shows a preview of the Site Icon as a favicon and app icon while cropping. + * + * @class + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +var View = wp.media.View, + $ = jQuery, + SiteIconPreview; + +SiteIconPreview = View.extend({ + className: 'site-icon-preview', + template: wp.template( 'site-icon-preview' ), + + ready: function() { + this.controller.imgSelect.setOptions({ + onInit: this.updatePreview, + onSelectChange: this.updatePreview + }); + }, + + prepare: function() { + return { + url: this.options.attachment.get( 'url' ) + }; + }, + + updatePreview: function( img, coords ) { + var rx = 64 / coords.width, + ry = 64 / coords.height, + preview_rx = 16 / coords.width, + preview_ry = 16 / coords.height; + + $( '#preview-app-icon' ).css({ + width: Math.round(rx * this.imageWidth ) + 'px', + height: Math.round(ry * this.imageHeight ) + 'px', + marginLeft: '-' + Math.round(rx * coords.x1) + 'px', + marginTop: '-' + Math.round(ry * coords.y1) + 'px' + }); + + $( '#preview-favicon' ).css({ + width: Math.round( preview_rx * this.imageWidth ) + 'px', + height: Math.round( preview_ry * this.imageHeight ) + 'px', + marginLeft: '-' + Math.round( preview_rx * coords.x1 ) + 'px', + marginTop: '-' + Math.floor( preview_ry* coords.y1 ) + 'px' + }); + } +}); + +module.exports = SiteIconPreview; diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index a8933f36f1..8edeb62ebf 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -1243,6 +1243,24 @@ function wp_print_media_templates() {
+ + _x( '(no label)', 'missing menu item navigation label' ) ) ); - $scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery' ), false, 1 ); - $scripts->add( 'site-icon-crop', '/wp-admin/js/site-icon-crop.js', array( 'jcrop' ), false, 1 ); - $scripts->add( 'custom-header', "/wp-admin/js/custom-header.js", array( 'jquery-masonry' ), false, 1 ); $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array( 'wp-color-picker', 'media-views' ), false, 1 ); $scripts->add( 'media-gallery', "/wp-admin/js/media-gallery$suffix.js", array('jquery'), false, 1 );