Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 

922 рядки
22 KiB

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