[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 /* global getUserSetting, tinymce, QTags, wpActiveEditor */ 2 3 // WordPress, TinyMCE, and Media 4 // ----------------------------- 5 (function($){ 6 // Stores the editors' `wp.media.controller.Frame` instances. 7 var workflows = {}; 8 9 wp.media.string = { 10 // Joins the `props` and `attachment` objects, 11 // outputting the proper object format based on the 12 // attachment's type. 13 props: function( props, attachment ) { 14 var link, linkUrl, size, sizes, fallbacks, 15 defaultProps = wp.media.view.settings.defaultProps; 16 17 // Final fallbacks run after all processing has been completed. 18 fallbacks = function( props ) { 19 // Generate alt fallbacks and strip tags. 20 if ( 'image' === props.type && ! props.alt ) { 21 props.alt = props.caption || props.title || ''; 22 props.alt = props.alt.replace( /<\/?[^>]+>/g, '' ); 23 props.alt = props.alt.replace( /[\r\n]+/g, ' ' ); 24 } 25 26 return props; 27 }; 28 29 props = props ? _.clone( props ) : {}; 30 31 if ( attachment && attachment.type ) 32 props.type = attachment.type; 33 34 if ( 'image' === props.type ) { 35 props = _.defaults( props || {}, { 36 align: defaultProps.align || getUserSetting( 'align', 'none' ), 37 size: defaultProps.size || getUserSetting( 'imgsize', 'medium' ), 38 url: '', 39 classes: [] 40 }); 41 } 42 43 // All attachment-specific settings follow. 44 if ( ! attachment ) 45 return fallbacks( props ); 46 47 props.title = props.title || attachment.title; 48 49 link = props.link || defaultProps.link || getUserSetting( 'urlbutton', 'file' ); 50 if ( 'file' === link || 'embed' === link ) 51 linkUrl = attachment.url; 52 else if ( 'post' === link ) 53 linkUrl = attachment.link; 54 else if ( 'custom' === link ) 55 linkUrl = props.linkUrl; 56 props.linkUrl = linkUrl || ''; 57 58 // Format properties for images. 59 if ( 'image' === attachment.type ) { 60 props.classes.push( 'wp-image-' + attachment.id ); 61 62 sizes = attachment.sizes; 63 size = sizes && sizes[ props.size ] ? sizes[ props.size ] : attachment; 64 65 _.extend( props, _.pick( attachment, 'align', 'caption', 'alt' ), { 66 width: size.width, 67 height: size.height, 68 src: size.url, 69 captionId: 'attachment_' + attachment.id 70 }); 71 } else if ( 'video' === attachment.type || 'audio' === attachment.type ) { 72 _.extend( props, _.pick( attachment, 'title', 'type', 'icon', 'mime' ) ); 73 // Format properties for non-images. 74 } else { 75 props.title = props.title || attachment.filename; 76 props.rel = props.rel || 'attachment wp-att-' + attachment.id; 77 } 78 79 return fallbacks( props ); 80 }, 81 82 link: function( props, attachment ) { 83 var options; 84 85 props = wp.media.string.props( props, attachment ); 86 87 options = { 88 tag: 'a', 89 content: props.title, 90 attrs: { 91 href: props.linkUrl 92 } 93 }; 94 95 if ( props.rel ) 96 options.attrs.rel = props.rel; 97 98 return wp.html.string( options ); 99 }, 100 101 audio: function( props, attachment ) { 102 return wp.media.string._audioVideo( 'audio', props, attachment ); 103 }, 104 105 video: function( props, attachment ) { 106 return wp.media.string._audioVideo( 'video', props, attachment ); 107 }, 108 109 _audioVideo: function( type, props, attachment ) { 110 var shortcode, html, extension; 111 112 props = wp.media.string.props( props, attachment ); 113 if ( props.link !== 'embed' ) 114 return wp.media.string.link( props ); 115 116 shortcode = {}; 117 118 if ( 'video' === type ) { 119 if ( attachment.width ) 120 shortcode.width = attachment.width; 121 122 if ( attachment.height ) 123 shortcode.height = attachment.height; 124 } 125 126 extension = attachment.filename.split('.').pop(); 127 128 if ( _.contains( wp.media.view.settings.embedExts, extension ) ) { 129 shortcode[extension] = attachment.url; 130 } else { 131 // Render unsupported audio and video files as links. 132 return wp.media.string.link( props ); 133 } 134 135 html = wp.shortcode.string({ 136 tag: type, 137 attrs: shortcode 138 }); 139 140 return html; 141 }, 142 143 image: function( props, attachment ) { 144 var img = {}, 145 options, classes, shortcode, html; 146 147 props = wp.media.string.props( props, attachment ); 148 classes = props.classes || []; 149 150 img.src = typeof attachment !== 'undefined' ? attachment.url : props.url; 151 _.extend( img, _.pick( props, 'width', 'height', 'alt' ) ); 152 153 // Only assign the align class to the image if we're not printing 154 // a caption, since the alignment is sent to the shortcode. 155 if ( props.align && ! props.caption ) 156 classes.push( 'align' + props.align ); 157 158 if ( props.size ) 159 classes.push( 'size-' + props.size ); 160 161 img['class'] = _.compact( classes ).join(' '); 162 163 // Generate `img` tag options. 164 options = { 165 tag: 'img', 166 attrs: img, 167 single: true 168 }; 169 170 // Generate the `a` element options, if they exist. 171 if ( props.linkUrl ) { 172 options = { 173 tag: 'a', 174 attrs: { 175 href: props.linkUrl 176 }, 177 content: options 178 }; 179 } 180 181 html = wp.html.string( options ); 182 183 // Generate the caption shortcode. 184 if ( props.caption ) { 185 shortcode = {}; 186 187 if ( img.width ) 188 shortcode.width = img.width; 189 190 if ( props.captionId ) 191 shortcode.id = props.captionId; 192 193 if ( props.align ) 194 shortcode.align = 'align' + props.align; 195 196 html = wp.shortcode.string({ 197 tag: 'caption', 198 attrs: shortcode, 199 content: html + ' ' + props.caption 200 }); 201 } 202 203 return html; 204 } 205 }; 206 207 wp.media.gallery = (function() { 208 var galleries = {}; 209 210 return { 211 defaults: { 212 order: 'ASC', 213 id: wp.media.view.settings.post.id, 214 itemtag: 'dl', 215 icontag: 'dt', 216 captiontag: 'dd', 217 columns: '3', 218 link: 'post', 219 size: 'thumbnail', 220 orderby: 'menu_order ID' 221 }, 222 223 attachments: function( shortcode ) { 224 var shortcodeString = shortcode.string(), 225 result = galleries[ shortcodeString ], 226 attrs, args, query, others; 227 228 delete galleries[ shortcodeString ]; 229 230 if ( result ) 231 return result; 232 233 // Fill the default shortcode attributes. 234 attrs = _.defaults( shortcode.attrs.named, wp.media.gallery.defaults ); 235 args = _.pick( attrs, 'orderby', 'order' ); 236 237 args.type = 'image'; 238 args.perPage = -1; 239 240 // Mark the `orderby` override attribute. 241 if( undefined !== attrs.orderby ) 242 attrs._orderByField = attrs.orderby; 243 244 if ( 'rand' === attrs.orderby ) 245 attrs._orderbyRandom = true; 246 247 // Map the `orderby` attribute to the corresponding model property. 248 if ( ! attrs.orderby || /^menu_order(?: ID)?$/i.test( attrs.orderby ) ) 249 args.orderby = 'menuOrder'; 250 251 // Map the `ids` param to the correct query args. 252 if ( attrs.ids ) { 253 args.post__in = attrs.ids.split(','); 254 args.orderby = 'post__in'; 255 } else if ( attrs.include ) { 256 args.post__in = attrs.include.split(','); 257 } 258 259 if ( attrs.exclude ) 260 args.post__not_in = attrs.exclude.split(','); 261 262 if ( ! args.post__in ) 263 args.uploadedTo = attrs.id; 264 265 // Collect the attributes that were not included in `args`. 266 others = _.omit( attrs, 'id', 'ids', 'include', 'exclude', 'orderby', 'order' ); 267 268 query = wp.media.query( args ); 269 query.gallery = new Backbone.Model( others ); 270 return query; 271 }, 272 273 shortcode: function( attachments ) { 274 var props = attachments.props.toJSON(), 275 attrs = _.pick( props, 'orderby', 'order' ), 276 shortcode, clone; 277 278 if ( attachments.gallery ) 279 _.extend( attrs, attachments.gallery.toJSON() ); 280 281 // Convert all gallery shortcodes to use the `ids` property. 282 // Ignore `post__in` and `post__not_in`; the attachments in 283 // the collection will already reflect those properties. 284 attrs.ids = attachments.pluck('id'); 285 286 // Copy the `uploadedTo` post ID. 287 if ( props.uploadedTo ) 288 attrs.id = props.uploadedTo; 289 290 // Check if the gallery is randomly ordered. 291 delete attrs.orderby; 292 293 if ( attrs._orderbyRandom ) 294 attrs.orderby = 'rand'; 295 else if ( attrs._orderByField && attrs._orderByField != 'rand' ) 296 attrs.orderby = attrs._orderByField; 297 298 delete attrs._orderbyRandom; 299 delete attrs._orderByField; 300 301 // If the `ids` attribute is set and `orderby` attribute 302 // is the default value, clear it for cleaner output. 303 if ( attrs.ids && 'post__in' === attrs.orderby ) 304 delete attrs.orderby; 305 306 // Remove default attributes from the shortcode. 307 _.each( wp.media.gallery.defaults, function( value, key ) { 308 if ( value === attrs[ key ] ) 309 delete attrs[ key ]; 310 }); 311 312 shortcode = new wp.shortcode({ 313 tag: 'gallery', 314 attrs: attrs, 315 type: 'single' 316 }); 317 318 // Use a cloned version of the gallery. 319 clone = new wp.media.model.Attachments( attachments.models, { 320 props: props 321 }); 322 clone.gallery = attachments.gallery; 323 galleries[ shortcode.string() ] = clone; 324 325 return shortcode; 326 }, 327 328 edit: function( content ) { 329 var shortcode = wp.shortcode.next( 'gallery', content ), 330 defaultPostId = wp.media.gallery.defaults.id, 331 attachments, selection; 332 333 // Bail if we didn't match the shortcode or all of the content. 334 if ( ! shortcode || shortcode.content !== content ) 335 return; 336 337 // Ignore the rest of the match object. 338 shortcode = shortcode.shortcode; 339 340 if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) ) 341 shortcode.set( 'id', defaultPostId ); 342 343 attachments = wp.media.gallery.attachments( shortcode ); 344 345 selection = new wp.media.model.Selection( attachments.models, { 346 props: attachments.props.toJSON(), 347 multiple: true 348 }); 349 350 selection.gallery = attachments.gallery; 351 352 // Fetch the query's attachments, and then break ties from the 353 // query to allow for sorting. 354 selection.more().done( function() { 355 // Break ties with the query. 356 selection.props.set({ query: false }); 357 selection.unmirror(); 358 selection.props.unset('orderby'); 359 }); 360 361 // Destroy the previous gallery frame. 362 if ( this.frame ) 363 this.frame.dispose(); 364 365 // Store the current gallery frame. 366 this.frame = wp.media({ 367 frame: 'post', 368 state: 'gallery-edit', 369 title: wp.media.view.l10n.editGalleryTitle, 370 editing: true, 371 multiple: true, 372 selection: selection 373 }).open(); 374 375 return this.frame; 376 } 377 }; 378 }()); 379 380 wp.media.featuredImage = { 381 get: function() { 382 return wp.media.view.settings.post.featuredImageId; 383 }, 384 385 set: function( id ) { 386 var settings = wp.media.view.settings; 387 388 settings.post.featuredImageId = id; 389 390 wp.media.post( 'set-post-thumbnail', { 391 json: true, 392 post_id: settings.post.id, 393 thumbnail_id: settings.post.featuredImageId, 394 _wpnonce: settings.post.nonce 395 }).done( function( html ) { 396 $( '.inside', '#postimagediv' ).html( html ); 397 }); 398 }, 399 400 frame: function() { 401 if ( this._frame ) 402 return this._frame; 403 404 this._frame = wp.media({ 405 state: 'featured-image', 406 states: [ new wp.media.controller.FeaturedImage() ] 407 }); 408 409 this._frame.on( 'toolbar:create:featured-image', function( toolbar ) { 410 this.createSelectToolbar( toolbar, { 411 text: wp.media.view.l10n.setFeaturedImage 412 }); 413 }, this._frame ); 414 415 this._frame.state('featured-image').on( 'select', this.select ); 416 return this._frame; 417 }, 418 419 select: function() { 420 var settings = wp.media.view.settings, 421 selection = this.get('selection').single(); 422 423 if ( ! settings.post.featuredImageId ) 424 return; 425 426 wp.media.featuredImage.set( selection ? selection.id : -1 ); 427 }, 428 429 init: function() { 430 // Open the content media manager to the 'featured image' tab when 431 // the post thumbnail is clicked. 432 $('#postimagediv').on( 'click', '#set-post-thumbnail', function( event ) { 433 event.preventDefault(); 434 // Stop propagation to prevent thickbox from activating. 435 event.stopPropagation(); 436 437 wp.media.featuredImage.frame().open(); 438 439 // Update the featured image id when the 'remove' link is clicked. 440 }).on( 'click', '#remove-post-thumbnail', function() { 441 wp.media.view.settings.post.featuredImageId = -1; 442 }); 443 } 444 }; 445 446 $( wp.media.featuredImage.init ); 447 448 wp.media.editor = { 449 insert: function( h ) { 450 var mce = typeof(tinymce) != 'undefined', 451 qt = typeof(QTags) != 'undefined', 452 wpActiveEditor = window.wpActiveEditor, 453 ed; 454 455 // Delegate to the global `send_to_editor` if it exists. 456 // This attempts to play nice with any themes/plugins that have 457 // overridden the insert functionality. 458 if ( window.send_to_editor ) 459 return window.send_to_editor.apply( this, arguments ); 460 461 if ( ! wpActiveEditor ) { 462 if ( mce && tinymce.activeEditor ) { 463 ed = tinymce.activeEditor; 464 wpActiveEditor = window.wpActiveEditor = ed.id; 465 } else if ( !qt ) { 466 return false; 467 } 468 } else if ( mce ) { 469 if ( tinymce.activeEditor && (tinymce.activeEditor.id == 'mce_fullscreen' || tinymce.activeEditor.id == 'wp_mce_fullscreen') ) 470 ed = tinymce.activeEditor; 471 else 472 ed = tinymce.get(wpActiveEditor); 473 } 474 475 if ( ed && !ed.isHidden() ) { 476 // restore caret position on IE 477 if ( tinymce.isIE && ed.windowManager.insertimagebookmark ) 478 ed.selection.moveToBookmark(ed.windowManager.insertimagebookmark); 479 480 if ( h.indexOf('[caption') !== -1 ) { 481 if ( ed.wpSetImgCaption ) 482 h = ed.wpSetImgCaption(h); 483 } else if ( h.indexOf('[gallery') !== -1 ) { 484 if ( ed.plugins.wpgallery ) 485 h = ed.plugins.wpgallery._do_gallery(h); 486 } else if ( h.indexOf('[embed') === 0 ) { 487 if ( ed.plugins.wordpress ) 488 h = ed.plugins.wordpress._setEmbed(h); 489 } 490 491 ed.execCommand('mceInsertContent', false, h); 492 } else if ( qt ) { 493 QTags.insertContent(h); 494 } else { 495 document.getElementById(wpActiveEditor).value += h; 496 } 497 498 // If the old thickbox remove function exists, call it in case 499 // a theme/plugin overloaded it. 500 if ( window.tb_remove ) 501 try { window.tb_remove(); } catch( e ) {} 502 }, 503 504 add: function( id, options ) { 505 var workflow = this.get( id ); 506 507 if ( workflow ) // only add once: if exists return existing 508 return workflow; 509 510 workflow = workflows[ id ] = wp.media( _.defaults( options || {}, { 511 frame: 'post', 512 state: 'insert', 513 title: wp.media.view.l10n.addMedia, 514 multiple: true 515 } ) ); 516 517 workflow.on( 'insert', function( selection ) { 518 var state = workflow.state(); 519 520 selection = selection || state.get('selection'); 521 522 if ( ! selection ) 523 return; 524 525 $.when.apply( $, selection.map( function( attachment ) { 526 var display = state.display( attachment ).toJSON(); 527 return this.send.attachment( display, attachment.toJSON() ); 528 }, this ) ).done( function() { 529 wp.media.editor.insert( _.toArray( arguments ).join('\n\n') ); 530 }); 531 }, this ); 532 533 workflow.state('gallery-edit').on( 'update', function( selection ) { 534 this.insert( wp.media.gallery.shortcode( selection ).string() ); 535 }, this ); 536 537 workflow.state('embed').on( 'select', function() { 538 var state = workflow.state(), 539 type = state.get('type'), 540 embed = state.props.toJSON(); 541 542 embed.url = embed.url || ''; 543 544 if ( 'link' === type ) { 545 _.defaults( embed, { 546 title: embed.url, 547 linkUrl: embed.url 548 }); 549 550 this.send.link( embed ).done( function( resp ) { 551 wp.media.editor.insert( resp ); 552 }); 553 554 } else if ( 'image' === type ) { 555 _.defaults( embed, { 556 title: embed.url, 557 linkUrl: '', 558 align: 'none', 559 link: 'none' 560 }); 561 562 if ( 'none' === embed.link ) 563 embed.linkUrl = ''; 564 else if ( 'file' === embed.link ) 565 embed.linkUrl = embed.url; 566 567 this.insert( wp.media.string.image( embed ) ); 568 } 569 }, this ); 570 571 workflow.state('featured-image').on( 'select', wp.media.featuredImage.select ); 572 workflow.setState( workflow.options.state ); 573 return workflow; 574 }, 575 576 id: function( id ) { 577 if ( id ) 578 return id; 579 580 // If an empty `id` is provided, default to `wpActiveEditor`. 581 id = wpActiveEditor; 582 583 // If that doesn't work, fall back to `tinymce.activeEditor.id`. 584 if ( ! id && typeof tinymce !== 'undefined' && tinymce.activeEditor ) 585 id = tinymce.activeEditor.id; 586 587 // Last but not least, fall back to the empty string. 588 id = id || ''; 589 return id; 590 }, 591 592 get: function( id ) { 593 id = this.id( id ); 594 return workflows[ id ]; 595 }, 596 597 remove: function( id ) { 598 id = this.id( id ); 599 delete workflows[ id ]; 600 }, 601 602 send: { 603 attachment: function( props, attachment ) { 604 var caption = attachment.caption, 605 options, html; 606 607 // If captions are disabled, clear the caption. 608 if ( ! wp.media.view.settings.captions ) 609 delete attachment.caption; 610 611 props = wp.media.string.props( props, attachment ); 612 613 options = { 614 id: attachment.id, 615 post_content: attachment.description, 616 post_excerpt: caption 617 }; 618 619 if ( props.linkUrl ) 620 options.url = props.linkUrl; 621 622 if ( 'image' === attachment.type ) { 623 html = wp.media.string.image( props ); 624 625 _.each({ 626 align: 'align', 627 size: 'image-size', 628 alt: 'image_alt' 629 }, function( option, prop ) { 630 if ( props[ prop ] ) 631 options[ option ] = props[ prop ]; 632 }); 633 } else if ( 'video' === attachment.type ) { 634 html = wp.media.string.video( props, attachment ); 635 } else if ( 'audio' === attachment.type ) { 636 html = wp.media.string.audio( props, attachment ); 637 } else { 638 html = wp.media.string.link( props ); 639 options.post_title = props.title; 640 } 641 642 return wp.media.post( 'send-attachment-to-editor', { 643 nonce: wp.media.view.settings.nonce.sendToEditor, 644 attachment: options, 645 html: html, 646 post_id: wp.media.view.settings.post.id 647 }); 648 }, 649 650 link: function( embed ) { 651 return wp.media.post( 'send-link-to-editor', { 652 nonce: wp.media.view.settings.nonce.sendToEditor, 653 src: embed.linkUrl, 654 title: embed.title, 655 html: wp.media.string.link( embed ), 656 post_id: wp.media.view.settings.post.id 657 }); 658 } 659 }, 660 661 open: function( id, options ) { 662 var workflow, editor; 663 664 options = options || {}; 665 666 id = this.id( id ); 667 668 // Save a bookmark of the caret position in IE. 669 if ( typeof tinymce !== 'undefined' ) { 670 editor = tinymce.get( id ); 671 672 if ( tinymce.isIE && editor && ! editor.isHidden() ) { 673 editor.focus(); 674 editor.windowManager.insertimagebookmark = editor.selection.getBookmark(); 675 } 676 } 677 678 workflow = this.get( id ); 679 680 // Redo workflow if state has changed 681 if ( ! workflow || ( workflow.options && options.state !== workflow.options.state ) ) 682 workflow = this.add( id, options ); 683 684 return workflow.open(); 685 }, 686 687 init: function() { 688 $(document.body).on( 'click', '.insert-media', function( event ) { 689 var $this = $(this), 690 editor = $this.data('editor'), 691 options = { 692 frame: 'post', 693 state: 'insert', 694 title: wp.media.view.l10n.addMedia, 695 multiple: true 696 }; 697 698 event.preventDefault(); 699 700 // Remove focus from the `.insert-media` button. 701 // Prevents Opera from showing the outline of the button 702 // above the modal. 703 // 704 // See: http://core.trac.wordpress.org/ticket/22445 705 $this.blur(); 706 707 if ( $this.hasClass( 'gallery' ) ) { 708 options.state = 'gallery'; 709 options.title = wp.media.view.l10n.createGalleryTitle; 710 } 711 712 wp.media.editor.open( editor, options ); 713 }); 714 } 715 }; 716 717 _.bindAll( wp.media.editor, 'open' ); 718 $( wp.media.editor.init ); 719 }(jQuery));
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |