Ticket #26870: 26870-media-editor.diff
File 26870-media-editor.diff, 16.7 KB (added by , 11 years ago) |
---|
-
src/wp-includes/js/media-editor.js
3 3 // WordPress, TinyMCE, and Media 4 4 // ----------------------------- 5 5 (function($){ 6 // Stores the editors' `wp.media.controller.Frame` instances. 6 /** 7 * Stores the editors' `wp.media.controller.Frame` instances. 8 * 9 * @static 10 */ 7 11 var workflows = {}; 8 12 13 /** 14 * wp.media.string 15 */ 9 16 wp.media.string = { 10 // Joins the `props` and `attachment` objects, 11 // outputting the proper object format based on the 12 // attachment's type. 17 /** 18 * Joins the `props` and `attachment` objects, 19 * outputting the proper object format based on the 20 * attachment's type. 21 * 22 * @global wp.media.view.settings.defaultProps 23 * 24 * @param {Object} props 25 * @param {Object} attachment 26 * @returns {Object} Joined props 27 */ 13 28 props: function( props, attachment ) { 14 29 var link, linkUrl, size, sizes, fallbacks, 15 30 defaultProps = wp.media.view.settings.defaultProps; … … 28 43 29 44 props = props ? _.clone( props ) : {}; 30 45 31 if ( attachment && attachment.type ) 46 if ( attachment && attachment.type ) { 32 47 props.type = attachment.type; 48 } 33 49 34 50 if ( 'image' === props.type ) { 35 51 props = _.defaults( props || {}, { … … 41 57 } 42 58 43 59 // All attachment-specific settings follow. 44 if ( ! attachment ) 60 if ( ! attachment ) { 45 61 return fallbacks( props ); 62 } 46 63 47 64 props.title = props.title || attachment.title; 48 65 49 66 link = props.link || defaultProps.link || getUserSetting( 'urlbutton', 'file' ); 50 if ( 'file' === link || 'embed' === link ) 67 if ( 'file' === link || 'embed' === link ) { 51 68 linkUrl = attachment.url; 52 else if ( 'post' === link )69 } else if ( 'post' === link ) { 53 70 linkUrl = attachment.link; 54 else if ( 'custom' === link )71 } else if ( 'custom' === link ) { 55 72 linkUrl = props.linkUrl; 73 } 56 74 props.linkUrl = linkUrl || ''; 57 75 58 76 // Format properties for images. … … 79 97 return fallbacks( props ); 80 98 }, 81 99 100 /** 101 * Create the markup for a link 102 * 103 * @global wp.html.string 104 * 105 * @param {Object} props 106 * @param {Object} attachment 107 * @returns {string} The link markup 108 */ 82 109 link: function( props, attachment ) { 83 110 var options; 84 111 … … 92 119 } 93 120 }; 94 121 95 if ( props.rel ) 122 if ( props.rel ) { 96 123 options.attrs.rel = props.rel; 124 } 97 125 98 126 return wp.html.string( options ); 99 127 }, 100 128 /** 129 * Create an Audio shortcode 130 * 131 * @param {Object} props 132 * @param {Object} attachment 133 * @returns {string} The audio shortcode 134 */ 101 135 audio: function( props, attachment ) { 102 136 return wp.media.string._audioVideo( 'audio', props, attachment ); 103 137 }, 104 138 /** 139 * Create a Video shortcode 140 * 141 * @param {Object} props 142 * @param {Object} attachment 143 * @returns {string} The video shortcode 144 */ 105 145 video: function( props, attachment ) { 106 146 return wp.media.string._audioVideo( 'video', props, attachment ); 107 147 }, 108 148 /** 149 * Helper function to create a media shortcode 150 * 151 * @access private 152 * 153 * @global wp.shortcode 154 * @global wp.media.view.settings 155 * 156 * @param {string} type The shortcode tag name: 'audio' or 'video'. 157 * @param {Object} props 158 * @param {Object} attachment 159 * @returns {string} The media shortcode 160 */ 109 161 _audioVideo: function( type, props, attachment ) { 110 162 var shortcode, html, extension; 111 163 … … 116 168 shortcode = {}; 117 169 118 170 if ( 'video' === type ) { 119 if ( attachment.width ) 171 if ( attachment.width ) { 120 172 shortcode.width = attachment.width; 173 } 121 174 122 if ( attachment.height ) 175 if ( attachment.height ) { 123 176 shortcode.height = attachment.height; 177 } 124 178 } 125 179 126 180 extension = attachment.filename.split('.').pop(); … … 139 193 140 194 return html; 141 195 }, 142 196 /** 197 * Create image markup, optionally with a link and/or wrapped in a caption shortcode 198 * 199 * @global wp.html 200 * @global wp.shortcode 201 * 202 * @param {Object} props 203 * @param {Object} attachment 204 * @returns {string} 205 */ 143 206 image: function( props, attachment ) { 144 207 var img = {}, 145 208 options, classes, shortcode, html; … … 152 215 153 216 // Only assign the align class to the image if we're not printing 154 217 // a caption, since the alignment is sent to the shortcode. 155 if ( props.align && ! props.caption ) 218 if ( props.align && ! props.caption ) { 156 219 classes.push( 'align' + props.align ); 220 } 157 221 158 if ( props.size ) 222 if ( props.size ) { 159 223 classes.push( 'size-' + props.size ); 224 } 160 225 161 226 img['class'] = _.compact( classes ).join(' '); 162 227 … … 184 249 if ( props.caption ) { 185 250 shortcode = {}; 186 251 187 if ( img.width ) 252 if ( img.width ) { 188 253 shortcode.width = img.width; 254 } 189 255 190 if ( props.captionId ) 256 if ( props.captionId ) { 191 257 shortcode.id = props.captionId; 258 } 192 259 193 if ( props.align ) 260 if ( props.align ) { 194 261 shortcode.align = 'align' + props.align; 262 } 195 263 196 264 html = wp.shortcode.string({ 197 265 tag: 'caption', … … 204 272 } 205 273 }; 206 274 275 /** 276 * wp.media.gallery 277 * 278 * @type {Object} 279 */ 207 280 wp.media.gallery = (function() { 281 /** 282 * 283 * @static 284 * @type object 285 */ 208 286 var galleries = {}; 209 287 210 288 return { 289 /** 290 * @global wp.media.view.settings 291 */ 211 292 defaults: { 212 293 order: 'ASC', 213 294 id: wp.media.view.settings.post.id, … … 220 301 orderby: 'menu_order ID' 221 302 }, 222 303 304 /** 305 * @global wp.media.query 306 * 307 * @param {Object} shortcode 308 * @returns {Object} 309 */ 223 310 attachments: function( shortcode ) { 224 311 var shortcodeString = shortcode.string(), 225 312 result = galleries[ shortcodeString ], … … 227 314 228 315 delete galleries[ shortcodeString ]; 229 316 230 if ( result ) 317 if ( result ) { 231 318 return result; 319 } 232 320 233 321 // Fill the default shortcode attributes. 234 322 attrs = _.defaults( shortcode.attrs.named, wp.media.gallery.defaults ); … … 238 326 args.perPage = -1; 239 327 240 328 // Mark the `orderby` override attribute. 241 if( undefined !== attrs.orderby ) 329 if( undefined !== attrs.orderby ) { 242 330 attrs._orderByField = attrs.orderby; 243 244 if ( 'rand' === attrs.orderby ) 331 } 332 if ( 'rand' === attrs.orderby ) { 245 333 attrs._orderbyRandom = true; 334 } 246 335 247 336 // Map the `orderby` attribute to the corresponding model property. 248 if ( ! attrs.orderby || /^menu_order(?: ID)?$/i.test( attrs.orderby ) ) 337 if ( ! attrs.orderby || /^menu_order(?: ID)?$/i.test( attrs.orderby ) ) { 249 338 args.orderby = 'menuOrder'; 339 } 250 340 251 341 // Map the `ids` param to the correct query args. 252 342 if ( attrs.ids ) { … … 256 346 args.post__in = attrs.include.split(','); 257 347 } 258 348 259 if ( attrs.exclude ) 349 if ( attrs.exclude ) { 260 350 args.post__not_in = attrs.exclude.split(','); 351 } 261 352 262 if ( ! args.post__in ) 353 if ( ! args.post__in ) { 263 354 args.uploadedTo = attrs.id; 355 } 264 356 265 357 // Collect the attributes that were not included in `args`. 266 358 others = _.omit( attrs, 'id', 'ids', 'include', 'exclude', 'orderby', 'order' ); … … 270 362 return query; 271 363 }, 272 364 365 /** 366 * @global wp.shortcode 367 * @global wp.media.model.Attachments 368 * 369 * @param {Object} attachments 370 * @returns {wp.shortcode} 371 */ 273 372 shortcode: function( attachments ) { 274 373 var props = attachments.props.toJSON(), 275 374 attrs = _.pick( props, 'orderby', 'order' ), 276 375 shortcode, clone; 277 376 278 if ( attachments.gallery ) 377 if ( attachments.gallery ) { 279 378 _.extend( attrs, attachments.gallery.toJSON() ); 379 } 280 380 281 381 // Convert all gallery shortcodes to use the `ids` property. 282 382 // Ignore `post__in` and `post__not_in`; the attachments in … … 284 384 attrs.ids = attachments.pluck('id'); 285 385 286 386 // Copy the `uploadedTo` post ID. 287 if ( props.uploadedTo ) 387 if ( props.uploadedTo ) { 288 388 attrs.id = props.uploadedTo; 389 } 289 390 290 391 // Check if the gallery is randomly ordered. 291 392 delete attrs.orderby; 292 393 293 if ( attrs._orderbyRandom ) 394 if ( attrs._orderbyRandom ) { 294 395 attrs.orderby = 'rand'; 295 else if ( attrs._orderByField && attrs._orderByField != 'rand' )396 } else if ( attrs._orderByField && attrs._orderByField != 'rand' ) { 296 397 attrs.orderby = attrs._orderByField; 398 } 297 399 298 400 delete attrs._orderbyRandom; 299 401 delete attrs._orderByField; 300 402 301 403 // If the `ids` attribute is set and `orderby` attribute 302 404 // is the default value, clear it for cleaner output. 303 if ( attrs.ids && 'post__in' === attrs.orderby ) 405 if ( attrs.ids && 'post__in' === attrs.orderby ) { 304 406 delete attrs.orderby; 407 } 305 408 306 409 // Remove default attributes from the shortcode. 307 410 _.each( wp.media.gallery.defaults, function( value, key ) { … … 324 427 325 428 return shortcode; 326 429 }, 327 430 /** 431 * @global wp.shortcode 432 * @global wp.media.model.Selection 433 * @global wp.media.view.l10n 434 * 435 * @param {string} content 436 * @returns {wp.media.view.MediaFrame} A media workflow. 437 */ 328 438 edit: function( content ) { 329 439 var shortcode = wp.shortcode.next( 'gallery', content ), 330 440 defaultPostId = wp.media.gallery.defaults.id, 331 441 attachments, selection; 332 442 333 443 // Bail if we didn't match the shortcode or all of the content. 334 if ( ! shortcode || shortcode.content !== content ) 444 if ( ! shortcode || shortcode.content !== content ) { 335 445 return; 446 } 336 447 337 448 // Ignore the rest of the match object. 338 449 shortcode = shortcode.shortcode; 339 450 340 if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) ) 451 if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) ) { 341 452 shortcode.set( 'id', defaultPostId ); 453 } 342 454 343 455 attachments = wp.media.gallery.attachments( shortcode ); 344 456 … … 359 471 }); 360 472 361 473 // Destroy the previous gallery frame. 362 if ( this.frame ) 474 if ( this.frame ) { 363 475 this.frame.dispose(); 476 } 364 477 365 478 // Store the current gallery frame. 366 479 this.frame = wp.media({ … … 377 490 }; 378 491 }()); 379 492 493 /** 494 * wp.media.featuredImage 495 */ 380 496 wp.media.featuredImage = { 497 /** 498 * Get the featured image post ID 499 * 500 * @global wp.media.view.settings 501 * 502 * @returns {wp.media.view.settings.post.featuredImageId|Number} 503 */ 381 504 get: function() { 382 505 return wp.media.view.settings.post.featuredImageId; 383 506 }, 384 507 508 /** 509 * Set the featured image id, save the post thumbnail data and 510 * set the HTML in the post meta box to the new featured image. 511 * 512 * @global wp.media.view.settings 513 * @global wp.media.post 514 * 515 * @param {number} id 516 */ 385 517 set: function( id ) { 386 518 var settings = wp.media.view.settings; 387 519 … … 396 528 $( '.inside', '#postimagediv' ).html( html ); 397 529 }); 398 530 }, 399 531 /** 532 * The Featured Image workflow 533 * 534 * @global wp.media.controller.FeaturedImage 535 * @global wp.media.view.l10n 536 * 537 * @returns {wp.media.view.MediaFrame} A media workflow. 538 */ 400 539 frame: function() { 401 if ( this._frame ) 540 if ( this._frame ) { 402 541 return this._frame; 542 } 403 543 404 544 this._frame = wp.media({ 405 545 state: 'featured-image', … … 415 555 this._frame.state('featured-image').on( 'select', this.select ); 416 556 return this._frame; 417 557 }, 418 558 /** 559 * @global wp.media.view.settings 560 */ 419 561 select: function() { 420 562 var settings = wp.media.view.settings, 421 563 selection = this.get('selection').single(); 422 564 423 if ( ! settings.post.featuredImageId ) 565 if ( ! settings.post.featuredImageId ) { 424 566 return; 567 } 425 568 426 569 wp.media.featuredImage.set( selection ? selection.id : -1 ); 427 570 }, 428 571 572 /** 573 * Open the content media manager to the 'featured image' tab when 574 * the post thumbnail is clicked. 575 * 576 * Update the featured image id when the 'remove' link is clicked. 577 * 578 * @global wp.media.view.settings 579 */ 429 580 init: function() { 430 // Open the content media manager to the 'featured image' tab when431 // the post thumbnail is clicked.432 581 $('#postimagediv').on( 'click', '#set-post-thumbnail', function( event ) { 433 582 event.preventDefault(); 434 583 // Stop propagation to prevent thickbox from activating. 435 584 event.stopPropagation(); 436 585 437 586 wp.media.featuredImage.frame().open(); 438 439 // Update the featured image id when the 'remove' link is clicked.440 587 }).on( 'click', '#remove-post-thumbnail', function() { 441 588 wp.media.view.settings.post.featuredImageId = -1; 442 589 }); … … 445 592 446 593 $( wp.media.featuredImage.init ); 447 594 595 /** 596 * wp.media.editor 597 */ 448 598 wp.media.editor = { 599 /** 600 * @global tinymce 601 * @global QTags 602 * 603 * @param {string} html 604 */ 449 605 insert: function( html ) { 450 606 var editor, 451 607 hasTinymce = typeof tinymce !== 'undefined', … … 485 641 } 486 642 }, 487 643 644 /** 645 * @global wp.media.view.l10n 646 * 647 * @param {string} id A slug used to identify the workflow. 648 * @param {Object} [options={}] 649 * 650 * @returns {wp.media.view.MediaFrame} A media workflow. 651 */ 488 652 add: function( id, options ) { 489 653 var workflow = this.get( id ); 490 654 491 if ( workflow ) // only add once: if exists return existing 655 // only add once: if exists return existing 656 if ( workflow ) { 492 657 return workflow; 658 } 493 659 494 660 workflow = workflows[ id ] = wp.media( _.defaults( options || {}, { 495 661 frame: 'post', … … 543 709 link: 'none' 544 710 }); 545 711 546 if ( 'none' === embed.link ) 712 if ( 'none' === embed.link ) { 547 713 embed.linkUrl = ''; 548 else if ( 'file' === embed.link )714 } else if ( 'file' === embed.link ) { 549 715 embed.linkUrl = embed.url; 716 } 550 717 551 718 this.insert( wp.media.string.image( embed ) ); 552 719 } … … 557 724 return workflow; 558 725 }, 559 726 727 /** 728 * Determines the proper current workflow id 729 * 730 * @global wpActiveEditor 731 * @global tinymce 732 * 733 * @param {string} id 734 * @returns {wpActiveEditor|String|tinymce.activeEditor.id} 735 */ 560 736 id: function( id ) { 561 if ( id ) 737 if ( id ) { 562 738 return id; 739 } 563 740 564 741 // If an empty `id` is provided, default to `wpActiveEditor`. 565 742 id = wpActiveEditor; 566 743 567 744 // If that doesn't work, fall back to `tinymce.activeEditor.id`. 568 if ( ! id && typeof tinymce !== 'undefined' && tinymce.activeEditor ) 745 if ( ! id && typeof tinymce !== 'undefined' && tinymce.activeEditor ) { 569 746 id = tinymce.activeEditor.id; 747 } 570 748 571 749 // Last but not least, fall back to the empty string. 572 750 id = id || ''; 573 751 return id; 574 752 }, 575 753 /** 754 * Return the workflow specified by id 755 * 756 * @param {string} id 757 * @returns {wp.media.view.MediaFrame} A media workflow. 758 */ 576 759 get: function( id ) { 577 760 id = this.id( id ); 578 761 return workflows[ id ]; 579 762 }, 580 763 /** 764 * Remove the workflow represented by id from the workflow cache 765 * 766 * @param {string} id 767 */ 581 768 remove: function( id ) { 582 769 id = this.id( id ); 583 770 delete workflows[ id ]; 584 771 }, 585 772 586 773 send: { 774 /** 775 * @global wp.media.view.settings 776 * @global wp.media.post 777 * 778 * @param {Object} props 779 * @param {Object} attachment 780 * @returns {Promise} 781 */ 587 782 attachment: function( props, attachment ) { 588 783 var caption = attachment.caption, 589 784 options, html; 590 785 591 786 // If captions are disabled, clear the caption. 592 if ( ! wp.media.view.settings.captions ) 787 if ( ! wp.media.view.settings.captions ) { 593 788 delete attachment.caption; 789 } 594 790 595 791 props = wp.media.string.props( props, attachment ); 596 792 … … 600 796 post_excerpt: caption 601 797 }; 602 798 603 if ( props.linkUrl ) 799 if ( props.linkUrl ) { 604 800 options.url = props.linkUrl; 801 } 605 802 606 803 if ( 'image' === attachment.type ) { 607 804 html = wp.media.string.image( props ); … … 630 827 post_id: wp.media.view.settings.post.id 631 828 }); 632 829 }, 633 830 /** 831 * @global wp.media.view.settings 832 * 833 * @param {Object} embed 834 * @returns {Promise} 835 */ 634 836 link: function( embed ) { 635 837 return wp.media.post( 'send-link-to-editor', { 636 838 nonce: wp.media.view.settings.nonce.sendToEditor, … … 641 843 }); 642 844 } 643 845 }, 644 846 /** 847 * @param {string} id 848 * @param {Object} options 849 * @returns {wp.media.view.MediaFrame} 850 */ 645 851 open: function( id, options ) { 646 852 var workflow, editor; 647 853 … … 662 868 workflow = this.get( id ); 663 869 664 870 // Redo workflow if state has changed 665 if ( ! workflow || ( workflow.options && options.state !== workflow.options.state ) ) 871 if ( ! workflow || ( workflow.options && options.state !== workflow.options.state ) ) { 666 872 workflow = this.add( id, options ); 873 } 667 874 668 875 return workflow.open(); 669 876 }, 670 877 878 /** 879 * Bind click event for .insert-media using event delegation 880 * 881 * @global wp.media.view.l10n 882 */ 671 883 init: function() { 672 884 $(document.body).on( 'click', '.insert-media', function( event ) { 673 885 var $this = $(this),