media-audiovideo.js 26 KB

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