<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[27608] trunk/src/wp-includes: Create a new file, `media-audiovideo.js`, to house all of the audio and video JS code in core.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://core.trac.wordpress.org/changeset/27608">27608</a></dd>
<dt>Author</dt> <dd>wonderboymusic</dd>
<dt>Date</dt> <dd>2014-03-19 05:30:27 +0000 (Wed, 19 Mar 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Create a new file, `media-audiovideo.js`, to house all of the audio and video JS code in core.
UX Changes:
* Don't add a menu item for "Add Audio|Video Source"
* In the Audio|Video Details modal, add buttons and some suggestive text for adding alternate playback sources
* Don't show "Create Audio|Video Playlist" menu items until the user has uploaded audio or video files
See <a href="http://core.trac.wordpress.org/ticket/27437">#27437</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesjsmediaeditorjs">trunk/src/wp-includes/js/media-editor.js</a></li>
<li><a href="#trunksrcwpincludesjsmediamodelsjs">trunk/src/wp-includes/js/media-models.js</a></li>
<li><a href="#trunksrcwpincludesjsmediaviewsjs">trunk/src/wp-includes/js/media-views.js</a></li>
<li><a href="#trunksrcwpincludesjsmediaelementwpmediaelementcss">trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css</a></li>
<li><a href="#trunksrcwpincludesmediatemplatephp">trunk/src/wp-includes/media-template.php</a></li>
<li><a href="#trunksrcwpincludesmediaphp">trunk/src/wp-includes/media.php</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesjsmediaaudiovideojs">trunk/src/wp-includes/js/media-audiovideo.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesjsmediaaudiovideojs"></a>
<div class="addfile"><h4>Added: trunk/src/wp-includes/js/media-audiovideo.js (0 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/js/media-audiovideo.js (rev 0)
+++ trunk/src/wp-includes/js/media-audiovideo.js 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -0,0 +1,985 @@
</span><ins>+/* global _wpMediaViewsL10n */
+
+(function ($, _, Backbone) {
+ var media = wp.media, l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n;
+
+ /**
+ * @mixin
+ */
+ wp.media.mixin = {
+
+ /**
+ * Pauses every instance of MediaElementPlayer
+ */
+ pauseAllPlayers: function () {
+ var p;
+ if ( window.mejs && window.mejs.players ) {
+ for ( p in window.mejs.players ) {
+ window.mejs.players[p].pause();
+ }
+ }
+ },
+
+ /**
+ * Utility to identify the user's browser
+ */
+ ua: {
+ is : function (browser) {
+ var passes = false, ua = window.navigator.userAgent;
+
+ switch ( browser ) {
+ case 'oldie':
+ passes = ua.match(/MSIE [6-8]/gi) !== null;
+ break;
+ case 'ie':
+ passes = ua.match(/MSIE/gi) !== null;
+ break;
+ case 'ff':
+ passes = ua.match(/firefox/gi) !== null;
+ break;
+ case 'opera':
+ passes = ua.match(/OPR/) !== null;
+ break;
+ case 'safari':
+ passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) === null;
+ break;
+ case 'chrome':
+ passes = ua.match(/safari/gi) && ua.match(/chrome/gi) !== null;
+ break;
+ }
+
+ return passes;
+ }
+ },
+
+ /**
+ * Specify compatibility for native playback by browser
+ */
+ compat :{
+ 'opera' : {
+ audio: ['ogg', 'wav'],
+ video: ['ogg', 'webm']
+ },
+ 'chrome' : {
+ audio: ['ogg', 'mpeg', 'x-ms-wma'],
+ video: ['ogg', 'webm', 'mp4', 'm4v', 'mpeg']
+ },
+ 'ff' : {
+ audio: ['ogg', 'mpeg'],
+ video: ['ogg', 'webm']
+ },
+ 'safari' : {
+ audio: ['mpeg', 'wav'],
+ video: ['mp4', 'm4v', 'mpeg', 'x-ms-wmv', 'quicktime']
+ },
+ 'ie' : {
+ audio: ['mpeg'],
+ video: ['mp4', 'm4v', 'mpeg']
+ }
+ },
+
+ /**
+ * Determine if the passed media contains a <source> that provides
+ * native playback in the user's browser
+ *
+ * @param {jQuery} media
+ * @returns {Boolean}
+ */
+ isCompatible: function ( media ) {
+ if ( ! media.find( 'source' ).length ) {
+ return false;
+ }
+
+ var ua = this.ua, test = false, found = false, sources;
+
+ if ( ua.is( 'oldIE' ) ) {
+ return false;
+ }
+
+ sources = media.find( 'source' );
+
+ _.find( this.compat, function (supports, browser) {
+ if ( ua.is( browser ) ) {
+ found = true;
+ _.each( sources, function (elem) {
+ var audio = new RegExp( 'audio\/(' + supports.audio.join('|') + ')', 'gi' ),
+ video = new RegExp( 'video\/(' + supports.video.join('|') + ')', 'gi' );
+
+ if ( elem.type.match( video ) !== null || elem.type.match( audio ) !== null ) {
+ test = true;
+ }
+ } );
+ }
+
+ return test || found;
+ } );
+
+ return test;
+ },
+
+ /**
+ * Override the MediaElement method for removing a player.
+ * MediaElement tries to pull the audio/video tag out of
+ * its container and re-add it to the DOM.
+ */
+ removePlayer: function() {
+ var t = this.player, featureIndex, feature;
+
+ // invoke features cleanup
+ for ( featureIndex in t.options.features ) {
+ feature = t.options.features[featureIndex];
+ if ( t['clean' + feature] ) {
+ try {
+ t['clean' + feature](t);
+ } catch (e) {}
+ }
+ }
+
+ if ( ! t.isDynamic ) {
+ t.$node.remove();
+ }
+
+ if ( 'native' !== t.media.pluginType ) {
+ t.media.remove();
+ }
+
+ delete window.mejs.players[t.id];
+
+ t.container.remove();
+ t.globalUnbind();
+ delete t.node.player;
+ },
+
+ /**
+ * Allows any class that has set 'player' to a MediaElementPlayer
+ * instance to remove the player when listening to events.
+ *
+ * Examples: modal closes, shortcode properties are removed, etc.
+ */
+ unsetPlayer : function() {
+ if ( this.player ) {
+ wp.media.mixin.pauseAllPlayers();
+ wp.media.mixin.removePlayer.apply( this );
+ this.player = false;
+ }
+ }
+ };
+
+ /**
+ * Autowire "collection"-type shortcodes
+ */
+ wp.media.playlist = new wp.media.collection({
+ tag: 'playlist',
+ type : 'audio',
+ editTitle : l10n.editPlaylistTitle,
+ defaults : {
+ id: wp.media.view.settings.post.id,
+ style: 'light',
+ tracklist: true,
+ tracknumbers: true,
+ images: true,
+ artists: true
+ }
+ });
+
+ wp.media['video-playlist'] = new wp.media.collection({
+ tag: 'video-playlist',
+ type : 'video',
+ editTitle : l10n.editVideoPlaylistTitle,
+ defaults : {
+ id: wp.media.view.settings.post.id,
+ style: 'light',
+ tracklist: false,
+ tracknumbers: false,
+ images: true
+ }
+ });
+
+ /**
+ * Shortcode modeling for audio
+ * `edit()` prepares the shortcode for the media modal
+ * `shortcode()` builds the new shortcode after update
+ *
+ * @namespace
+ */
+ wp.media.audio = {
+ coerce : wp.media.coerce,
+
+ defaults : {
+ id : wp.media.view.settings.post.id,
+ src : '',
+ loop : false,
+ autoplay : false,
+ preload : 'none'
+ },
+
+ edit : function (data) {
+ var frame, shortcode = wp.shortcode.next( 'audio', data ).shortcode;
+ frame = wp.media({
+ frame: 'audio',
+ state: 'audio-details',
+ metadata: _.defaults(
+ shortcode.attrs.named,
+ wp.media.audio.defaults
+ )
+ });
+
+ return frame;
+ },
+
+ shortcode : function (shortcode) {
+ var self = this;
+
+ _.each( wp.media.audio.defaults, function( value, key ) {
+ shortcode[ key ] = self.coerce( shortcode, key );
+
+ if ( value === shortcode[ key ] ) {
+ delete shortcode[ key ];
+ }
+ });
+
+ return wp.shortcode.string({
+ tag: 'audio',
+ attrs: shortcode
+ });
+ }
+ };
+
+ /**
+ * Shortcode modeling for video
+ * `edit()` prepares the shortcode for the media modal
+ * `shortcode()` builds the new shortcode after update
+ *
+ * @namespace
+ */
+ wp.media.video = {
+ coerce : wp.media.coerce,
+
+ defaults : {
+ id : wp.media.view.settings.post.id,
+ src : '',
+ poster : '',
+ loop : false,
+ autoplay : false,
+ preload : 'metadata',
+ content : ''
+ },
+
+ edit : function (data) {
+ var frame,
+ defaults = this.defaults,
+ shortcode = wp.shortcode.next( 'video', data ).shortcode,
+ attrs;
+
+ attrs = shortcode.attrs.named;
+ attrs.content = shortcode.content;
+
+ frame = wp.media({
+ frame: 'video',
+ state: 'video-details',
+ metadata: _.defaults( attrs, defaults )
+ });
+
+ return frame;
+ },
+
+ shortcode : function (shortcode) {
+ var self = this, content = shortcode.content;
+ delete shortcode.content;
+
+ _.each( this.defaults, function( value, key ) {
+ shortcode[ key ] = self.coerce( shortcode, key );
+
+ if ( value === shortcode[ key ] ) {
+ delete shortcode[ key ];
+ }
+ });
+
+ return wp.shortcode.string({
+ tag: 'video',
+ attrs: shortcode,
+ content: content
+ });
+ }
+ };
+
+ /**
+ * wp.media.model.PostMedia
+ *
+ * @constructor
+ * @augments Backbone.Model
+ **/
+ media.model.PostMedia = Backbone.Model.extend({
+ initialize: function() {
+ this.attachment = false;
+ },
+
+ setSource: function ( attachment ) {
+ this.attachment = attachment;
+ this.extension = attachment.get('filename' ).split('.').pop();
+
+ if ( this.get( 'src' ) && this.extension === this.get( 'src' ).split('.').pop() ) {
+ this.unset( 'src' );
+ }
+
+ if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
+ this.set( this.extension, this.attachment.get( 'url' ) );
+ } else {
+ this.unset( this.extension );
+ }
+ },
+
+ changeAttachment: function( attachment ) {
+ var self = this;
+
+ this.setSource( attachment );
+
+ this.unset( 'src' );
+ _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function (ext) {
+ self.unset( ext );
+ } );
+ }
+ });
+
+ /**
+ * wp.media.controller.AudioDetails
+ *
+ * @constructor
+ * @augments wp.media.controller.State
+ * @augments Backbone.Model
+ */
+ media.controller.AudioDetails = media.controller.State.extend({
+ defaults: _.defaults({
+ id: 'audio-details',
+ toolbar: 'audio-details',
+ title: l10n.audioDetailsTitle,
+ content: 'audio-details',
+ menu: 'audio-details',
+ router: false,
+ attachment: false,
+ priority: 60,
+ editing: false
+ }, media.controller.Library.prototype.defaults ),
+
+ initialize: function( options ) {
+ this.media = options.media;
+ media.controller.State.prototype.initialize.apply( this, arguments );
+ }
+ });
+
+ /**
+ * wp.media.controller.VideoDetails
+ *
+ * @constructor
+ * @augments wp.media.controller.State
+ * @augments Backbone.Model
+ */
+ media.controller.VideoDetails = media.controller.State.extend({
+ defaults: _.defaults({
+ id: 'video-details',
+ toolbar: 'video-details',
+ title: l10n.videoDetailsTitle,
+ content: 'video-details',
+ menu: 'video-details',
+ router: false,
+ attachment: false,
+ priority: 60,
+ editing: false
+ }, media.controller.Library.prototype.defaults ),
+
+ initialize: function( options ) {
+ this.media = options.media;
+ media.controller.State.prototype.initialize.apply( this, arguments );
+ }
+ });
+
+ /**
+ * wp.media.view.MediaFrame.MediaDetails
+ *
+ * @constructor
+ * @augments wp.media.view.MediaFrame.Select
+ * @augments wp.media.view.MediaFrame
+ * @augments wp.media.view.Frame
+ * @augments wp.media.View
+ * @augments wp.Backbone.View
+ * @augments Backbone.View
+ * @mixes wp.media.controller.StateMachine
+ */
+ media.view.MediaFrame.MediaDetails = media.view.MediaFrame.Select.extend({
+ defaults: {
+ id: 'media',
+ url: '',
+ menu: 'media-details',
+ content: 'media-details',
+ toolbar: 'media-details',
+ type: 'link',
+ priority: 120
+ },
+
+ initialize: function( options ) {
+ this.DetailsView = options.DetailsView;
+ this.cancelText = options.cancelText;
+ this.addText = options.addText;
+
+ this.media = new media.model.PostMedia( options.metadata );
+ this.options.selection = new media.model.Selection( this.media.attachment, { multiple: false } );
+ media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
+ },
+
+ bindHandlers: function() {
+ var menu = this.defaults.menu;
+
+ media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments );
+
+ this.on( 'menu:create:' + menu, this.createMenu, this );
+ this.on( 'content:render:' + menu, this.renderDetailsContent, this );
+ this.on( 'menu:render:' + menu, this.renderMenu, this );
+ this.on( 'toolbar:render:' + menu, this.renderDetailsToolbar, this );
+ },
+
+ renderDetailsContent: function() {
+ var view = new this.DetailsView({
+ controller: this,
+ model: this.state().media,
+ attachment: this.state().media.attachment
+ }).render();
+
+ this.content.set( view );
+ },
+
+ renderMenu: function( view ) {
+ var lastState = this.lastState(),
+ previous = lastState && lastState.id,
+ frame = this;
+
+ view.set({
+ cancel: {
+ text: this.cancelText,
+ priority: 20,
+ click: function() {
+ if ( previous ) {
+ frame.setState( previous );
+ } else {
+ frame.close();
+ }
+ }
+ },
+ separateCancel: new media.View({
+ className: 'separator',
+ priority: 40
+ })
+ });
+
+ },
+
+ renderDetailsToolbar: function() {
+ this.toolbar.set( new media.view.Toolbar({
+ controller: this,
+ items: {
+ select: {
+ style: 'primary',
+ text: l10n.update,
+ priority: 80,
+
+ click: function() {
+ var controller = this.controller,
+ state = controller.state();
+
+ controller.close();
+
+ state.trigger( 'update', controller.media.toJSON() );
+
+ // Restore and reset the default state.
+ controller.setState( controller.options.state );
+ controller.reset();
+ }
+ }
+ }
+ }) );
+ },
+
+ renderReplaceToolbar: function() {
+ this.toolbar.set( new media.view.Toolbar({
+ controller: this,
+ items: {
+ replace: {
+ style: 'primary',
+ text: l10n.replace,
+ priority: 80,
+
+ click: function() {
+ var controller = this.controller,
+ state = controller.state(),
+ selection = state.get( 'selection' ),
+ attachment = selection.single();
+
+ controller.media.changeAttachment( attachment );
+
+ state.trigger( 'replace', controller.media.toJSON() );
+
+ // Restore and reset the default state.
+ controller.setState( controller.options.state );
+ controller.reset();
+ }
+ }
+ }
+ }) );
+ },
+
+ renderAddSourceToolbar: function() {
+ this.toolbar.set( new media.view.Toolbar({
+ controller: this,
+ items: {
+ replace: {
+ style: 'primary',
+ text: this.addText,
+ priority: 80,
+
+ click: function() {
+ var controller = this.controller,
+ state = controller.state(),
+ selection = state.get( 'selection' ),
+ attachment = selection.single();
+
+ controller.media.setSource( attachment );
+
+ state.trigger( 'add-source', controller.media.toJSON() );
+
+ // Restore and reset the default state.
+ controller.setState( controller.options.state );
+ controller.reset();
+ }
+ }
+ }
+ }) );
+ }
+ });
+
+ /**
+ * wp.media.view.MediaFrame.AudioDetails
+ *
+ * @constructor
+ * @augments wp.media.view.MediaFrame.MediaDetails
+ * @augments wp.media.view.MediaFrame.Select
+ * @augments wp.media.view.MediaFrame
+ * @augments wp.media.view.Frame
+ * @augments wp.media.View
+ * @augments wp.Backbone.View
+ * @augments Backbone.View
+ * @mixes wp.media.controller.StateMachine
+ */
+ media.view.MediaFrame.AudioDetails = media.view.MediaFrame.MediaDetails.extend({
+ defaults: {
+ id: 'audio',
+ url: '',
+ menu: 'audio-details',
+ content: 'audio-details',
+ toolbar: 'audio-details',
+ type: 'link',
+ title: l10n.audioDetailsTitle,
+ priority: 120
+ },
+
+ initialize: function( options ) {
+ options.DetailsView = media.view.AudioDetails;
+ options.cancelText = l10n.audioDetailsCancel;
+ options.addText = l10n.audioAddSourceTitle;
+
+ media.view.MediaFrame.MediaDetails.prototype.initialize.call( this, options );
+ },
+
+ bindHandlers: function() {
+ media.view.MediaFrame.MediaDetails.prototype.bindHandlers.apply( this, arguments );
+
+ this.on( 'toolbar:render:replace-audio', this.renderReplaceToolbar, this );
+ this.on( 'toolbar:render:add-audio-source', this.renderAddSourceToolbar, this );
+ },
+
+ createStates: function() {
+ this.states.add([
+ new media.controller.AudioDetails( {
+ media: this.media,
+ editable: false,
+ menu: 'audio-details'
+ } ),
+
+ new media.controller.MediaLibrary( {
+ type: 'audio',
+ id: 'replace-audio',
+ title: l10n.audioReplaceTitle,
+ toolbar: 'replace-audio',
+ media: this.media,
+ menu: 'audio-details'
+ } ),
+
+ new media.controller.MediaLibrary( {
+ type: 'audio',
+ id: 'add-audio-source',
+ title: l10n.audioAddSourceTitle,
+ toolbar: 'add-audio-source',
+ media: this.media,
+ menu: false
+ } )
+ ]);
+ }
+ });
+
+ /**
+ * wp.media.view.MediaFrame.VideoDetails
+ *
+ * @constructor
+ * @augments wp.media.view.MediaFrame.MediaDetails
+ * @augments wp.media.view.MediaFrame.Select
+ * @augments wp.media.view.MediaFrame
+ * @augments wp.media.view.Frame
+ * @augments wp.media.View
+ * @augments wp.Backbone.View
+ * @augments Backbone.View
+ * @mixes wp.media.controller.StateMachine
+ */
+ media.view.MediaFrame.VideoDetails = media.view.MediaFrame.MediaDetails.extend({
+ defaults: {
+ id: 'video',
+ url: '',
+ menu: 'video-details',
+ content: 'video-details',
+ toolbar: 'video-details',
+ type: 'link',
+ title: l10n.videoDetailsTitle,
+ priority: 120
+ },
+
+ initialize: function( options ) {
+ options.DetailsView = media.view.VideoDetails;
+ options.cancelText = l10n.videoDetailsCancel;
+ options.addText = l10n.videoAddSourceTitle;
+
+ media.view.MediaFrame.MediaDetails.prototype.initialize.call( this, options );
+ },
+
+ bindHandlers: function() {
+ media.view.MediaFrame.MediaDetails.prototype.bindHandlers.apply( this, arguments );
+
+ this.on( 'toolbar:render:replace-video', this.renderReplaceToolbar, this );
+ this.on( 'toolbar:render:add-video-source', this.renderAddSourceToolbar, this );
+ this.on( 'toolbar:render:select-poster-image', this.renderSelectPosterImageToolbar, this );
+ this.on( 'toolbar:render:add-track', this.renderAddTrackToolbar, this );
+ },
+
+ createStates: function() {
+ this.states.add([
+ new media.controller.VideoDetails({
+ media: this.media,
+ editable: false,
+ menu: 'video-details'
+ }),
+
+ new media.controller.MediaLibrary( {
+ type: 'video',
+ id: 'replace-video',
+ title: l10n.videoReplaceTitle,
+ toolbar: 'replace-video',
+ media: this.media,
+ menu: 'video-details'
+ } ),
+
+ new media.controller.MediaLibrary( {
+ type: 'video',
+ id: 'add-video-source',
+ title: l10n.videoAddSourceTitle,
+ toolbar: 'add-video-source',
+ media: this.media,
+ menu: false
+ } ),
+
+ new media.controller.MediaLibrary( {
+ type: 'image',
+ id: 'select-poster-image',
+ title: l10n.videoSelectPosterImageTitle,
+ toolbar: 'select-poster-image',
+ media: this.media,
+ menu: 'video-details'
+ } ),
+
+ new media.controller.MediaLibrary( {
+ type: 'text',
+ id: 'add-track',
+ title: l10n.videoAddTrackTitle,
+ toolbar: 'add-track',
+ media: this.media,
+ menu: 'video-details'
+ } )
+ ]);
+ },
+
+ renderSelectPosterImageToolbar: function() {
+ this.toolbar.set( new media.view.Toolbar({
+ controller: this,
+ items: {
+ replace: {
+ style: 'primary',
+ text: l10n.videoSelectPosterImageTitle,
+ priority: 80,
+
+ click: function() {
+ var controller = this.controller,
+ state = controller.state(),
+ selection = state.get( 'selection' ),
+ attachment = selection.single();
+
+ controller.media.set( 'poster', attachment.get( 'url' ) );
+
+ state.trigger( 'set-poster-image', controller.media.toJSON() );
+
+ // Restore and reset the default state.
+ controller.setState( controller.options.state );
+ controller.reset();
+ }
+ }
+ }
+ }) );
+ },
+
+ renderAddTrackToolbar: function() {
+ this.toolbar.set( new media.view.Toolbar({
+ controller: this,
+ items: {
+ replace: {
+ style: 'primary',
+ text: l10n.videoAddTrackTitle,
+ priority: 80,
+
+ click: function() {
+ var controller = this.controller,
+ state = controller.state(),
+ selection = state.get( 'selection' ),
+ attachment = selection.single(),
+ content = controller.media.get( 'content' );
+
+ if ( -1 === content.indexOf( attachment.get( 'url' ) ) ) {
+ content += [
+ '<track srclang="en" label="English"kind="subtitles" src="',
+ attachment.get( 'url' ),
+ '" />'
+ ].join('');
+
+ controller.media.set( 'content', content );
+ }
+
+ state.trigger( 'add-track', controller.media.toJSON() );
+
+ // Restore and reset the default state.
+ controller.setState( controller.options.state );
+ controller.reset();
+ }
+ }
+ }
+ }) );
+ }
+ });
+
+ /**
+ * wp.media.view.AudioDetails
+ *
+ * @contructor
+ * @augments wp.media.view.MediaDetails
+ * @augments wp.media.view.Settings.AttachmentDisplay
+ * @augments wp.media.view.Settings
+ * @augments wp.media.View
+ * @augments wp.Backbone.View
+ * @augments Backbone.View
+ */
+ media.view.AudioDetails = media.view.MediaDetails.extend({
+ className: 'audio-details',
+ template: media.template('audio-details'),
+
+ setMedia: function() {
+ var audio = this.$('.wp-audio-shortcode');
+
+ if ( audio.find( 'source' ).length ) {
+ if ( audio.is(':hidden') ) {
+ audio.show();
+ }
+ this.media = media.view.MediaDetails.prepareSrc( audio.get(0) );
+ } else {
+ audio.hide();
+ this.media = false;
+ }
+
+ return this;
+ }
+ });
+
+ /**
+ * wp.media.view.VideoDetails
+ *
+ * @contructor
+ * @augments wp.media.view.MediaDetails
+ * @augments wp.media.view.Settings.AttachmentDisplay
+ * @augments wp.media.view.Settings
+ * @augments wp.media.View
+ * @augments wp.Backbone.View
+ * @augments Backbone.View
+ */
+ media.view.VideoDetails = media.view.MediaDetails.extend({
+ className: 'video-details',
+ template: media.template('video-details'),
+
+ setMedia: function() {
+ var video = this.$('.wp-video-shortcode');
+
+ if ( video.find( 'source' ).length ) {
+ if ( video.is(':hidden') ) {
+ video.show();
+ }
+
+ if ( ! video.hasClass('youtube-video') ) {
+ this.media = media.view.MediaDetails.prepareSrc( video.get(0) );
+ } else {
+ this.media = video.get(0);
+ }
+ } else {
+ video.hide();
+ this.media = false;
+ }
+
+ return this;
+ }
+ });
+
+ _.extend( wp.media.playlist, {
+ /**
+ * Determine how many audio and video files the user has uploaded
+ */
+ counts : (function (settings) {
+ var counts = {};
+
+ return function () {
+ if ( ! _.isEmpty( counts ) ) {
+ return counts;
+ }
+
+ var a = 0, v = 0;
+ _.each( settings.attachmentCounts, function (total, mime) {
+ var type;
+ if ( -1 < mime.indexOf('/') ) {
+ type = mime.split('/')[0];
+
+ total = parseInt(total, 10);
+
+ switch ( type ) {
+ case 'audio':
+ a += total;
+ break;
+ case 'video':
+ v += total;
+ break;
+ }
+ }
+ } );
+
+ counts.audio = a;
+ counts.video = v;
+
+ return counts;
+ };
+ }(media.view.settings)),
+
+ /**
+ * Return the playlist states for MediaFrame.Post
+ *
+ * @param {Object} options
+ * @returns {Array}
+ */
+ states : function (options) {
+ return [
+ new media.controller.Library({
+ id: 'playlist',
+ title: l10n.createPlaylistTitle,
+ priority: 60,
+ toolbar: 'main-playlist',
+ filterable: 'uploaded',
+ multiple: 'add',
+ editable: false,
+
+ library: media.query( _.defaults({
+ type: 'audio'
+ }, options.library ) )
+ }),
+
+ // Playlist states.
+ new media.controller.CollectionEdit({
+ type: 'audio',
+ collectionType: 'playlist',
+ title: l10n.editPlaylistTitle,
+ SettingsView: media.view.Settings.Playlist,
+ library: options.selection,
+ editing: options.editing,
+ menu: 'playlist',
+ dragInfoText: l10n.playlistDragInfo,
+ dragInfo: false
+ }),
+
+ new media.controller.CollectionAdd({
+ type: 'audio',
+ collectionType: 'playlist',
+ title: l10n.addToPlaylistTitle
+ })
+ ];
+ },
+
+ /**
+ * Return the video-playlist states for MediaFrame.Post
+ *
+ * @param {Object} options
+ * @returns {Array}
+ */
+ videoStates : function (options) {
+ return [
+ new media.controller.Library({
+ id: 'video-playlist',
+ title: l10n.createVideoPlaylistTitle,
+ priority: 60,
+ toolbar: 'main-video-playlist',
+ filterable: 'uploaded',
+ multiple: 'add',
+ editable: false,
+
+ library: media.query( _.defaults({
+ type: 'video'
+ }, options.library ) )
+ }),
+
+ // Video Playlist states.
+ new media.controller.CollectionEdit({
+ type: 'video',
+ collectionType: 'video-playlist',
+ title: l10n.editVideoPlaylistTitle,
+ SettingsView: media.view.Settings.Playlist,
+ library: options.selection,
+ editing: options.editing,
+ menu: 'video-playlist',
+ dragInfoText: l10n.videoPlaylistDragInfo,
+ dragInfo: false
+ }),
+
+ new media.controller.CollectionAdd({
+ type: 'video',
+ collectionType: 'video-playlist',
+ title: l10n.addToVideoPlaylistTitle
+ })
+ ];
+ }
+ } );
+
+ function init() {
+ $(document.body)
+ .on( 'click', '.wp-switch-editor', wp.media.mixin.pauseAllPlayers )
+ .on( 'click', '.add-media-source', function () {
+ media.frame.setState('add-' + media.frame.defaults.id + '-source');
+ } );
+ }
+
+ $( init );
+
+}(jQuery, _, Backbone));
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunksrcwpincludesjsmediaeditorjs"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/js/media-editor.js (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/js/media-editor.js 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/js/media-editor.js 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -11,6 +11,26 @@
</span><span class="cx"> var workflows = {};
</span><span class="cx">
</span><span class="cx"> /**
</span><ins>+ * A helper mixin function to avoid truthy and falsey values being
+ * passed as an input that expects booleans. If key is undefined in the map,
+ * but has a default value, set it.
+ *
+ * @param {object} attrs Map of props from a shortcode or settings.
+ * @param {string} key The key within the passed map to check for a value.
+ * @returns {mixed|undefined} The original or coerced value of key within attrs
+ */
+ wp.media.coerce = function ( attrs, key ) {
+ if ( _.isUndefined( attrs[ key ] ) && ! _.isUndefined( this.defaults[ key ] ) ) {
+ attrs[ key ] = this.defaults[ key ];
+ } else if ( 'true' === attrs[ key ] ) {
+ attrs[ key ] = true;
+ } else if ( 'false' === attrs[ key ] ) {
+ attrs[ key ] = false;
+ }
+ return attrs[ key ];
+ };
+
+ /**
</ins><span class="cx"> * wp.media.string
</span><span class="cx"> * @namespace
</span><span class="cx"> */
</span><span class="lines">@@ -274,176 +294,11 @@
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span><del>- /**
- * @mixin
- */
- wp.media.mixin = {
- /**
- * A helper function to avoid truthy and falsey values being
- * passed as an input that expects booleans. If key is undefined in the map,
- * but has a default value, set it.
- *
- * @param {object} attrs Map of props from a shortcode or settings.
- * @param {string} key The key within the passed map to check for a value.
- * @returns {mixed|undefined} The original or coerced value of key within attrs
- */
- coerce: function ( attrs, key ) {
- if ( _.isUndefined( attrs[ key ] ) && ! _.isUndefined( this.defaults[ key ] ) ) {
- attrs[ key ] = this.defaults[ key ];
- } else if ( 'true' === attrs[ key ] ) {
- attrs[ key ] = true;
- } else if ( 'false' === attrs[ key ] ) {
- attrs[ key ] = false;
- }
- return attrs[ key ];
- },
-
- pauseAllPlayers: function () {
- var p;
- if ( window.mejs && window.mejs.players ) {
- for ( p in window.mejs.players ) {
- window.mejs.players[p].pause();
- }
- }
- },
-
- ua: {
- is : function (browser) {
- var passes = false, ua = window.navigator.userAgent;
-
- switch ( browser ) {
- case 'oldie':
- passes = ua.match(/MSIE [6-8]/gi) !== null;
- break;
- case 'ie':
- passes = ua.match(/MSIE/gi) !== null;
- break;
- case 'ff':
- passes = ua.match(/firefox/gi) !== null;
- break;
- case 'opera':
- passes = ua.match(/OPR/) !== null;
- break;
- case 'safari':
- passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) === null;
- break;
- case 'chrome':
- passes = ua.match(/safari/gi) && ua.match(/chrome/gi) !== null;
- break;
- }
-
- return passes;
- }
- },
-
- compat :{
- 'opera' : {
- audio: ['ogg', 'wav'],
- video: ['ogg', 'webm']
- },
- 'chrome' : {
- audio: ['ogg', 'mpeg', 'x-ms-wma'],
- video: ['ogg', 'webm', 'mp4', 'm4v', 'mpeg']
- },
- 'ff' : {
- audio: ['ogg', 'mpeg'],
- video: ['ogg', 'webm']
- },
- 'safari' : {
- audio: ['mpeg', 'wav'],
- video: ['mp4', 'm4v', 'mpeg', 'x-ms-wmv', 'quicktime']
- },
- 'ie' : {
- audio: ['mpeg'],
- video: ['mp4', 'm4v', 'mpeg']
- }
- },
-
- isCompatible: function ( media ) {
- if ( ! media.find( 'source' ).length ) {
- return false;
- }
-
- var ua = this.ua, test = false, found = false, sources;
-
- if ( ua.is( 'oldIE' ) ) {
- return false;
- }
-
- sources = media.find( 'source' );
-
- _.find( this.compat, function (supports, browser) {
- if ( ua.is( browser ) ) {
- found = true;
- _.each( sources, function (elem) {
- var audio = new RegExp( 'audio\/(' + supports.audio.join('|') + ')', 'gi' ),
- video = new RegExp( 'video\/(' + supports.video.join('|') + ')', 'gi' );
-
- if ( elem.type.match( video ) !== null || elem.type.match( audio ) !== null ) {
- test = true;
- }
- } );
- }
-
- return test || found;
- } );
-
- return test;
- },
-
- /**
- * Override the MediaElement method for removing a player.
- * MediaElement tries to pull the audio/video tag out of
- * its container and re-add it to the DOM.
- */
- removePlayer: function() {
- var t = this.player, featureIndex, feature;
-
- // invoke features cleanup
- for ( featureIndex in t.options.features ) {
- feature = t.options.features[featureIndex];
- if ( t['clean' + feature] ) {
- try {
- t['clean' + feature](t);
- } catch (e) {}
- }
- }
-
- if ( ! t.isDynamic ) {
- t.$node.remove();
- }
-
- if ( 'native' !== t.media.pluginType ) {
- t.media.remove();
- }
-
- delete window.mejs.players[t.id];
-
- t.container.remove();
- t.globalUnbind();
- delete t.node.player;
- },
-
- /**
- * Allows any class that has set 'player' to a MediaElementPlayer
- * instance to remove the player when listening to events.
- *
- * Examples: modal closes, shortcode properties are removed, etc.
- */
- unsetPlayer : function() {
- if ( this.player ) {
- wp.media.mixin.pauseAllPlayers();
- wp.media.mixin.removePlayer.apply( this );
- this.player = false;
- }
- }
- };
-
</del><span class="cx"> wp.media.collection = function(attributes) {
</span><span class="cx"> var collections = {};
</span><span class="cx">
</span><span class="cx"> return _.extend( attributes, {
</span><del>- coerce : wp.media.mixin.coerce,
</del><ins>+ coerce : wp.media.coerce,
</ins><span class="cx"> /**
</span><span class="cx"> * Retrieve attachments based on the properties of the passed shortcode
</span><span class="cx"> *
</span><span class="lines">@@ -669,134 +524,7 @@
</span><span class="cx"> }
</span><span class="cx"> });
</span><span class="cx">
</span><del>- wp.media.playlist = new wp.media.collection({
- tag: 'playlist',
- type : 'audio',
- editTitle : wp.media.view.l10n.editPlaylistTitle,
- defaults : {
- id: wp.media.view.settings.post.id,
- style: 'light',
- tracklist: true,
- tracknumbers: true,
- images: true,
- artists: true
- }
- });
-
- wp.media['video-playlist'] = new wp.media.collection({
- tag: 'video-playlist',
- type : 'video',
- editTitle : wp.media.view.l10n.editVideoPlaylistTitle,
- defaults : {
- id: wp.media.view.settings.post.id,
- style: 'light',
- tracklist: false,
- tracknumbers: false,
- images: true
- }
- });
-
</del><span class="cx"> /**
</span><del>- * @namespace
- */
- wp.media.audio = {
- coerce : wp.media.mixin.coerce,
-
- defaults : {
- id : wp.media.view.settings.post.id,
- src : '',
- loop : false,
- autoplay : false,
- preload : 'none'
- },
-
- edit : function (data) {
- var frame, shortcode = wp.shortcode.next( 'audio', data ).shortcode;
- frame = wp.media({
- frame: 'audio',
- state: 'audio-details',
- metadata: _.defaults(
- shortcode.attrs.named,
- wp.media.audio.defaults
- )
- });
-
- return frame;
- },
-
- shortcode : function (shortcode) {
- var self = this;
-
- _.each( wp.media.audio.defaults, function( value, key ) {
- shortcode[ key ] = self.coerce( shortcode, key );
-
- if ( value === shortcode[ key ] ) {
- delete shortcode[ key ];
- }
- });
-
- return wp.shortcode.string({
- tag: 'audio',
- attrs: shortcode
- });
- }
- };
-
- /**
- * @namespace
- */
- wp.media.video = {
- coerce : wp.media.mixin.coerce,
-
- defaults : {
- id : wp.media.view.settings.post.id,
- src : '',
- poster : '',
- loop : false,
- autoplay : false,
- preload : 'metadata',
- content : ''
- },
-
- edit : function (data) {
- var frame,
- defaults = this.defaults,
- shortcode = wp.shortcode.next( 'video', data ).shortcode,
- attrs;
-
- attrs = shortcode.attrs.named;
- attrs.content = shortcode.content;
-
- frame = wp.media({
- frame: 'video',
- state: 'video-details',
- metadata: _.defaults( attrs, defaults )
- });
-
- return frame;
- },
-
- shortcode : function (shortcode) {
- var self = this, content = shortcode.content;
- delete shortcode.content;
-
- _.each( this.defaults, function( value, key ) {
- shortcode[ key ] = self.coerce( shortcode, key );
-
- if ( value === shortcode[ key ] ) {
- delete shortcode[ key ];
- }
- });
-
- return wp.shortcode.string({
- tag: 'video',
- attrs: shortcode,
- content: content
- });
- }
- };
-
- /**
</del><span class="cx"> * wp.media.featuredImage
</span><span class="cx"> * @namespace
</span><span class="cx"> */
</span><span class="lines">@@ -1279,17 +1007,10 @@
</span><span class="cx"> if ( elem.hasClass( 'gallery' ) ) {
</span><span class="cx"> options.state = 'gallery';
</span><span class="cx"> options.title = wp.media.view.l10n.createGalleryTitle;
</span><del>- } else if ( elem.hasClass( 'playlist' ) ) {
- options.state = 'playlist';
- options.title = wp.media.view.l10n.createPlaylistTitle;
- } else if ( elem.hasClass( 'video-playlist' ) ) {
- options.state = 'video-playlist';
- options.title = wp.media.view.l10n.createVideoPlaylistTitle;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> wp.media.editor.open( editor, options );
</span><del>- })
- .on( 'click', '.wp-switch-editor', wp.media.mixin.pauseAllPlayers );
</del><ins>+ });
</ins><span class="cx">
</span><span class="cx"> // Initialize and render the Editor drag-and-drop uploader.
</span><span class="cx"> new wp.media.view.EditorUploader().render();
</span></span></pre></div>
<a id="trunksrcwpincludesjsmediamodelsjs"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/js/media-models.js (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/js/media-models.js 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/js/media-models.js 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -40,6 +40,8 @@
</span><span class="cx">
</span><span class="cx"> delete attributes.frame;
</span><span class="cx">
</span><ins>+ media.frame = frame;
+
</ins><span class="cx"> return frame;
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -453,44 +455,6 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> /**
</span><del>- * wp.media.model.PostMedia
- *
- * @constructor
- * @augments Backbone.Model
- **/
- media.model.PostMedia = Backbone.Model.extend({
- initialize: function() {
- this.attachment = false;
- },
-
- setSource: function ( attachment ) {
- this.attachment = attachment;
- this.extension = attachment.get('filename' ).split('.').pop();
-
- if ( this.get( 'src' ) && this.extension === this.get( 'src' ).split('.').pop() ) {
- this.unset( 'src' );
- }
-
- if ( _.contains( wp.media.view.settings.embedExts, this.extension ) ) {
- this.set( this.extension, this.attachment.get( 'url' ) );
- } else {
- this.unset( this.extension );
- }
- },
-
- changeAttachment: function( attachment ) {
- var self = this;
-
- this.setSource( attachment );
-
- this.unset( 'src' );
- _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function (ext) {
- self.unset( ext );
- } );
- }
- });
-
- /**
</del><span class="cx"> * wp.media.model.Attachments
</span><span class="cx"> *
</span><span class="cx"> * @constructor
</span></span></pre></div>
<a id="trunksrcwpincludesjsmediaviewsjs"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/js/media-views.js (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/js/media-views.js 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/js/media-views.js 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -766,58 +766,6 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> /**
</span><del>- * wp.media.controller.AudioDetails
- *
- * @constructor
- * @augments wp.media.controller.State
- * @augments Backbone.Model
- */
- media.controller.AudioDetails = media.controller.State.extend({
- defaults: _.defaults({
- id: 'audio-details',
- toolbar: 'audio-details',
- title: l10n.audioDetailsTitle,
- content: 'audio-details',
- menu: 'audio-details',
- router: false,
- attachment: false,
- priority: 60,
- editing: false
- }, media.controller.Library.prototype.defaults ),
-
- initialize: function( options ) {
- this.media = options.media;
- media.controller.State.prototype.initialize.apply( this, arguments );
- }
- });
-
- /**
- * wp.media.controller.VideoDetails
- *
- * @constructor
- * @augments wp.media.controller.State
- * @augments Backbone.Model
- */
- media.controller.VideoDetails = media.controller.State.extend({
- defaults: _.defaults({
- id: 'video-details',
- toolbar: 'video-details',
- title: l10n.videoDetailsTitle,
- content: 'video-details',
- menu: 'video-details',
- router: false,
- attachment: false,
- priority: 60,
- editing: false
- }, media.controller.Library.prototype.defaults ),
-
- initialize: function( options ) {
- this.media = options.media;
- media.controller.State.prototype.initialize.apply( this, arguments );
- }
- });
-
- /**
</del><span class="cx"> * wp.media.controller.CollectionEdit
</span><span class="cx"> *
</span><span class="cx"> * @constructor
</span><span class="lines">@@ -1930,7 +1878,7 @@
</span><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> createStates: function() {
</span><del>- var options = this.options;
</del><ins>+ var options = this.options, counts;
</ins><span class="cx">
</span><span class="cx"> // Add the default states.
</span><span class="cx"> this.states.add([
</span><span class="lines">@@ -1990,76 +1938,19 @@
</span><span class="cx"> type: 'image',
</span><span class="cx"> collectionType: 'gallery',
</span><span class="cx"> title: l10n.addToGalleryTitle
</span><del>- }),
</del><ins>+ })
+ ]);
</ins><span class="cx">
</span><del>- new media.controller.Library({
- id: 'playlist',
- title: l10n.createPlaylistTitle,
- priority: 60,
- toolbar: 'main-playlist',
- filterable: 'uploaded',
- multiple: 'add',
- editable: false,
</del><ins>+ counts = media.playlist.counts();
</ins><span class="cx">
</span><del>- library: media.query( _.defaults({
- type: 'audio'
- }, options.library ) )
- }),
</del><ins>+ if ( counts.audio ) {
+ this.states.add( media.playlist.states(options) );
+ }
</ins><span class="cx">
</span><del>- // Playlist states.
- new media.controller.CollectionEdit({
- type: 'audio',
- collectionType: 'playlist',
- title: l10n.editPlaylistTitle,
- SettingsView: media.view.Settings.Playlist,
- library: options.selection,
- editing: options.editing,
- menu: 'playlist',
- dragInfoText: l10n.playlistDragInfo,
- dragInfo: false
- }),
</del><ins>+ if ( counts.video ) {
+ this.states.add( media.playlist.videoStates(options) );
+ }
</ins><span class="cx">
</span><del>- new media.controller.CollectionAdd({
- type: 'audio',
- collectionType: 'playlist',
- title: l10n.addToPlaylistTitle
- }),
-
- new media.controller.Library({
- id: 'video-playlist',
- title: l10n.createVideoPlaylistTitle,
- priority: 60,
- toolbar: 'main-video-playlist',
- filterable: 'uploaded',
- multiple: 'add',
- editable: false,
-
- library: media.query( _.defaults({
- type: 'video'
- }, options.library ) )
- }),
-
- // Video Playlist states.
- new media.controller.CollectionEdit({
- type: 'video',
- collectionType: 'video-playlist',
- title: l10n.editVideoPlaylistTitle,
- SettingsView: media.view.Settings.Playlist,
- library: options.selection,
- editing: options.editing,
- menu: 'video-playlist',
- dragInfoText: l10n.videoPlaylistDragInfo,
- dragInfo: false
- }),
-
- new media.controller.CollectionAdd({
- type: 'video',
- collectionType: 'video-playlist',
- title: l10n.addToVideoPlaylistTitle
- })
- ]);
-
-
</del><span class="cx"> if ( media.view.settings.post.featuredImageId ) {
</span><span class="cx"> this.states.add( new media.controller.FeaturedImage() );
</span><span class="cx"> }
</span><span class="lines">@@ -2746,391 +2637,6 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> /**
</span><del>- * wp.media.view.MediaFrame.MediaDetails
- *
- * @constructor
- * @augments wp.media.view.MediaFrame.Select
- * @augments wp.media.view.MediaFrame
- * @augments wp.media.view.Frame
- * @augments wp.media.View
- * @augments wp.Backbone.View
- * @augments Backbone.View
- * @mixes wp.media.controller.StateMachine
- */
- media.view.MediaFrame.MediaDetails = media.view.MediaFrame.Select.extend({
- defaults: {
- id: 'media',
- url: '',
- menu: 'media-details',
- content: 'media-details',
- toolbar: 'media-details',
- type: 'link',
- priority: 120
- },
-
- initialize: function( options ) {
- this.DetailsView = options.DetailsView;
- this.cancelText = options.cancelText;
- this.addText = options.addText;
-
- this.media = new media.model.PostMedia( options.metadata );
- this.options.selection = new media.model.Selection( this.media.attachment, { multiple: false } );
- media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
- },
-
- bindHandlers: function() {
- var menu = this.defaults.menu;
-
- media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments );
-
- this.on( 'menu:create:' + menu, this.createMenu, this );
- this.on( 'content:render:' + menu, this.renderDetailsContent, this );
- this.on( 'menu:render:' + menu, this.renderMenu, this );
- this.on( 'toolbar:render:' + menu, this.renderDetailsToolbar, this );
- },
-
- renderDetailsContent: function() {
- var view = new this.DetailsView({
- controller: this,
- model: this.state().media,
- attachment: this.state().media.attachment
- }).render();
-
- this.content.set( view );
- },
-
- renderMenu: function( view ) {
- var lastState = this.lastState(),
- previous = lastState && lastState.id,
- frame = this;
-
- view.set({
- cancel: {
- text: this.cancelText,
- priority: 20,
- click: function() {
- if ( previous ) {
- frame.setState( previous );
- } else {
- frame.close();
- }
- }
- },
- separateCancel: new media.View({
- className: 'separator',
- priority: 40
- })
- });
-
- },
-
- renderDetailsToolbar: function() {
- this.toolbar.set( new media.view.Toolbar({
- controller: this,
- items: {
- select: {
- style: 'primary',
- text: l10n.update,
- priority: 80,
-
- click: function() {
- var controller = this.controller,
- state = controller.state();
-
- controller.close();
-
- state.trigger( 'update', controller.media.toJSON() );
-
- // Restore and reset the default state.
- controller.setState( controller.options.state );
- controller.reset();
- }
- }
- }
- }) );
- },
-
- renderReplaceToolbar: function() {
- this.toolbar.set( new media.view.Toolbar({
- controller: this,
- items: {
- replace: {
- style: 'primary',
- text: l10n.replace,
- priority: 80,
-
- click: function() {
- var controller = this.controller,
- state = controller.state(),
- selection = state.get( 'selection' ),
- attachment = selection.single();
-
- controller.media.changeAttachment( attachment );
-
- state.trigger( 'replace', controller.media.toJSON() );
-
- // Restore and reset the default state.
- controller.setState( controller.options.state );
- controller.reset();
- }
- }
- }
- }) );
- },
-
- renderAddSourceToolbar: function() {
- this.toolbar.set( new media.view.Toolbar({
- controller: this,
- items: {
- replace: {
- style: 'primary',
- text: this.addText,
- priority: 80,
-
- click: function() {
- var controller = this.controller,
- state = controller.state(),
- selection = state.get( 'selection' ),
- attachment = selection.single();
-
- controller.media.setSource( attachment );
-
- state.trigger( 'add-source', controller.media.toJSON() );
-
- // Restore and reset the default state.
- controller.setState( controller.options.state );
- controller.reset();
- }
- }
- }
- }) );
- }
- });
-
- /**
- * wp.media.view.MediaFrame.AudioDetails
- *
- * @constructor
- * @augments wp.media.view.MediaFrame.MediaDetails
- * @augments wp.media.view.MediaFrame.Select
- * @augments wp.media.view.MediaFrame
- * @augments wp.media.view.Frame
- * @augments wp.media.View
- * @augments wp.Backbone.View
- * @augments Backbone.View
- * @mixes wp.media.controller.StateMachine
- */
- media.view.MediaFrame.AudioDetails = media.view.MediaFrame.MediaDetails.extend({
- defaults: {
- id: 'audio',
- url: '',
- menu: 'audio-details',
- content: 'audio-details',
- toolbar: 'audio-details',
- type: 'link',
- title: l10n.audioDetailsTitle,
- priority: 120
- },
-
- initialize: function( options ) {
- options.DetailsView = media.view.AudioDetails;
- options.cancelText = l10n.audioDetailsCancel;
- options.addText = l10n.audioAddSourceTitle;
-
- media.view.MediaFrame.MediaDetails.prototype.initialize.call( this, options );
- },
-
- bindHandlers: function() {
- media.view.MediaFrame.MediaDetails.prototype.bindHandlers.apply( this, arguments );
-
- this.on( 'toolbar:render:replace-audio', this.renderReplaceToolbar, this );
- this.on( 'toolbar:render:add-audio-source', this.renderAddSourceToolbar, this );
- },
-
- createStates: function() {
- this.states.add([
- new media.controller.AudioDetails( {
- media: this.media,
- editable: false,
- menu: 'audio-details'
- } ),
-
- new media.controller.MediaLibrary( {
- type: 'audio',
- id: 'replace-audio',
- title: l10n.audioReplaceTitle,
- toolbar: 'replace-audio',
- media: this.media,
- menu: 'audio-details'
- } ),
-
- new media.controller.MediaLibrary( {
- type: 'audio',
- id: 'add-audio-source',
- title: l10n.audioAddSourceTitle,
- toolbar: 'add-audio-source',
- media: this.media,
- menu: 'audio-details'
- } )
- ]);
- }
- });
-
- /**
- * wp.media.view.MediaFrame.VideoDetails
- *
- * @constructor
- * @augments wp.media.view.MediaFrame.MediaDetails
- * @augments wp.media.view.MediaFrame.Select
- * @augments wp.media.view.MediaFrame
- * @augments wp.media.view.Frame
- * @augments wp.media.View
- * @augments wp.Backbone.View
- * @augments Backbone.View
- * @mixes wp.media.controller.StateMachine
- */
- media.view.MediaFrame.VideoDetails = media.view.MediaFrame.MediaDetails.extend({
- defaults: {
- id: 'video',
- url: '',
- menu: 'video-details',
- content: 'video-details',
- toolbar: 'video-details',
- type: 'link',
- title: l10n.videoDetailsTitle,
- priority: 120
- },
-
- initialize: function( options ) {
- options.DetailsView = media.view.VideoDetails;
- options.cancelText = l10n.videoDetailsCancel;
- options.addText = l10n.videoAddSourceTitle;
-
- media.view.MediaFrame.MediaDetails.prototype.initialize.call( this, options );
- },
-
- bindHandlers: function() {
- media.view.MediaFrame.MediaDetails.prototype.bindHandlers.apply( this, arguments );
-
- this.on( 'toolbar:render:replace-video', this.renderReplaceToolbar, this );
- this.on( 'toolbar:render:add-video-source', this.renderAddSourceToolbar, this );
- this.on( 'toolbar:render:select-poster-image', this.renderSelectPosterImageToolbar, this );
- this.on( 'toolbar:render:add-track', this.renderAddTrackToolbar, this );
- },
-
- createStates: function() {
- this.states.add([
- new media.controller.VideoDetails({
- media: this.media,
- editable: false,
- menu: 'video-details'
- }),
-
- new media.controller.MediaLibrary( {
- type: 'video',
- id: 'replace-video',
- title: l10n.videoReplaceTitle,
- toolbar: 'replace-video',
- media: this.media,
- menu: 'video-details'
- } ),
-
- new media.controller.MediaLibrary( {
- type: 'video',
- id: 'add-video-source',
- title: l10n.videoAddSourceTitle,
- toolbar: 'add-video-source',
- media: this.media,
- menu: 'video-details'
- } ),
-
- new media.controller.MediaLibrary( {
- type: 'image',
- id: 'select-poster-image',
- title: l10n.videoSelectPosterImageTitle,
- toolbar: 'select-poster-image',
- media: this.media,
- menu: 'video-details'
- } ),
-
- new media.controller.MediaLibrary( {
- type: 'text',
- id: 'add-track',
- title: l10n.videoAddTrackTitle,
- toolbar: 'add-track',
- media: this.media,
- menu: 'video-details'
- } )
- ]);
- },
-
- renderSelectPosterImageToolbar: function() {
- this.toolbar.set( new media.view.Toolbar({
- controller: this,
- items: {
- replace: {
- style: 'primary',
- text: l10n.videoSelectPosterImageTitle,
- priority: 80,
-
- click: function() {
- var controller = this.controller,
- state = controller.state(),
- selection = state.get( 'selection' ),
- attachment = selection.single();
-
- controller.media.set( 'poster', attachment.get( 'url' ) );
-
- state.trigger( 'set-poster-image', controller.media.toJSON() );
-
- // Restore and reset the default state.
- controller.setState( controller.options.state );
- controller.reset();
- }
- }
- }
- }) );
- },
-
- renderAddTrackToolbar: function() {
- this.toolbar.set( new media.view.Toolbar({
- controller: this,
- items: {
- replace: {
- style: 'primary',
- text: l10n.videoAddTrackTitle,
- priority: 80,
-
- click: function() {
- var controller = this.controller,
- state = controller.state(),
- selection = state.get( 'selection' ),
- attachment = selection.single(),
- content = controller.media.get( 'content' );
-
- if ( -1 === content.indexOf( attachment.get( 'url' ) ) ) {
- content += [
- '<track srclang="en" label="English"kind="subtitles" src="',
- attachment.get( 'url' ),
- '" />'
- ].join('');
-
- controller.media.set( 'content', content );
- }
-
- state.trigger( 'add-track', controller.media.toJSON() );
-
- // Restore and reset the default state.
- controller.setState( controller.options.state );
- controller.reset();
- }
- }
- }
- }) );
- }
- });
-
- /**
</del><span class="cx"> * wp.media.view.Modal
</span><span class="cx"> *
</span><span class="cx"> * @constructor
</span><span class="lines">@@ -6663,75 +6169,6 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> /**
</span><del>- * wp.media.view.AudioDetails
- *
- * @contructor
- * @augments wp.media.view.MediaDetails
- * @augments wp.media.view.Settings.AttachmentDisplay
- * @augments wp.media.view.Settings
- * @augments wp.media.View
- * @augments wp.Backbone.View
- * @augments Backbone.View
- */
- media.view.AudioDetails = media.view.MediaDetails.extend({
- className: 'audio-details',
- template: media.template('audio-details'),
-
- setMedia: function() {
- var audio = this.$('.wp-audio-shortcode');
-
- if ( audio.find( 'source' ).length ) {
- if ( audio.is(':hidden') ) {
- audio.show();
- }
- this.media = media.view.MediaDetails.prepareSrc( audio.get(0) );
- } else {
- audio.hide();
- this.media = false;
- }
-
- return this;
- }
- });
-
- /**
- * wp.media.view.VideoDetails
- *
- * @contructor
- * @augments wp.media.view.MediaDetails
- * @augments wp.media.view.Settings.AttachmentDisplay
- * @augments wp.media.view.Settings
- * @augments wp.media.View
- * @augments wp.Backbone.View
- * @augments Backbone.View
- */
- media.view.VideoDetails = media.view.MediaDetails.extend({
- className: 'video-details',
- template: media.template('video-details'),
-
- setMedia: function() {
- var video = this.$('.wp-video-shortcode');
-
- if ( video.find( 'source' ).length ) {
- if ( video.is(':hidden') ) {
- video.show();
- }
-
- if ( ! video.hasClass('youtube-video') ) {
- this.media = media.view.MediaDetails.prepareSrc( video.get(0) );
- } else {
- this.media = video.get(0);
- }
- } else {
- video.hide();
- this.media = false;
- }
-
- return this;
- }
- });
-
- /**
</del><span class="cx"> * wp.media.view.Spinner
</span><span class="cx"> *
</span><span class="cx"> * @constructor
</span></span></pre></div>
<a id="trunksrcwpincludesjsmediaelementwpmediaelementcss"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/js/mediaelement/wp-mediaelement.css 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx">
</span><span class="cx"> .media-embed-details .embed-media-settings {
</span><span class="cx"> padding-top: 0;
</span><ins>+ top: 28px;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> .media-embed-details .instructions {
</span><span class="lines">@@ -44,10 +45,6 @@
</span><span class="cx"> color: #f00;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-.media-embed-details .embed-media-settings {
- top: 0;
-}
-
</del><span class="cx"> .media-embed-details .embed-media-settings .checkbox-setting {
</span><span class="cx"> width: 100px;
</span><span class="cx"> clear: none;
</span></span></pre></div>
<a id="trunksrcwpincludesmediatemplatephp"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/media-template.php (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/media-template.php 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/media-template.php 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -765,14 +765,19 @@
</span><span class="cx"> </script>
</span><span class="cx">
</span><span class="cx"> <script type="text/html" id="tmpl-audio-details">
</span><ins>+ <# var ext, html5types = { mp3: true, ogg: true }; #>
+
</ins><span class="cx"> <?php $audio_types = wp_get_audio_extensions(); ?>
</span><span class="cx"> <div class="media-embed media-embed-details">
</span><span class="cx"> <div class="embed-media-settings embed-audio-settings">
</span><del>- <div class="instructions media-instructions">{{{ wp.media.view.l10n.audioDetailsText }}}</div>
-
</del><span class="cx"> <?php wp_underscore_audio_template() ?>
</span><span class="cx">
</span><del>- <# if ( ! _.isEmpty( data.model.src ) ) { #>
</del><ins>+ <# if ( ! _.isEmpty( data.model.src ) ) {
+ ext = data.model.src.split('.').pop();
+ if ( html5types[ ext ] ) {
+ delete html5types[ ext ];
+ }
+ #>
</ins><span class="cx"> <label class="setting">
</span><span class="cx"> <span>SRC</span>
</span><span class="cx"> <input type="text" disabled="disabled" data-setting="src" value="{{ data.model.src }}" />
</span><span class="lines">@@ -782,7 +787,11 @@
</span><span class="cx"> <?php
</span><span class="cx">
</span><span class="cx"> foreach ( $audio_types as $type ):
</span><del>- ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) { #>
</del><ins>+ ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) {
+ if ( ! _.isUndefined( html5types.<?php echo $type ?> ) ) {
+ delete html5types.<?php echo $type ?>;
+ }
+ #>
</ins><span class="cx"> <label class="setting">
</span><span class="cx"> <span><?php echo strtoupper( $type ) ?></span>
</span><span class="cx"> <input type="text" disabled="disabled" data-setting="<?php echo $type ?>" value="{{ data.model.<?php echo $type ?> }}" />
</span><span class="lines">@@ -791,6 +800,17 @@
</span><span class="cx"> <# } #>
</span><span class="cx"> <?php endforeach ?>
</span><span class="cx">
</span><ins>+ <# if ( ! _.isEmpty( html5types ) ) { #>
+ <div class="setting">
+ <span>{{{ wp.media.view.l10n.mediaHTML5Text }}}</span>
+ <div class="button-large">
+ <# _.each( html5types, function (value, type) { #>
+ <button class="button add-media-source">{{ type }}</button>
+ <# } ) #>
+ </div>
+ </div>
+ <# } #>
+
</ins><span class="cx"> <div class="setting preload">
</span><span class="cx"> <span><?php _e( 'Preload' ); ?></span>
</span><span class="cx"> <div class="button-group button-large" data-setting="preload">
</span><span class="lines">@@ -815,10 +835,11 @@
</span><span class="cx"> </script>
</span><span class="cx">
</span><span class="cx"> <script type="text/html" id="tmpl-video-details">
</span><ins>+ <# var ext, html5types = { mp4: true, ogv: true, webm: true }; #>
+
</ins><span class="cx"> <?php $video_types = wp_get_video_extensions(); ?>
</span><span class="cx"> <div class="media-embed media-embed-details">
</span><span class="cx"> <div class="embed-media-settings embed-video-settings">
</span><del>- <div class="instructions media-instructions">{{{ wp.media.view.l10n.videoDetailsText }}}</div>
</del><span class="cx"> <div class="wp-video-holder">
</span><span class="cx"> <#
</span><span class="cx"> var isYouTube = ! _.isEmpty( data.model.src ) && data.model.src.match(/youtube|youtu\.be/);
</span><span class="lines">@@ -832,7 +853,12 @@
</span><span class="cx">
</span><span class="cx"> <?php wp_underscore_video_template() ?>
</span><span class="cx">
</span><del>- <# if ( ! _.isEmpty( data.model.src ) ) { #>
</del><ins>+ <# if ( ! _.isEmpty( data.model.src ) ) {
+ ext = data.model.src.split('.').pop();
+ if ( html5types[ ext ] ) {
+ delete html5types[ ext ];
+ }
+ #>
</ins><span class="cx"> <label class="setting">
</span><span class="cx"> <span>SRC</span>
</span><span class="cx"> <input type="text" disabled="disabled" data-setting="src" value="{{ data.model.src }}" />
</span><span class="lines">@@ -840,7 +866,11 @@
</span><span class="cx"> </label>
</span><span class="cx"> <# } #>
</span><span class="cx"> <?php foreach ( $video_types as $type ):
</span><del>- ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) { #>
</del><ins>+ ?><# if ( ! _.isEmpty( data.model.<?php echo $type ?> ) ) {
+ if ( ! _.isUndefined( html5types.<?php echo $type ?> ) ) {
+ delete html5types.<?php echo $type ?>;
+ }
+ #>
</ins><span class="cx"> <label class="setting">
</span><span class="cx"> <span><?php echo strtoupper( $type ) ?></span>
</span><span class="cx"> <input type="text" disabled="disabled" data-setting="<?php echo $type ?>" value="{{ data.model.<?php echo $type ?> }}" />
</span><span class="lines">@@ -849,6 +879,18 @@
</span><span class="cx"> <# } #>
</span><span class="cx"> <?php endforeach ?>
</span><span class="cx"> </div>
</span><ins>+
+ <# if ( ! _.isEmpty( html5types ) ) { #>
+ <div class="setting">
+ <span>{{{ wp.media.view.l10n.mediaHTML5Text }}}</span>
+ <div class="button-large">
+ <# _.each( html5types, function (value, type) { #>
+ <button class="button add-media-source">{{ type }}</button>
+ <# } ) #>
+ </div>
+ </div>
+ <# } #>
+
</ins><span class="cx"> <# if ( ! _.isEmpty( data.model.poster ) ) { #>
</span><span class="cx"> <label class="setting">
</span><span class="cx"> <span><?php _e( 'Poster Image' ); ?></span>
</span></span></pre></div>
<a id="trunksrcwpincludesmediaphp"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/media.php (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/media.php 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/media.php 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -2400,6 +2400,7 @@
</span><span class="cx"> 'id' => 0,
</span><span class="cx"> ),
</span><span class="cx"> 'defaultProps' => $props,
</span><ins>+ 'attachmentCounts' => wp_count_attachments(),
</ins><span class="cx"> 'embedExts' => $exts,
</span><span class="cx"> 'embedMimes' => $ext_mimes
</span><span class="cx"> );
</span><span class="lines">@@ -2495,21 +2496,19 @@
</span><span class="cx"> /* translators: suggested height of header image in pixels */
</span><span class="cx"> 'suggestedHeight' => __( 'Suggested height is %d pixels.' ),
</span><span class="cx">
</span><ins>+ 'mediaHTML5Text' => __( 'Add alternate sources for maximum HTML5 playback:' ),
+
</ins><span class="cx"> // Edit Audio
</span><span class="cx"> 'audioDetailsTitle' => __( 'Audio Details' ),
</span><span class="cx"> 'audioReplaceTitle' => __( 'Replace Audio' ),
</span><span class="cx"> 'audioAddSourceTitle' => __( 'Add Audio Source' ),
</span><span class="cx"> 'audioDetailsCancel' => __( 'Cancel Edit' ),
</span><del>- 'audioDetailsText' => __( '"Replace Audio" will remove all associated source files when you update. ' .
- '"Add Audio Source" allows you to specify alternate sources for maximum native HTML5 audio playback.' ),
</del><span class="cx">
</span><span class="cx"> // Edit Video
</span><span class="cx"> 'videoDetailsTitle' => __( 'Video Details' ),
</span><span class="cx"> 'videoReplaceTitle' => __( 'Replace Video' ),
</span><span class="cx"> 'videoAddSourceTitle' => __( 'Add Video Source' ),
</span><span class="cx"> 'videoDetailsCancel' => __( 'Cancel Edit' ),
</span><del>- 'videoDetailsText' => __( '"Replace Video" will remove all associated source files when you update. ' .
- '"Add Video Source" allows you to specify alternate sources for maximum native HTML5 video playback.' ),
</del><span class="cx"> 'videoSelectPosterImageTitle' => _( 'Select Poster Image' ),
</span><span class="cx"> 'videoAddTrackTitle' => __( 'Add Subtitles' ),
</span><span class="cx">
</span><span class="lines">@@ -2542,6 +2541,7 @@
</span><span class="cx"> wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings );
</span><span class="cx">
</span><span class="cx"> wp_enqueue_script( 'media-editor' );
</span><ins>+ wp_enqueue_script( 'media-audiovideo' );
</ins><span class="cx"> wp_enqueue_style( 'media-views' );
</span><span class="cx"> wp_enqueue_style( 'imgareaselect' );
</span><span class="cx"> wp_plupload_default_settings();
</span></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4>Modified: trunk/src/wp-includes/script-loader.php (27607 => 27608)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/src/wp-includes/script-loader.php 2014-03-19 05:28:36 UTC (rev 27607)
+++ trunk/src/wp-includes/script-loader.php 2014-03-19 05:30:27 UTC (rev 27608)
</span><span class="lines">@@ -396,6 +396,7 @@
</span><span class="cx"> // Both rely on numerous settings, styles, and templates to operate correctly.
</span><span class="cx"> $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'image-edit' ), false, 1 );
</span><span class="cx"> $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 );
</span><ins>+ $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 );
</ins><span class="cx"> $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models' ), false, 1 );
</span><span class="cx">
</span><span class="cx"> if ( is_admin() ) {
</span></span></pre>
</div>
</div>
</body>
</html>