Ticket #21811: 21811-07.patch
File 21811-07.patch, 17.7 KB (added by , 11 years ago) |
---|
-
src/wp-admin/js/image-edit.js
diff --git src/wp-admin/js/image-edit.js src/wp-admin/js/image-edit.js index 9eaf51b..90016c1 100644
var imageEdit = window.imageEdit = { 5 5 iasapi : {}, 6 6 hold : {}, 7 7 postid : '', 8 _view : {}, 8 9 9 10 intval : function(f) { 10 11 return f | 0; … … var imageEdit = window.imageEdit = { 245 246 }, 246 247 247 248 save : function(postid, nonce) { 248 var data, target = this.getTarget(postid), history = this.filterHistory(postid, 0); 249 var data, 250 target = this.getTarget(postid), 251 history = this.filterHistory(postid, 0), 252 self = this; 249 253 250 254 if ( '' === history ) { 251 255 return false; … … var imageEdit = window.imageEdit = { 283 287 $('#imgedit-response-' + postid).html('<div class="updated"><p>' + ret.msg + '</p></div>'); 284 288 } 285 289 286 imageEdit.close(postid); 290 if ( self._view ) { 291 self._view.save(); 292 } else { 293 imageEdit.close(postid); 294 } 287 295 }); 288 296 }, 289 297 290 open : function(postid, nonce) { 298 open : function( postid, nonce, view ) { 299 this._view = view; 300 291 301 var data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid), 292 302 btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('.spinner'); 293 303 … … var imageEdit = window.imageEdit = { 319 329 }, 320 330 321 331 initCrop : function(postid, image, parent) { 322 var t = this, selW = $('#imgedit-sel-width-' + postid), 323 selH = $('#imgedit-sel-height-' + postid); 332 var t = this, 333 selW = $('#imgedit-sel-width-' + postid), 334 selH = $('#imgedit-sel-height-' + postid), 335 $img; 324 336 325 337 t.iasapi = $(image).imgAreaSelect({ 326 338 parent: parent, … … var imageEdit = window.imageEdit = { 330 342 minWidth: 3, 331 343 minHeight: 3, 332 344 333 onInit: function() { 345 onInit: function( img ) { 346 // Ensure that the imgareaselect wrapper elements are position:absolute 347 // (even if we're in a position:fixed modal) 348 $img = $( img ); 349 $img.next().css( 'position', 'absolute' ) 350 .nextAll( '.imgareaselect-outer' ).css( 'position', 'absolute' ); 351 334 352 parent.children().mousedown(function(e){ 335 353 var ratio = false, sel, defRatio; 336 354 … … var imageEdit = window.imageEdit = { 397 415 398 416 this.iasapi = {}; 399 417 this.hold = {}; 400 $('#image-editor-' + postid).fadeOut('fast', function() { 401 $('#media-head-' + postid).fadeIn('fast'); 402 $(this).empty(); 403 }); 418 419 // If we've loaded the editor in the context of a Media Modal, then switch to the previous view, 420 // whatever that might have been. 421 if ( this._view && 'object' === typeof this._view ){ 422 this._view.back(); 423 } 424 425 // In case we are not accessing the image editor in the context of a View, close the editor the old-skool way 426 else { 427 $('#image-editor-' + postid).fadeOut('fast', function() { 428 $('#media-head-' + postid).fadeIn('fast'); 429 $(this).empty(); 430 }); 431 } 432 433 404 434 }, 405 435 406 436 notsaved : function(postid) { -
src/wp-includes/css/media-views.css
diff --git src/wp-includes/css/media-views.css src/wp-includes/css/media-views.css index 6d9d9b0..3259fd2 100644
1486 1486 display: block; 1487 1487 } 1488 1488 1489 .media-embed .edit-attachment { 1490 margin-left: 10px; 1491 } 1492 1489 1493 .media-embed .thumbnail:after { 1490 1494 content: ''; 1491 1495 display: block; -
src/wp-includes/js/media-editor.js
diff --git src/wp-includes/js/media-editor.js src/wp-includes/js/media-editor.js index ec13796..b2dfd15 100644
648 648 649 649 this._frame = wp.media({ 650 650 state: 'featured-image', 651 states: [ new wp.media.controller.FeaturedImage() ]651 states: [ new wp.media.controller.FeaturedImage() , new wp.media.controller.EditImage() ] 652 652 }); 653 653 654 654 this._frame.on( 'toolbar:create:featured-image', function( toolbar ) { … … 660 660 }); 661 661 }, this._frame ); 662 662 663 this._frame.on( 'content:render:edit-image', function() { 664 var selection = this.state('featured-image').get('selection'), 665 view = new wp.media.view.EditImage( { model: selection.single(), controller: this } ).render(); 666 667 this.content.set( view ); 668 669 // after bringing in the frame, load the actual editor via an ajax call 670 view.loadEditor(); 671 672 }, this._frame ); 673 663 674 this._frame.state('featured-image').on( 'select', this.select ); 664 675 return this._frame; 665 676 }, -
src/wp-includes/js/media-models.js
diff --git src/wp-includes/js/media-models.js src/wp-includes/js/media-models.js index 5363ffe..2580793 100644
window.wp = window.wp || {}; 367 367 368 368 bindAttachmentListeners: function() { 369 369 this.listenTo( this.attachment, 'sync', this.setLinkTypeFromUrl ); 370 this.listenTo( this.attachment, 'change', this.updateSize ); 370 371 }, 371 372 372 373 changeAttachment: function( attachment, props ) { -
src/wp-includes/js/media-views.js
diff --git src/wp-includes/js/media-views.js src/wp-includes/js/media-views.js index db5ea30..6662c73 100644
482 482 }; 483 483 }); 484 484 485 media.selectionSync = { 486 syncSelection: function() { 487 var selection = this.get('selection'), 488 manager = this.frame._selection; 489 490 if ( ! this.get('syncSelection') || ! manager || ! selection ) { 491 return; 492 } 493 494 // If the selection supports multiple items, validate the stored 495 // attachments based on the new selection's conditions. Record 496 // the attachments that are not included; we'll maintain a 497 // reference to those. Other attachments are considered in flux. 498 if ( selection.multiple ) { 499 selection.reset( [], { silent: true }); 500 selection.validateAll( manager.attachments ); 501 manager.difference = _.difference( manager.attachments.models, selection.models ); 502 } 503 504 // Sync the selection's single item with the master. 505 selection.single( manager.single ); 506 }, 507 508 /** 509 * Record the currently active attachments, which is a combination 510 * of the selection's attachments and the set of selected 511 * attachments that this specific selection considered invalid. 512 * Reset the difference and record the single attachment. 513 */ 514 recordSelection: function() { 515 var selection = this.get('selection'), 516 manager = this.frame._selection; 517 518 if ( ! this.get('syncSelection') || ! manager || ! selection ) { 519 return; 520 } 521 522 if ( selection.multiple ) { 523 manager.attachments.reset( selection.toArray().concat( manager.difference ) ); 524 manager.difference = []; 525 } else { 526 manager.attachments.add( selection.toArray() ); 527 } 528 529 manager.single = selection._single; 530 } 531 }; 532 485 533 /** 486 534 * wp.media.controller.Library 487 535 * … … 634 682 return _.contains( media.view.settings.embedExts, attachment.get('filename').split('.').pop() ); 635 683 }, 636 684 637 syncSelection: function() {638 var selection = this.get('selection'),639 manager = this.frame._selection;640 641 if ( ! this.get('syncSelection') || ! manager || ! selection ) {642 return;643 }644 645 // If the selection supports multiple items, validate the stored646 // attachments based on the new selection's conditions. Record647 // the attachments that are not included; we'll maintain a648 // reference to those. Other attachments are considered in flux.649 if ( selection.multiple ) {650 selection.reset( [], { silent: true });651 selection.validateAll( manager.attachments );652 manager.difference = _.difference( manager.attachments.models, selection.models );653 }654 655 // Sync the selection's single item with the master.656 selection.single( manager.single );657 },658 659 /**660 * Record the currently active attachments, which is a combination661 * of the selection's attachments and the set of selected662 * attachments that this specific selection considered invalid.663 * Reset the difference and record the single attachment.664 */665 recordSelection: function() {666 var selection = this.get('selection'),667 manager = this.frame._selection;668 669 if ( ! this.get('syncSelection') || ! manager || ! selection ) {670 return;671 }672 673 if ( selection.multiple ) {674 manager.attachments.reset( selection.toArray().concat( manager.difference ) );675 manager.difference = [];676 } else {677 manager.attachments.add( selection.toArray() );678 }679 680 manager.single = selection._single;681 },682 685 683 686 /** 684 687 * If the state is active, no items are selected, and the current … … 733 736 } 734 737 }); 735 738 739 _.extend( media.controller.Library.prototype, media.selectionSync ); 740 736 741 /** 737 742 * wp.media.controller.ImageDetails 738 743 * … … 1000 1005 toolbar: 'featured-image', 1001 1006 title: l10n.setFeaturedImageTitle, 1002 1007 priority: 60, 1003 syncSelection: false1008 syncSelection: true 1004 1009 }, media.controller.Library.prototype.defaults ), 1005 1010 1006 1011 initialize: function() { … … 1081 1086 toolbar: 'replace', 1082 1087 title: l10n.replaceImageTitle, 1083 1088 priority: 60, 1084 syncSelection: false1089 syncSelection: true 1085 1090 }, media.controller.Library.prototype.defaults ), 1086 1091 1087 1092 initialize: function( options ) { … … 1132 1137 }); 1133 1138 1134 1139 /** 1140 * wp.media.controller.EditImage 1141 * 1142 * @constructor 1143 * @augments wp.media.controller.State 1144 * @augments Backbone.Model 1145 */ 1146 media.controller.EditImage = media.controller.State.extend({ 1147 defaults: { 1148 id: 'edit-image', 1149 url: '', 1150 menu: false, 1151 title: l10n.editImage, 1152 content: 'edit-image', 1153 syncSelection: true 1154 }, 1155 1156 activate: function() { 1157 if ( ! this.get('selection') ) { 1158 this.set( 'selection', new media.model.Selection() ); 1159 } 1160 this.syncSelection(); 1161 } 1162 }); 1163 1164 _.extend( media.controller.EditImage.prototype, media.selectionSync ); 1165 1166 1167 /** 1135 1168 * wp.media.controller.Embed 1136 1169 * 1137 1170 * @constructor … … 1803 1836 // Embed states. 1804 1837 new media.controller.Embed(), 1805 1838 1839 new media.controller.EditImage( { selection: options.selection } ), 1840 1806 1841 // Gallery states. 1807 1842 new media.controller.GalleryEdit({ 1808 1843 library: options.selection, … … 1890 1925 1891 1926 content: { 1892 1927 'embed': 'embedContent', 1928 'edit-image': 'editImageContent', 1893 1929 'edit-selection': 'editSelectionContent' 1894 1930 }, 1895 1931 … … 2040 2076 this.content.set( view ); 2041 2077 }, 2042 2078 2079 editImageContent: function() { 2080 var selection = this.state().get('selection'), 2081 view = new media.view.EditImage( { model: selection.single(), controller: this } ).render(); 2082 2083 this.content.set( view ); 2084 2085 // after bringing in the frame, load the actual editor via an ajax call 2086 view.loadEditor(); 2087 2088 }, 2089 2043 2090 // Toolbars 2044 2091 2045 2092 /** … … 2370 2417 media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); 2371 2418 this.on( 'menu:create:image-details', this.createMenu, this ); 2372 2419 this.on( 'content:render:image-details', this.renderImageDetailsContent, this ); 2420 this.on( 'content:render:edit-image', this.editImageContent, this ); 2373 2421 this.on( 'menu:render:image-details', this.renderMenu, this ); 2374 2422 this.on( 'toolbar:render:image-details', this.renderImageDetailsToolbar, this ); 2375 2423 // override the select toolbar … … 2387 2435 id: 'replace-image', 2388 2436 library: media.query( { type: 'image' } ), 2389 2437 image: this.image, 2438 selection: this.options.selection, 2390 2439 multiple: false, 2391 2440 title: l10n.imageReplaceTitle, 2392 2441 menu: 'image-details', 2393 2442 toolbar: 'replace', 2394 2443 priority: 80, 2395 2444 displaySettings: true 2396 }) 2445 }), 2446 new media.controller.EditImage( { image: this.image, selection: this.options.selection } ) 2397 2447 ]); 2398 2448 }, 2399 2449 … … 2433 2483 2434 2484 }, 2435 2485 2486 editImageContent: function() { 2487 var state = this.state(), 2488 attachment = state.get('image').attachment, 2489 model, 2490 view; 2491 2492 if ( ! attachment ) { 2493 return; 2494 } 2495 2496 model = state.get('selection').single(); 2497 2498 if ( ! model ) { 2499 model = attachment; 2500 } 2501 2502 view = new media.view.EditImage( { model: model, controller: this } ).render(); 2503 2504 this.content.set( view ); 2505 2506 // after bringing in the frame, load the actual editor via an ajax call 2507 view.loadEditor(); 2508 2509 }, 2510 2436 2511 renderImageDetailsToolbar: function() { 2437 2512 this.toolbar.set( new media.view.Toolbar({ 2438 2513 controller: this, … … 5250 5325 } 5251 5326 }, 5252 5327 5253 editAttachment: function() { 5254 this.$el.addClass('needs-refresh'); 5328 editAttachment: function( event ) { 5329 event.preventDefault(); 5330 this.controller.setState( 'edit-image' ); 5255 5331 }, 5256 5332 /** 5257 5333 * @param {Object} event … … 5261 5337 event.preventDefault(); 5262 5338 this.model.fetch(); 5263 5339 } 5340 5264 5341 }); 5265 5342 5266 5343 /** … … 5534 5611 media.view.ImageDetails = media.view.Settings.AttachmentDisplay.extend({ 5535 5612 className: 'image-details', 5536 5613 template: media.template('image-details'), 5537 5614 events: _.defaults( media.view.Settings.AttachmentDisplay.prototype.events, { 5615 'click .edit-attachment': 'editAttachment' 5616 } ), 5538 5617 initialize: function() { 5539 5618 // used in AttachmentDisplay.prototype.updateLinkTo 5540 5619 this.options.attachment = this.model.attachment; 5620 if ( this.model.attachment ) { 5621 this.listenTo( this.model.attachment, 'change:url', this.updateUrl ); 5622 } 5541 5623 media.view.Settings.AttachmentDisplay.prototype.initialize.apply( this, arguments ); 5542 5624 }, 5543 5625 … … 5553 5635 }, this.options ); 5554 5636 }, 5555 5637 5556 5557 5638 render: function() { 5558 5639 var self = this, 5559 5640 args = arguments; … … 5574 5655 resetFocus: function() { 5575 5656 this.$( '.caption textarea' ).focus(); 5576 5657 this.$( '.embed-image-settings' ).scrollTop( 0 ); 5658 }, 5659 5660 updateUrl: function() { 5661 this.$( '.thumbnail img' ).attr( 'src', this.model.get('url' ) ); 5662 this.$( '.url' ).val( this.model.get('url' ) ); 5663 }, 5664 5665 editAttachment: function( event ) { 5666 event.preventDefault(); 5667 this.controller.setState( 'edit-image' ); 5577 5668 } 5578 5669 }); 5670 5671 5672 media.view.EditImage = media.View.extend({ 5673 5674 className: 'image-editor', 5675 template: media.template('image-editor'), 5676 5677 initialize: function( options ) { 5678 this.editor = window.imageEdit; 5679 this.controller = options.controller; 5680 media.View.prototype.initialize.apply( this, arguments ); 5681 }, 5682 5683 prepare: function() { 5684 return this.model.toJSON(); 5685 }, 5686 5687 render: function() { 5688 media.View.prototype.render.apply( this, arguments ); 5689 return this; 5690 }, 5691 5692 loadEditor: function() { 5693 this.editor.open( this.model.get('id'), this.model.get('nonces').edit, this ); 5694 }, 5695 5696 back: function() { 5697 var lastState = this.controller.lastState(); 5698 this.controller.setState( lastState ); 5699 }, 5700 5701 save: function() { 5702 var self = this, 5703 lastState = this.controller.lastState(); 5704 5705 this.model.fetch().done( function() { 5706 self.controller.setState( lastState ); 5707 }); 5708 } 5709 5710 }); 5711 5579 5712 }(jQuery)); -
src/wp-includes/media-template.php
diff --git src/wp-includes/media-template.php src/wp-includes/media-template.php index daf8c29..752502c 100644
function wp_print_media_templates() { 560 560 <div class="thumbnail"> 561 561 <img src="{{ data.model.url }}" draggable="false" /> 562 562 </div> 563 <# if ( data.attachment ) { #> 564 <input type="button" class="edit-attachment button" value="<?php esc_attr_e( 'Edit Image' ); ?>" /> 565 <# } #> 563 566 564 567 <div class="setting url"> 565 568 <?php // might want to make the url editable if it isn't an attachment ?> … … function wp_print_media_templates() { 649 652 </div> 650 653 </div> 651 654 </script> 655 656 <script type="text/html" id="tmpl-image-editor"> 657 <div id="media-head-{{{ data.id }}}"></div> 658 <div id="image-editor-{{{ data.id }}}"></div> 659 </script> 652 660 <?php 653 661 654 662 /** -
src/wp-includes/media.php
diff --git src/wp-includes/media.php src/wp-includes/media.php index ebcfa0e..6b09bc3 100644
function wp_prepare_attachment_for_js( $attachment ) { 2135 2135 'nonces' => array( 2136 2136 'update' => false, 2137 2137 'delete' => false, 2138 'edit' => false 2138 2139 ), 2139 2140 'editLink' => false, 2140 2141 ); 2141 2142 2142 2143 if ( current_user_can( 'edit_post', $attachment->ID ) ) { 2143 2144 $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID ); 2145 $response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID ); 2144 2146 $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' ); 2145 2147 } 2146 2148 … … function wp_enqueue_media( $args = array() ) { 2340 2342 'imageDetailsTitle' => __( 'Image Details' ), 2341 2343 'imageReplaceTitle' => __( 'Replace Image' ), 2342 2344 'imageDetailsCancel' => __( 'Cancel Edit' ), 2345 'editImage' => __( 'Edit Image' ), 2343 2346 2344 2347 // Playlist 2345 2348 'playlistDragInfo' => __( 'Drag and drop to reorder tracks.' ), … … function wp_enqueue_media( $args = array() ) { 2371 2374 2372 2375 wp_enqueue_script( 'media-editor' ); 2373 2376 wp_enqueue_style( 'media-views' ); 2377 wp_enqueue_style( 'imgareaselect' ); 2374 2378 wp_plupload_default_settings(); 2375 2379 2376 2380 require_once ABSPATH . WPINC . '/media-template.php'; … … function theme_supports_thumbnails( $post ) { 2590 2594 } 2591 2595 2592 2596 return current_theme_supports( 'post-thumbnails', $post->post_type ); 2593 } 2594 No newline at end of file 2597 } -
src/wp-includes/script-loader.php
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php index d696b13..a3dc3b7 100644
function wp_default_scripts( &$scripts ) { 395 395 // To enqueue media-views or media-editor, call wp_enqueue_media(). 396 396 // Both rely on numerous settings, styles, and templates to operate correctly. 397 397 $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable' ), false, 1 ); 398 $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 );398 $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views', 'image-edit' ), false, 1 ); 399 399 $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models' ), false, 1 ); 400 400 401 401 if ( is_admin() ) {