357 | | toView: wp.mce.gallery.toView, |
| 354 | |
| 355 | View: _.extend( {}, wp.media.mixin, { |
| 356 | initialize: function( options ) { |
| 357 | this.players = []; |
| 358 | this.shortcode = options.shortcode; |
| 359 | _.bindAll( this, 'setPlayer', 'pausePlayers' ); |
| 360 | $( this ).on( 'ready', this.setPlayer ); |
| 361 | $( 'body' ).on( 'click', '.wp-switch-editor', this.pausePlayers ); |
| 362 | $( document ).on( 'media:edit', this.pausePlayers ); |
| 363 | }, |
| 364 | |
| 365 | /** |
| 366 | * Creates the player instance for the current node |
| 367 | * |
| 368 | * @global MediaElementPlayer |
| 369 | * @global _wpmejsSettings |
| 370 | * |
| 371 | * @param {Event} e |
| 372 | * @param {HTMLElement} node |
| 373 | */ |
| 374 | setPlayer: function(e, node) { |
| 375 | // if the ready event fires on an empty node |
| 376 | if ( ! node ) { |
| 377 | return; |
| 378 | } |
| 379 | |
| 380 | var self = this, |
| 381 | media, |
| 382 | firefox = this.ua.is( 'ff' ), |
| 383 | className = '.wp-' + this.shortcode.tag + '-shortcode'; |
| 384 | |
| 385 | media = $( node ).find( className ); |
| 386 | |
| 387 | if ( ! this.isCompatible( media ) ) { |
| 388 | media.closest( '.wpview-wrap' ).addClass( 'wont-play' ); |
| 389 | if ( ! media.parent().hasClass( 'wpview-wrap' ) ) { |
| 390 | media.parent().replaceWith( media ); |
| 391 | } |
| 392 | media.replaceWith( '<p>' + media.find( 'source' ).eq(0).prop( 'src' ) + '</p>' ); |
| 393 | return; |
| 394 | } else { |
| 395 | media.closest( '.wpview-wrap' ).removeClass( 'wont-play' ); |
| 396 | if ( firefox ) { |
| 397 | media.prop( 'preload', 'metadata' ); |
| 398 | } else { |
| 399 | media.prop( 'preload', 'none' ); |
| 400 | } |
| 401 | } |
| 402 | |
| 403 | media = wp.media.view.MediaDetails.prepareSrc( media.get(0) ); |
| 404 | |
| 405 | setTimeout( function() { |
| 406 | wp.mce.av.loaded = true; |
| 407 | self.players.push( new MediaElementPlayer( media, self.mejsSettings ) ); |
| 408 | }, wp.mce.av.loaded ? 10 : 500 ); |
| 409 | }, |
| 410 | |
| 411 | /** |
| 412 | * Pass data to the View's Underscore template and return the compiled output |
| 413 | * |
| 414 | * @returns {string} |
| 415 | */ |
| 416 | getHtml: function() { |
| 417 | var attrs = this.shortcode.attrs.named; |
| 418 | attrs.content = this.shortcode.content; |
| 419 | |
| 420 | return this.template({ model: _.defaults( |
| 421 | attrs, |
| 422 | wp.media[ this.shortcode.tag ].defaults ) |
| 423 | }); |
| 424 | }, |
| 425 | |
| 426 | unbind: function() { |
| 427 | this.unsetPlayers(); |
| 428 | } |
| 429 | } ), |
400 | | * Base View class for audio and video shortcodes |
401 | | * |
402 | | * @constructor |
403 | | * @augments wp.mce.View |
404 | | * @mixes wp.media.mixin |
405 | | */ |
406 | | wp.mce.media.View = wp.mce.View.extend({ |
407 | | initialize: function( options ) { |
408 | | this.players = []; |
409 | | this.shortcode = options.shortcode; |
410 | | _.bindAll( this, 'setPlayer', 'pausePlayers' ); |
411 | | $( this ).on( 'ready', this.setPlayer ); |
412 | | $( 'body' ).on( 'click', '.wp-switch-editor', this.pausePlayers ); |
413 | | $( document ).on( 'media:edit', this.pausePlayers ); |
414 | | }, |
415 | | |
416 | | /** |
417 | | * Creates the player instance for the current node |
418 | | * |
419 | | * @global MediaElementPlayer |
420 | | * @global _wpmejsSettings |
421 | | * |
422 | | * @param {Event} e |
423 | | * @param {HTMLElement} node |
424 | | */ |
425 | | setPlayer: function(e, node) { |
426 | | // if the ready event fires on an empty node |
427 | | if ( ! node ) { |
428 | | return; |
429 | | } |
430 | | |
431 | | var self = this, |
432 | | media, |
433 | | firefox = this.ua.is( 'ff' ), |
434 | | className = '.wp-' + this.shortcode.tag + '-shortcode'; |
435 | | |
436 | | media = $( node ).find( className ); |
437 | | |
438 | | if ( ! this.isCompatible( media ) ) { |
439 | | media.closest( '.wpview-wrap' ).addClass( 'wont-play' ); |
440 | | if ( ! media.parent().hasClass( 'wpview-wrap' ) ) { |
441 | | media.parent().replaceWith( media ); |
442 | | } |
443 | | media.replaceWith( '<p>' + media.find( 'source' ).eq(0).prop( 'src' ) + '</p>' ); |
444 | | return; |
445 | | } else { |
446 | | media.closest( '.wpview-wrap' ).removeClass( 'wont-play' ); |
447 | | if ( firefox ) { |
448 | | media.prop( 'preload', 'metadata' ); |
449 | | } else { |
450 | | media.prop( 'preload', 'none' ); |
451 | | } |
452 | | } |
453 | | |
454 | | media = wp.media.view.MediaDetails.prepareSrc( media.get(0) ); |
455 | | |
456 | | setTimeout( function() { |
457 | | wp.mce.media.loaded = true; |
458 | | self.players.push( new MediaElementPlayer( media, self.mejsSettings ) ); |
459 | | }, wp.mce.media.loaded ? 10 : 500 ); |
460 | | }, |
461 | | |
462 | | /** |
463 | | * Pass data to the View's Underscore template and return the compiled output |
464 | | * |
465 | | * @returns {string} |
466 | | */ |
467 | | getHtml: function() { |
468 | | var attrs = this.shortcode.attrs.named; |
469 | | attrs.content = this.shortcode.content; |
470 | | |
471 | | return this.template({ model: _.defaults( |
472 | | attrs, |
473 | | wp.media[ this.shortcode.tag ].defaults ) |
474 | | }); |
475 | | }, |
476 | | |
477 | | unbind: function() { |
478 | | this.unsetPlayers(); |
479 | | } |
480 | | }); |
481 | | _.extend( wp.mce.media.View.prototype, wp.media.mixin ); |
482 | | |
483 | | /** |
520 | | wp.mce.media.PlaylistView = wp.mce.View.extend({ |
521 | | className: 'editor-playlist', |
522 | | template: media.template('editor-playlist'), |
523 | | |
524 | | initialize: function( options ) { |
525 | | this.players = []; |
526 | | this.data = {}; |
527 | | this.attachments = []; |
528 | | this.shortcode = options.shortcode; |
529 | | |
530 | | $( 'body' ).on( 'click', '.wp-switch-editor', this.pausePlayers ); |
531 | | $( document ).on( 'media:edit', this.pausePlayers ); |
532 | | |
533 | | this.fetch(); |
534 | | }, |
535 | | |
536 | | /** |
537 | | * Asynchronously fetch the shortcode's attachments |
538 | | */ |
539 | | fetch: function() { |
540 | | this.attachments = wp.media.playlist.attachments( this.shortcode ); |
541 | | this.dfd = this.attachments.more().done( _.bind( this.render, this ) ); |
542 | | }, |
543 | | |
544 | | /** |
545 | | * Get the HTML for the view (which also set's the data), replace the |
546 | | * current HTML, and then invoke the WPPlaylistView instance to render |
547 | | * the playlist in the editor |
548 | | * |
549 | | * @global WPPlaylistView |
550 | | * @global tinymce.editors |
551 | | */ |
552 | | render: function() { |
553 | | var html = this.getHtml(), self = this; |
554 | | |
555 | | _.each( tinymce.editors, function( editor ) { |
556 | | var doc; |
557 | | if ( editor.plugins.wpview ) { |
558 | | doc = editor.getDoc(); |
559 | | $( doc ).find( '[data-wpview-text="' + this.encodedText + '"]' ).each(function (i, elem) { |
560 | | var node = $( elem ); |
561 | | |
562 | | // The <ins> is used to mark the end of the wrapper div. Needed when comparing |
563 | | // the content as string for preventing extra undo levels. |
564 | | node.html( html ).append( '<ins data-wpview-end="1"></ins>' ); |
565 | | |
566 | | if ( ! self.data.tracks ) { |
567 | | return; |
568 | | } |
569 | | |
570 | | self.players.push( new WPPlaylistView({ |
571 | | el: $( elem ).find( '.wp-playlist' ).get(0), |
572 | | metadata: self.data |
573 | | }).player ); |
574 | | }); |
| 500 | wp.mce.views.register( 'playlist', _.extend( {}, wp.mce.av, { |
| 501 | state: ['playlist-edit', 'video-playlist-edit'], |
| 502 | View: _.extend( {}, wp.media.mixin, { |
| 503 | template: media.template( 'editor-playlist' ), |
| 504 | |
| 505 | initialize: function( options ) { |
| 506 | this.players = []; |
| 507 | this.data = {}; |
| 508 | this.attachments = []; |
| 509 | this.shortcode = options.shortcode; |
| 510 | |
| 511 | $( 'body' ).on( 'click', '.wp-switch-editor', this.pausePlayers ); |
| 512 | $( document ).on( 'media:edit', this.pausePlayers ); |
| 513 | |
| 514 | this.fetch(); |
| 515 | |
| 516 | $( this ).on( 'ready', this.setPlaylist ); |
| 517 | }, |
| 518 | |
| 519 | /** |
| 520 | * Asynchronously fetch the shortcode's attachments |
| 521 | */ |
| 522 | fetch: function() { |
| 523 | this.attachments = wp.media.playlist.attachments( this.shortcode ); |
| 524 | this.dfd = this.attachments.more().done( _.bind( this.render, this ) ); |
| 525 | }, |
| 526 | |
| 527 | setPlaylist: function( event, element ) { |
| 528 | if ( ! this.data.tracks ) { |
| 529 | return; |
576 | | }, this ); |
577 | | }, |
578 | | |
579 | | /** |
580 | | * Set the data that will be used to compile the Underscore template, |
581 | | * compile the template, and then return it. |
582 | | * |
583 | | * @returns {string} |
584 | | */ |
585 | | getHtml: function() { |
586 | | var data = this.shortcode.attrs.named, |
587 | | model = wp.media.playlist, |
588 | | options, |
589 | | attachments, |
590 | | tracks = []; |
591 | | |
592 | | // Don't render errors while still fetching attachments |
593 | | if ( this.dfd && 'pending' === this.dfd.state() && ! this.attachments.length ) { |
594 | | return; |
595 | | } |
596 | | |
597 | | _.each( model.defaults, function( value, key ) { |
598 | | data[ key ] = model.coerce( data, key ); |
599 | | }); |
600 | | |
601 | | options = { |
602 | | type: data.type, |
603 | | style: data.style, |
604 | | tracklist: data.tracklist, |
605 | | tracknumbers: data.tracknumbers, |
606 | | images: data.images, |
607 | | artists: data.artists |
608 | | }; |
609 | | |
610 | | if ( ! this.attachments.length ) { |
611 | | return this.template( options ); |
612 | | } |
613 | | |
614 | | attachments = this.attachments.toJSON(); |
615 | | |
616 | | _.each( attachments, function( attachment ) { |
617 | | var size = {}, resize = {}, track = { |
618 | | src : attachment.url, |
619 | | type : attachment.mime, |
620 | | title : attachment.title, |
621 | | caption : attachment.caption, |
622 | | description : attachment.description, |
623 | | meta : attachment.meta |
| 531 | |
| 532 | this.players.push( new WPPlaylistView( { |
| 533 | el: $( element ).find( '.wp-playlist' ).get( 0 ), |
| 534 | metadata: this.data |
| 535 | } ).player ); |
| 536 | }, |
| 537 | |
| 538 | /** |
| 539 | * Set the data that will be used to compile the Underscore template, |
| 540 | * compile the template, and then return it. |
| 541 | * |
| 542 | * @returns {string} |
| 543 | */ |
| 544 | getHtml: function() { |
| 545 | var data = this.shortcode.attrs.named, |
| 546 | model = wp.media.playlist, |
| 547 | options, |
| 548 | attachments, |
| 549 | tracks = []; |
| 550 | |
| 551 | // Don't render errors while still fetching attachments |
| 552 | if ( this.dfd && 'pending' === this.dfd.state() && ! this.attachments.length ) { |
| 553 | return; |
| 554 | } |
| 555 | |
| 556 | _.each( model.defaults, function( value, key ) { |
| 557 | data[ key ] = model.coerce( data, key ); |
| 558 | }); |
| 559 | |
| 560 | options = { |
| 561 | type: data.type, |
| 562 | style: data.style, |
| 563 | tracklist: data.tracklist, |
| 564 | tracknumbers: data.tracknumbers, |
| 565 | images: data.images, |
| 566 | artists: data.artists |
625 | | |
626 | | if ( 'video' === data.type ) { |
627 | | size.width = attachment.width; |
628 | | size.height = attachment.height; |
629 | | if ( media.view.settings.contentWidth ) { |
630 | | resize.width = media.view.settings.contentWidth - 22; |
631 | | resize.height = Math.ceil( ( size.height * resize.width ) / size.width ); |
632 | | if ( ! options.width ) { |
633 | | options.width = resize.width; |
634 | | options.height = resize.height; |
| 568 | |
| 569 | if ( ! this.attachments.length ) { |
| 570 | return this.template( options ); |
| 571 | } |
| 572 | |
| 573 | attachments = this.attachments.toJSON(); |
| 574 | |
| 575 | _.each( attachments, function( attachment ) { |
| 576 | var size = {}, resize = {}, track = { |
| 577 | src : attachment.url, |
| 578 | type : attachment.mime, |
| 579 | title : attachment.title, |
| 580 | caption : attachment.caption, |
| 581 | description : attachment.description, |
| 582 | meta : attachment.meta |
| 583 | }; |
| 584 | |
| 585 | if ( 'video' === data.type ) { |
| 586 | size.width = attachment.width; |
| 587 | size.height = attachment.height; |
| 588 | if ( media.view.settings.contentWidth ) { |
| 589 | resize.width = media.view.settings.contentWidth - 22; |
| 590 | resize.height = Math.ceil( ( size.height * resize.width ) / size.width ); |
| 591 | if ( ! options.width ) { |
| 592 | options.width = resize.width; |
| 593 | options.height = resize.height; |
| 594 | } |
| 595 | } else { |
| 596 | if ( ! options.width ) { |
| 597 | options.width = attachment.width; |
| 598 | options.height = attachment.height; |
| 599 | } |
642 | | track.dimensions = { |
643 | | original : size, |
644 | | resized : _.isEmpty( resize ) ? size : resize |
645 | | }; |
646 | | } else { |
647 | | options.width = 400; |
648 | | } |
649 | | |
650 | | track.image = attachment.image; |
651 | | track.thumb = attachment.thumb; |
652 | | |
653 | | tracks.push( track ); |
654 | | } ); |
655 | | |
656 | | options.tracks = tracks; |
657 | | this.data = options; |
658 | | |
659 | | return this.template( options ); |
660 | | }, |
661 | | |
662 | | unbind: function() { |
663 | | this.unsetPlayers(); |
664 | | } |
665 | | }); |
666 | | _.extend( wp.mce.media.PlaylistView.prototype, wp.media.mixin ); |
667 | | |
668 | | /** |
669 | | * TinyMCE handler for the playlist shortcode |
670 | | * |
671 | | * @mixes wp.mce.media |
672 | | */ |
673 | | wp.mce.playlist = _.extend( {}, wp.mce.media, { |
674 | | shortcode: 'playlist', |
675 | | state: ['playlist-edit', 'video-playlist-edit'], |
676 | | View: wp.mce.media.PlaylistView |
677 | | } ); |
678 | | wp.mce.views.register( 'playlist', wp.mce.playlist ); |
| 608 | |
| 609 | track.image = attachment.image; |
| 610 | track.thumb = attachment.thumb; |
| 611 | |
| 612 | tracks.push( track ); |
| 613 | } ); |
| 614 | |
| 615 | options.tracks = tracks; |
| 616 | this.data = options; |
| 617 | |
| 618 | return this.template( options ); |
| 619 | }, |
| 620 | |
| 621 | unbind: function() { |
| 622 | this.unsetPlayers(); |
| 623 | } |
| 624 | } ) |
| 625 | } ) ); |