]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/js/media-audiovideo.js
Wordpress 4.5.3
[autoinstalls/wordpress.git] / wp-includes / js / media-audiovideo.js
1 (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2 var media = wp.media,
3         baseSettings = window._wpmejsSettings || {},
4         l10n = window._wpMediaViewsL10n || {};
5
6 /**
7  * @mixin
8  */
9 wp.media.mixin = {
10         mejsSettings: baseSettings,
11
12         removeAllPlayers: function() {
13                 var p;
14
15                 if ( window.mejs && window.mejs.players ) {
16                         for ( p in window.mejs.players ) {
17                                 window.mejs.players[p].pause();
18                                 this.removePlayer( window.mejs.players[p] );
19                         }
20                 }
21         },
22
23         /**
24          * Override the MediaElement method for removing a player.
25          *      MediaElement tries to pull the audio/video tag out of
26          *      its container and re-add it to the DOM.
27          */
28         removePlayer: function(t) {
29                 var featureIndex, feature;
30
31                 if ( ! t.options ) {
32                         return;
33                 }
34
35                 // invoke features cleanup
36                 for ( featureIndex in t.options.features ) {
37                         feature = t.options.features[featureIndex];
38                         if ( t['clean' + feature] ) {
39                                 try {
40                                         t['clean' + feature](t);
41                                 } catch (e) {}
42                         }
43                 }
44
45                 if ( ! t.isDynamic ) {
46                         t.$node.remove();
47                 }
48
49                 if ( 'native' !== t.media.pluginType ) {
50                         t.$media.remove();
51                 }
52
53                 delete window.mejs.players[t.id];
54
55                 t.container.remove();
56                 t.globalUnbind();
57                 delete t.node.player;
58         },
59
60         /**
61          * Allows any class that has set 'player' to a MediaElementPlayer
62          *  instance to remove the player when listening to events.
63          *
64          *  Examples: modal closes, shortcode properties are removed, etc.
65          */
66         unsetPlayers : function() {
67                 if ( this.players && this.players.length ) {
68                         _.each( this.players, function (player) {
69                                 player.pause();
70                                 wp.media.mixin.removePlayer( player );
71                         } );
72                         this.players = [];
73                 }
74         }
75 };
76
77 /**
78  * Autowire "collection"-type shortcodes
79  */
80 wp.media.playlist = new wp.media.collection({
81         tag: 'playlist',
82         editTitle : l10n.editPlaylistTitle,
83         defaults : {
84                 id: wp.media.view.settings.post.id,
85                 style: 'light',
86                 tracklist: true,
87                 tracknumbers: true,
88                 images: true,
89                 artists: true,
90                 type: 'audio'
91         }
92 });
93
94 /**
95  * Shortcode modeling for audio
96  *  `edit()` prepares the shortcode for the media modal
97  *  `shortcode()` builds the new shortcode after update
98  *
99  * @namespace
100  */
101 wp.media.audio = {
102         coerce : wp.media.coerce,
103
104         defaults : {
105                 id : wp.media.view.settings.post.id,
106                 src : '',
107                 loop : false,
108                 autoplay : false,
109                 preload : 'none',
110                 width : 400
111         },
112
113         edit : function( data ) {
114                 var frame, shortcode = wp.shortcode.next( 'audio', data ).shortcode;
115
116                 frame = wp.media({
117                         frame: 'audio',
118                         state: 'audio-details',
119                         metadata: _.defaults( shortcode.attrs.named, this.defaults )
120                 });
121
122                 return frame;
123         },
124
125         shortcode : function( model ) {
126                 var content;
127
128                 _.each( this.defaults, function( value, key ) {
129                         model[ key ] = this.coerce( model, key );
130
131                         if ( value === model[ key ] ) {
132                                 delete model[ key ];
133                         }
134                 }, this );
135
136                 content = model.content;
137                 delete model.content;
138
139                 return new wp.shortcode({
140                         tag: 'audio',
141                         attrs: model,
142                         content: content
143                 });
144         }
145 };
146
147 /**
148  * Shortcode modeling for video
149  *  `edit()` prepares the shortcode for the media modal
150  *  `shortcode()` builds the new shortcode after update
151  *
152  * @namespace
153  */
154 wp.media.video = {
155         coerce : wp.media.coerce,
156
157         defaults : {
158                 id : wp.media.view.settings.post.id,
159                 src : '',
160                 poster : '',
161                 loop : false,
162                 autoplay : false,
163                 preload : 'metadata',
164                 content : '',
165                 width : 640,
166                 height : 360
167         },
168
169         edit : function( data ) {
170                 var frame,
171                         shortcode = wp.shortcode.next( 'video', data ).shortcode,
172                         attrs;
173
174                 attrs = shortcode.attrs.named;
175                 attrs.content = shortcode.content;
176
177                 frame = wp.media({
178                         frame: 'video',
179                         state: 'video-details',
180                         metadata: _.defaults( attrs, this.defaults )
181                 });
182
183                 return frame;
184         },
185
186         shortcode : function( model ) {
187                 var content;
188
189                 _.each( this.defaults, function( value, key ) {
190                         model[ key ] = this.coerce( model, key );
191
192                         if ( value === model[ key ] ) {
193                                 delete model[ key ];
194                         }
195                 }, this );
196
197                 content = model.content;
198                 delete model.content;
199
200                 return new wp.shortcode({
201                         tag: 'video',
202                         attrs: model,
203                         content: content
204                 });
205         }
206 };
207
208 media.model.PostMedia = require( './models/post-media.js' );
209 media.controller.AudioDetails = require( './controllers/audio-details.js' );
210 media.controller.VideoDetails = require( './controllers/video-details.js' );
211 media.view.MediaFrame.MediaDetails = require( './views/frame/media-details.js' );
212 media.view.MediaFrame.AudioDetails = require( './views/frame/audio-details.js' );
213 media.view.MediaFrame.VideoDetails = require( './views/frame/video-details.js' );
214 media.view.MediaDetails = require( './views/media-details.js' );
215 media.view.AudioDetails = require( './views/audio-details.js' );
216 media.view.VideoDetails = require( './views/video-details.js' );
217
218 },{"./controllers/audio-details.js":2,"./controllers/video-details.js":3,"./models/post-media.js":4,"./views/audio-details.js":5,"./views/frame/audio-details.js":6,"./views/frame/media-details.js":7,"./views/frame/video-details.js":8,"./views/media-details.js":9,"./views/video-details.js":10}],2:[function(require,module,exports){
219 /**
220  * wp.media.controller.AudioDetails
221  *
222  * The controller for the Audio Details state
223  *
224  * @class
225  * @augments wp.media.controller.State
226  * @augments Backbone.Model
227  */
228 var State = wp.media.controller.State,
229         l10n = wp.media.view.l10n,
230         AudioDetails;
231
232 AudioDetails = State.extend({
233         defaults: {
234                 id: 'audio-details',
235                 toolbar: 'audio-details',
236                 title: l10n.audioDetailsTitle,
237                 content: 'audio-details',
238                 menu: 'audio-details',
239                 router: false,
240                 priority: 60
241         },
242
243         initialize: function( options ) {
244                 this.media = options.media;
245                 State.prototype.initialize.apply( this, arguments );
246         }
247 });
248
249 module.exports = AudioDetails;
250
251 },{}],3:[function(require,module,exports){
252 /**
253  * wp.media.controller.VideoDetails
254  *
255  * The controller for the Video Details state
256  *
257  * @class
258  * @augments wp.media.controller.State
259  * @augments Backbone.Model
260  */
261 var State = wp.media.controller.State,
262         l10n = wp.media.view.l10n,
263         VideoDetails;
264
265 VideoDetails = State.extend({
266         defaults: {
267                 id: 'video-details',
268                 toolbar: 'video-details',
269                 title: l10n.videoDetailsTitle,
270                 content: 'video-details',
271                 menu: 'video-details',
272                 router: false,
273                 priority: 60
274         },
275
276         initialize: function( options ) {
277                 this.media = options.media;
278                 State.prototype.initialize.apply( this, arguments );
279         }
280 });
281
282 module.exports = VideoDetails;
283
284 },{}],4:[function(require,module,exports){
285 /**
286  * wp.media.model.PostMedia
287  *
288  * Shared model class for audio and video. Updates the model after
289  *   "Add Audio|Video Source" and "Replace Audio|Video" states return
290  *
291  * @class
292  * @augments Backbone.Model
293  */
294 var PostMedia = Backbone.Model.extend({
295         initialize: function() {
296                 this.attachment = false;
297         },
298
299         setSource: function( attachment ) {
300                 this.attachment = attachment;
301                 this.extension = attachment.get( 'filename' ).split('.').pop();
302
303                 if ( this.get( 'src' ) && this.extension === this.get( 'src' ).split('.').pop() ) {
304                         this.unset( 'src' );
305                 }
306
307                 if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
308                         this.set( this.extension, this.attachment.get( 'url' ) );
309                 } else {
310                         this.unset( this.extension );
311                 }
312         },
313
314         changeAttachment: function( attachment ) {
315                 this.setSource( attachment );
316
317                 this.unset( 'src' );
318                 _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function( ext ) {
319                         this.unset( ext );
320                 }, this );
321         }
322 });
323
324 module.exports = PostMedia;
325
326 },{}],5:[function(require,module,exports){
327 /**
328  * wp.media.view.AudioDetails
329  *
330  * @class
331  * @augments wp.media.view.MediaDetails
332  * @augments wp.media.view.Settings.AttachmentDisplay
333  * @augments wp.media.view.Settings
334  * @augments wp.media.View
335  * @augments wp.Backbone.View
336  * @augments Backbone.View
337  */
338 var MediaDetails = wp.media.view.MediaDetails,
339         AudioDetails;
340
341 AudioDetails = MediaDetails.extend({
342         className: 'audio-details',
343         template:  wp.template('audio-details'),
344
345         setMedia: function() {
346                 var audio = this.$('.wp-audio-shortcode');
347
348                 if ( audio.find( 'source' ).length ) {
349                         if ( audio.is(':hidden') ) {
350                                 audio.show();
351                         }
352                         this.media = MediaDetails.prepareSrc( audio.get(0) );
353                 } else {
354                         audio.hide();
355                         this.media = false;
356                 }
357
358                 return this;
359         }
360 });
361
362 module.exports = AudioDetails;
363
364 },{}],6:[function(require,module,exports){
365 /**
366  * wp.media.view.MediaFrame.AudioDetails
367  *
368  * @class
369  * @augments wp.media.view.MediaFrame.MediaDetails
370  * @augments wp.media.view.MediaFrame.Select
371  * @augments wp.media.view.MediaFrame
372  * @augments wp.media.view.Frame
373  * @augments wp.media.View
374  * @augments wp.Backbone.View
375  * @augments Backbone.View
376  * @mixes wp.media.controller.StateMachine
377  */
378 var MediaDetails = wp.media.view.MediaFrame.MediaDetails,
379         MediaLibrary = wp.media.controller.MediaLibrary,
380
381         l10n = wp.media.view.l10n,
382         AudioDetails;
383
384 AudioDetails = MediaDetails.extend({
385         defaults: {
386                 id:      'audio',
387                 url:     '',
388                 menu:    'audio-details',
389                 content: 'audio-details',
390                 toolbar: 'audio-details',
391                 type:    'link',
392                 title:    l10n.audioDetailsTitle,
393                 priority: 120
394         },
395
396         initialize: function( options ) {
397                 options.DetailsView = wp.media.view.AudioDetails;
398                 options.cancelText = l10n.audioDetailsCancel;
399                 options.addText = l10n.audioAddSourceTitle;
400
401                 MediaDetails.prototype.initialize.call( this, options );
402         },
403
404         bindHandlers: function() {
405                 MediaDetails.prototype.bindHandlers.apply( this, arguments );
406
407                 this.on( 'toolbar:render:replace-audio', this.renderReplaceToolbar, this );
408                 this.on( 'toolbar:render:add-audio-source', this.renderAddSourceToolbar, this );
409         },
410
411         createStates: function() {
412                 this.states.add([
413                         new wp.media.controller.AudioDetails( {
414                                 media: this.media
415                         } ),
416
417                         new MediaLibrary( {
418                                 type: 'audio',
419                                 id: 'replace-audio',
420                                 title: l10n.audioReplaceTitle,
421                                 toolbar: 'replace-audio',
422                                 media: this.media,
423                                 menu: 'audio-details'
424                         } ),
425
426                         new MediaLibrary( {
427                                 type: 'audio',
428                                 id: 'add-audio-source',
429                                 title: l10n.audioAddSourceTitle,
430                                 toolbar: 'add-audio-source',
431                                 media: this.media,
432                                 menu: false
433                         } )
434                 ]);
435         }
436 });
437
438 module.exports = AudioDetails;
439
440 },{}],7:[function(require,module,exports){
441 /**
442  * wp.media.view.MediaFrame.MediaDetails
443  *
444  * @class
445  * @augments wp.media.view.MediaFrame.Select
446  * @augments wp.media.view.MediaFrame
447  * @augments wp.media.view.Frame
448  * @augments wp.media.View
449  * @augments wp.Backbone.View
450  * @augments Backbone.View
451  * @mixes wp.media.controller.StateMachine
452  */
453 var Select = wp.media.view.MediaFrame.Select,
454         l10n = wp.media.view.l10n,
455         MediaDetails;
456
457 MediaDetails = Select.extend({
458         defaults: {
459                 id:      'media',
460                 url:     '',
461                 menu:    'media-details',
462                 content: 'media-details',
463                 toolbar: 'media-details',
464                 type:    'link',
465                 priority: 120
466         },
467
468         initialize: function( options ) {
469                 this.DetailsView = options.DetailsView;
470                 this.cancelText = options.cancelText;
471                 this.addText = options.addText;
472
473                 this.media = new wp.media.model.PostMedia( options.metadata );
474                 this.options.selection = new wp.media.model.Selection( this.media.attachment, { multiple: false } );
475                 Select.prototype.initialize.apply( this, arguments );
476         },
477
478         bindHandlers: function() {
479                 var menu = this.defaults.menu;
480
481                 Select.prototype.bindHandlers.apply( this, arguments );
482
483                 this.on( 'menu:create:' + menu, this.createMenu, this );
484                 this.on( 'content:render:' + menu, this.renderDetailsContent, this );
485                 this.on( 'menu:render:' + menu, this.renderMenu, this );
486                 this.on( 'toolbar:render:' + menu, this.renderDetailsToolbar, this );
487         },
488
489         renderDetailsContent: function() {
490                 var view = new this.DetailsView({
491                         controller: this,
492                         model: this.state().media,
493                         attachment: this.state().media.attachment
494                 }).render();
495
496                 this.content.set( view );
497         },
498
499         renderMenu: function( view ) {
500                 var lastState = this.lastState(),
501                         previous = lastState && lastState.id,
502                         frame = this;
503
504                 view.set({
505                         cancel: {
506                                 text:     this.cancelText,
507                                 priority: 20,
508                                 click:    function() {
509                                         if ( previous ) {
510                                                 frame.setState( previous );
511                                         } else {
512                                                 frame.close();
513                                         }
514                                 }
515                         },
516                         separateCancel: new wp.media.View({
517                                 className: 'separator',
518                                 priority: 40
519                         })
520                 });
521
522         },
523
524         setPrimaryButton: function(text, handler) {
525                 this.toolbar.set( new wp.media.view.Toolbar({
526                         controller: this,
527                         items: {
528                                 button: {
529                                         style:    'primary',
530                                         text:     text,
531                                         priority: 80,
532                                         click:    function() {
533                                                 var controller = this.controller;
534                                                 handler.call( this, controller, controller.state() );
535                                                 // Restore and reset the default state.
536                                                 controller.setState( controller.options.state );
537                                                 controller.reset();
538                                         }
539                                 }
540                         }
541                 }) );
542         },
543
544         renderDetailsToolbar: function() {
545                 this.setPrimaryButton( l10n.update, function( controller, state ) {
546                         controller.close();
547                         state.trigger( 'update', controller.media.toJSON() );
548                 } );
549         },
550
551         renderReplaceToolbar: function() {
552                 this.setPrimaryButton( l10n.replace, function( controller, state ) {
553                         var attachment = state.get( 'selection' ).single();
554                         controller.media.changeAttachment( attachment );
555                         state.trigger( 'replace', controller.media.toJSON() );
556                 } );
557         },
558
559         renderAddSourceToolbar: function() {
560                 this.setPrimaryButton( this.addText, function( controller, state ) {
561                         var attachment = state.get( 'selection' ).single();
562                         controller.media.setSource( attachment );
563                         state.trigger( 'add-source', controller.media.toJSON() );
564                 } );
565         }
566 });
567
568 module.exports = MediaDetails;
569
570 },{}],8:[function(require,module,exports){
571 /**
572  * wp.media.view.MediaFrame.VideoDetails
573  *
574  * @class
575  * @augments wp.media.view.MediaFrame.MediaDetails
576  * @augments wp.media.view.MediaFrame.Select
577  * @augments wp.media.view.MediaFrame
578  * @augments wp.media.view.Frame
579  * @augments wp.media.View
580  * @augments wp.Backbone.View
581  * @augments Backbone.View
582  * @mixes wp.media.controller.StateMachine
583  */
584 var MediaDetails = wp.media.view.MediaFrame.MediaDetails,
585         MediaLibrary = wp.media.controller.MediaLibrary,
586         l10n = wp.media.view.l10n,
587         VideoDetails;
588
589 VideoDetails = MediaDetails.extend({
590         defaults: {
591                 id:      'video',
592                 url:     '',
593                 menu:    'video-details',
594                 content: 'video-details',
595                 toolbar: 'video-details',
596                 type:    'link',
597                 title:    l10n.videoDetailsTitle,
598                 priority: 120
599         },
600
601         initialize: function( options ) {
602                 options.DetailsView = wp.media.view.VideoDetails;
603                 options.cancelText = l10n.videoDetailsCancel;
604                 options.addText = l10n.videoAddSourceTitle;
605
606                 MediaDetails.prototype.initialize.call( this, options );
607         },
608
609         bindHandlers: function() {
610                 MediaDetails.prototype.bindHandlers.apply( this, arguments );
611
612                 this.on( 'toolbar:render:replace-video', this.renderReplaceToolbar, this );
613                 this.on( 'toolbar:render:add-video-source', this.renderAddSourceToolbar, this );
614                 this.on( 'toolbar:render:select-poster-image', this.renderSelectPosterImageToolbar, this );
615                 this.on( 'toolbar:render:add-track', this.renderAddTrackToolbar, this );
616         },
617
618         createStates: function() {
619                 this.states.add([
620                         new wp.media.controller.VideoDetails({
621                                 media: this.media
622                         }),
623
624                         new MediaLibrary( {
625                                 type: 'video',
626                                 id: 'replace-video',
627                                 title: l10n.videoReplaceTitle,
628                                 toolbar: 'replace-video',
629                                 media: this.media,
630                                 menu: 'video-details'
631                         } ),
632
633                         new MediaLibrary( {
634                                 type: 'video',
635                                 id: 'add-video-source',
636                                 title: l10n.videoAddSourceTitle,
637                                 toolbar: 'add-video-source',
638                                 media: this.media,
639                                 menu: false
640                         } ),
641
642                         new MediaLibrary( {
643                                 type: 'image',
644                                 id: 'select-poster-image',
645                                 title: l10n.videoSelectPosterImageTitle,
646                                 toolbar: 'select-poster-image',
647                                 media: this.media,
648                                 menu: 'video-details'
649                         } ),
650
651                         new MediaLibrary( {
652                                 type: 'text',
653                                 id: 'add-track',
654                                 title: l10n.videoAddTrackTitle,
655                                 toolbar: 'add-track',
656                                 media: this.media,
657                                 menu: 'video-details'
658                         } )
659                 ]);
660         },
661
662         renderSelectPosterImageToolbar: function() {
663                 this.setPrimaryButton( l10n.videoSelectPosterImageTitle, function( controller, state ) {
664                         var urls = [], attachment = state.get( 'selection' ).single();
665
666                         controller.media.set( 'poster', attachment.get( 'url' ) );
667                         state.trigger( 'set-poster-image', controller.media.toJSON() );
668
669                         _.each( wp.media.view.settings.embedExts, function (ext) {
670                                 if ( controller.media.get( ext ) ) {
671                                         urls.push( controller.media.get( ext ) );
672                                 }
673                         } );
674
675                         wp.ajax.send( 'set-attachment-thumbnail', {
676                                 data : {
677                                         urls: urls,
678                                         thumbnail_id: attachment.get( 'id' )
679                                 }
680                         } );
681                 } );
682         },
683
684         renderAddTrackToolbar: function() {
685                 this.setPrimaryButton( l10n.videoAddTrackTitle, function( controller, state ) {
686                         var attachment = state.get( 'selection' ).single(),
687                                 content = controller.media.get( 'content' );
688
689                         if ( -1 === content.indexOf( attachment.get( 'url' ) ) ) {
690                                 content += [
691                                         '<track srclang="en" label="English" kind="subtitles" src="',
692                                         attachment.get( 'url' ),
693                                         '" />'
694                                 ].join('');
695
696                                 controller.media.set( 'content', content );
697                         }
698                         state.trigger( 'add-track', controller.media.toJSON() );
699                 } );
700         }
701 });
702
703 module.exports = VideoDetails;
704
705 },{}],9:[function(require,module,exports){
706 /* global MediaElementPlayer */
707
708 /**
709  * wp.media.view.MediaDetails
710  *
711  * @class
712  * @augments wp.media.view.Settings.AttachmentDisplay
713  * @augments wp.media.view.Settings
714  * @augments wp.media.View
715  * @augments wp.Backbone.View
716  * @augments Backbone.View
717  */
718 var AttachmentDisplay = wp.media.view.Settings.AttachmentDisplay,
719         $ = jQuery,
720         MediaDetails;
721
722 MediaDetails = AttachmentDisplay.extend({
723         initialize: function() {
724                 _.bindAll(this, 'success');
725                 this.players = [];
726                 this.listenTo( this.controller, 'close', wp.media.mixin.unsetPlayers );
727                 this.on( 'ready', this.setPlayer );
728                 this.on( 'media:setting:remove', wp.media.mixin.unsetPlayers, this );
729                 this.on( 'media:setting:remove', this.render );
730                 this.on( 'media:setting:remove', this.setPlayer );
731
732                 AttachmentDisplay.prototype.initialize.apply( this, arguments );
733         },
734
735         events: function(){
736                 return _.extend( {
737                         'click .remove-setting' : 'removeSetting',
738                         'change .content-track' : 'setTracks',
739                         'click .remove-track' : 'setTracks',
740                         'click .add-media-source' : 'addSource'
741                 }, AttachmentDisplay.prototype.events );
742         },
743
744         prepare: function() {
745                 return _.defaults({
746                         model: this.model.toJSON()
747                 }, this.options );
748         },
749
750         /**
751          * Remove a setting's UI when the model unsets it
752          *
753          * @fires wp.media.view.MediaDetails#media:setting:remove
754          *
755          * @param {Event} e
756          */
757         removeSetting : function(e) {
758                 var wrap = $( e.currentTarget ).parent(), setting;
759                 setting = wrap.find( 'input' ).data( 'setting' );
760
761                 if ( setting ) {
762                         this.model.unset( setting );
763                         this.trigger( 'media:setting:remove', this );
764                 }
765
766                 wrap.remove();
767         },
768
769         /**
770          *
771          * @fires wp.media.view.MediaDetails#media:setting:remove
772          */
773         setTracks : function() {
774                 var tracks = '';
775
776                 _.each( this.$('.content-track'), function(track) {
777                         tracks += $( track ).val();
778                 } );
779
780                 this.model.set( 'content', tracks );
781                 this.trigger( 'media:setting:remove', this );
782         },
783
784         addSource : function( e ) {
785                 this.controller.lastMime = $( e.currentTarget ).data( 'mime' );
786                 this.controller.setState( 'add-' + this.controller.defaults.id + '-source' );
787         },
788
789         loadPlayer: function () {
790                 this.players.push( new MediaElementPlayer( this.media, this.settings ) );
791                 this.scriptXhr = false;
792         },
793
794         /**
795          * @global MediaElementPlayer
796          */
797         setPlayer : function() {
798                 var baseSettings, src;
799
800                 if ( this.players.length || ! this.media || this.scriptXhr ) {
801                         return;
802                 }
803
804                 src = this.model.get( 'src' );
805
806                 if ( src && src.indexOf( 'vimeo' ) > -1 && ! ( 'Froogaloop' in window ) ) {
807                         baseSettings = wp.media.mixin.mejsSettings;
808                         this.scriptXhr = $.getScript( baseSettings.pluginPath + 'froogaloop.min.js', _.bind( this.loadPlayer, this ) );
809                 } else {
810                         this.loadPlayer();
811                 }
812         },
813
814         /**
815          * @abstract
816          */
817         setMedia : function() {
818                 return this;
819         },
820
821         success : function(mejs) {
822                 var autoplay = mejs.attributes.autoplay && 'false' !== mejs.attributes.autoplay;
823
824                 if ( 'flash' === mejs.pluginType && autoplay ) {
825                         mejs.addEventListener( 'canplay', function() {
826                                 mejs.play();
827                         }, false );
828                 }
829
830                 this.mejs = mejs;
831         },
832
833         /**
834          * @returns {media.view.MediaDetails} Returns itself to allow chaining
835          */
836         render: function() {
837                 AttachmentDisplay.prototype.render.apply( this, arguments );
838
839                 setTimeout( _.bind( function() {
840                         this.resetFocus();
841                 }, this ), 10 );
842
843                 this.settings = _.defaults( {
844                         success : this.success
845                 }, wp.media.mixin.mejsSettings );
846
847                 return this.setMedia();
848         },
849
850         resetFocus: function() {
851                 this.$( '.embed-media-settings' ).scrollTop( 0 );
852         }
853 }, {
854         instances : 0,
855         /**
856          * When multiple players in the DOM contain the same src, things get weird.
857          *
858          * @param {HTMLElement} elem
859          * @returns {HTMLElement}
860          */
861         prepareSrc : function( elem ) {
862                 var i = MediaDetails.instances++;
863                 _.each( $( elem ).find( 'source' ), function( source ) {
864                         source.src = [
865                                 source.src,
866                                 source.src.indexOf('?') > -1 ? '&' : '?',
867                                 '_=',
868                                 i
869                         ].join('');
870                 } );
871
872                 return elem;
873         }
874 });
875
876 module.exports = MediaDetails;
877
878 },{}],10:[function(require,module,exports){
879 /**
880  * wp.media.view.VideoDetails
881  *
882  * @class
883  * @augments wp.media.view.MediaDetails
884  * @augments wp.media.view.Settings.AttachmentDisplay
885  * @augments wp.media.view.Settings
886  * @augments wp.media.View
887  * @augments wp.Backbone.View
888  * @augments Backbone.View
889  */
890 var MediaDetails = wp.media.view.MediaDetails,
891         VideoDetails;
892
893 VideoDetails = MediaDetails.extend({
894         className: 'video-details',
895         template:  wp.template('video-details'),
896
897         setMedia: function() {
898                 var video = this.$('.wp-video-shortcode');
899
900                 if ( video.find( 'source' ).length ) {
901                         if ( video.is(':hidden') ) {
902                                 video.show();
903                         }
904
905                         if ( ! video.hasClass( 'youtube-video' ) && ! video.hasClass( 'vimeo-video' ) ) {
906                                 this.media = MediaDetails.prepareSrc( video.get(0) );
907                         } else {
908                                 this.media = video.get(0);
909                         }
910                 } else {
911                         video.hide();
912                         this.media = false;
913                 }
914
915                 return this;
916         }
917 });
918
919 module.exports = VideoDetails;
920
921 },{}]},{},[1]);