diff --git a/src/wp-includes/js/media-audiovideo.js b/src/wp-includes/js/media-audiovideo.js index ac411ea9c5..c78406f41b 100644 --- a/src/wp-includes/js/media-audiovideo.js +++ b/src/wp-includes/js/media-audiovideo.js @@ -1,7 +1,13 @@ /* global _wpMediaViewsL10n, _wpmejsSettings, MediaElementPlayer, tinymce, WPPlaylistView */ -(function ($, _, Backbone) { - var media = wp.media, l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n; +(function($, _, Backbone) { + var media = wp.media, + baseSettings = {}, + l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n; + + if ( ! _.isUndefined( window._wpmejsSettings ) ) { + baseSettings.pluginPath = _wpmejsSettings.pluginPath; + } /** * @mixin @@ -11,7 +17,7 @@ /** * Pauses every instance of MediaElementPlayer */ - pauseAllPlayers: function () { + pauseAllPlayers: function() { var p; if ( window.mejs && window.mejs.players ) { for ( p in window.mejs.players ) { @@ -24,7 +30,7 @@ * Utility to identify the user's browser */ ua: { - is : function (browser) { + is : function( browser ) { var passes = false, ua = window.navigator.userAgent; switch ( browser ) { @@ -44,7 +50,7 @@ passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) === null; break; case 'chrome': - passes = ua.match(/safari/gi) && ua.match(/chrome/gi) !== null; + passes = ua.match(/safari/gi) !== null && ua.match(/chrome/gi) !== null; break; } @@ -85,7 +91,7 @@ * @param {jQuery} media * @returns {Boolean} */ - isCompatible: function ( media ) { + isCompatible: function( media ) { if ( ! media.find( 'source' ).length ) { return false; } @@ -98,10 +104,10 @@ sources = media.find( 'source' ); - _.find( this.compat, function (supports, browser) { + _.find( this.compat, function( supports, browser ) { if ( ua.is( browser ) ) { found = true; - _.each( sources, function (elem) { + _.each( sources, function( elem ) { var audio = new RegExp( 'audio\/(' + supports.audio.join('|') + ')', 'gi' ), video = new RegExp( 'video\/(' + supports.video.join('|') + ')', 'gi' ); @@ -214,21 +220,18 @@ caption : '' }, - edit : function (data) { + 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 - ) + metadata: _.defaults( shortcode.attrs.named, this.defaults ) }); return frame; }, - shortcode : function (model) { + shortcode : function( model ) { var self = this, content; _.each( this.defaults, function( value, key ) { @@ -268,12 +271,13 @@ autoplay : false, preload : 'metadata', content : '', - caption : '' + caption : '', + width : 640, + height : 360 }, - edit : function (data) { + edit : function( data ) { var frame, - defaults = this.defaults, shortcode = wp.shortcode.next( 'video', data ).shortcode, attrs; @@ -283,13 +287,13 @@ frame = wp.media({ frame: 'video', state: 'video-details', - metadata: _.defaults( attrs, defaults ) + metadata: _.defaults( attrs, this.defaults ) }); return frame; }, - shortcode : function (model) { + shortcode : function( model ) { var self = this, content; _.each( this.defaults, function( value, key ) { @@ -312,19 +316,20 @@ }; /** - * wp.media.model.PostMedia + * Shared model class for audio and video. Updates the model after + * "Add Audio|Video Source" and "Replace Audio|Video" states return * * @constructor * @augments Backbone.Model - **/ + */ media.model.PostMedia = Backbone.Model.extend({ initialize: function() { this.attachment = false; }, - setSource: function ( attachment ) { + setSource: function( attachment ) { this.attachment = attachment; - this.extension = attachment.get('filename' ).split('.').pop(); + this.extension = attachment.get( 'filename' ).split('.').pop(); if ( this.get( 'src' ) && this.extension === this.get( 'src' ).split('.').pop() ) { this.unset( 'src' ); @@ -343,31 +348,29 @@ this.setSource( attachment ); this.unset( 'src' ); - _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function (ext) { + _.each( _.without( wp.media.view.settings.embedExts, this.extension ), function( ext ) { self.unset( ext ); } ); } }); /** - * wp.media.controller.AudioDetails + * The controller for the Audio Details state * * @constructor * @augments wp.media.controller.State * @augments Backbone.Model */ media.controller.AudioDetails = media.controller.State.extend({ - defaults: _.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 ), + priority: 60 + }, initialize: function( options ) { this.media = options.media; @@ -376,24 +379,22 @@ }); /** - * wp.media.controller.VideoDetails + * The controller for the Video Details state * * @constructor * @augments wp.media.controller.State * @augments Backbone.Model */ media.controller.VideoDetails = media.controller.State.extend({ - defaults: _.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 ), + priority: 60 + }, initialize: function( options ) { this.media = options.media; @@ -480,23 +481,17 @@ }, - renderDetailsToolbar: function() { + setPrimaryButton: function(text, handler) { this.toolbar.set( new media.view.Toolbar({ controller: this, items: { - select: { + button: { style: 'primary', - text: l10n.update, + text: text, priority: 80, - - click: function() { - var controller = this.controller, - state = controller.state(); - - controller.close(); - - state.trigger( 'update', controller.media.toJSON() ); - + click: function() { + var controller = this.controller; + handler.call( this, controller, controller.state() ); // Restore and reset the default state. controller.setState( controller.options.state ); controller.reset(); @@ -506,60 +501,27 @@ }) ); }, + renderDetailsToolbar: function() { + this.setPrimaryButton( l10n.update, function( controller, state ) { + controller.close(); + state.trigger( 'update', controller.media.toJSON() ); + } ); + }, + 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(); - } - } - } - }) ); + this.setPrimaryButton( l10n.replace, function( controller, state ) { + var attachment = state.get( 'selection' ).single(); + controller.media.changeAttachment( attachment ); + state.trigger( 'replace', controller.media.toJSON() ); + } ); }, 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(); - } - } - } - }) ); + this.setPrimaryButton( this.addText, function( controller, state ) { + var attachment = state.get( 'selection' ).single(); + controller.media.setSource( attachment ); + state.trigger( 'add-source', controller.media.toJSON() ); + } ); } }); @@ -606,9 +568,7 @@ createStates: function() { this.states.add([ new media.controller.AudioDetails( { - media: this.media, - editable: false, - menu: 'audio-details' + media: this.media } ), new media.controller.MediaLibrary( { @@ -677,9 +637,7 @@ createStates: function() { this.states.add([ new media.controller.VideoDetails({ - media: this.media, - editable: false, - menu: 'video-details' + media: this.media }), new media.controller.MediaLibrary( { @@ -721,68 +679,30 @@ }, renderSelectPosterImageToolbar: function() { - this.toolbar.set( new media.view.Toolbar({ - controller: this, - items: { - replace: { - style: 'primary', - text: l10n.videoSelectPosterImageTitle, - priority: 80, + this.setPrimaryButton( l10n.videoSelectPosterImageTitle, function( controller, state ) { + var attachment = state.get( 'selection' ).single(); - 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(); - } - } - } - }) ); + controller.media.set( 'poster', attachment.get( 'url' ) ); + state.trigger( 'set-poster-image', controller.media.toJSON() ); + } ); }, renderAddTrackToolbar: function() { - this.toolbar.set( new media.view.Toolbar({ - controller: this, - items: { - replace: { - style: 'primary', - text: l10n.videoAddTrackTitle, - priority: 80, + this.setPrimaryButton( l10n.videoAddTrackTitle, function( controller, state ) { + var attachment = state.get( 'selection' ).single(), + content = controller.media.get( 'content' ); - 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 += [ + '' + ].join(''); - if ( -1 === content.indexOf( attachment.get( 'url' ) ) ) { - content += [ - '' - ].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(); - } - } + controller.media.set( 'content', content ); } - }) ); + state.trigger( 'add-track', controller.media.toJSON() ); + } ); } }); @@ -827,9 +747,8 @@ * * @param {Event} e */ - removeSetting : function (e) { + removeSetting : function(e) { var wrap = $( e.currentTarget ).parent(), setting; - setting = wrap.find( 'input' ).data( 'setting' ); if ( setting ) { @@ -844,10 +763,10 @@ * * @fires wp.media.view.MediaDetails#media:setting:remove */ - setTracks : function () { + setTracks : function() { var tracks = ''; - _.each( this.$('.content-track'), function (track) { + _.each( this.$('.content-track'), function(track) { tracks += $( track ).val(); } ); @@ -858,7 +777,7 @@ /** * @global MediaElementPlayer */ - setPlayer : function () { + setPlayer : function() { if ( ! this.player && this.media ) { this.player = new MediaElementPlayer( this.media, this.settings ); } @@ -867,15 +786,15 @@ /** * @abstract */ - setMedia : function () { + setMedia : function() { return this; }, - success : function (mejs) { + success : function(mejs) { var autoplay = mejs.attributes.autoplay && 'false' !== mejs.attributes.autoplay; if ( 'flash' === mejs.pluginType && autoplay ) { - mejs.addEventListener( 'canplay', function () { + mejs.addEventListener( 'canplay', function() { mejs.play(); }, false ); } @@ -884,23 +803,17 @@ }, /** - * @global _wpmejsSettings - * * @returns {media.view.MediaDetails} Returns itself to allow chaining */ render: function() { - var self = this, settings = { - success : this.success - }; - - if ( ! _.isUndefined( window._wpmejsSettings ) ) { - settings.pluginPath = _wpmejsSettings.pluginPath; - } + var self = this; media.view.Settings.AttachmentDisplay.prototype.render.apply( this, arguments ); setTimeout( function() { self.resetFocus(); }, 10 ); - this.settings = settings; + this.settings = _.defaults( { + success : this.success + }, baseSettings ); return this.setMedia(); }, @@ -914,21 +827,21 @@ /** * When multiple players in the DOM contain the same src, things get weird. * - * @param {HTMLElement} media + * @param {HTMLElement} elem * @returns {HTMLElement} */ - prepareSrc : function (media) { - var i = wp.media.view.MediaDetails.instances++; - _.each( $(media).find('source'), function (source) { + prepareSrc : function( elem ) { + var i = media.view.MediaDetails.instances++; + _.each( $( elem ).find( 'source' ), function( source ) { source.src = [ source.src, source.src.indexOf('?') > -1 ? '&' : '?', '_=', i ].join(''); - }); + } ); - return media; + return elem; } }); @@ -1010,16 +923,16 @@ * @param {Object} settings * @returns {Object} */ - counts : (function (settings) { + counts : (function(settings) { var counts = {}; - return function () { + return function() { if ( ! _.isEmpty( counts ) ) { return counts; } var a = 0, v = 0; - _.each( settings.attachmentCounts, function (total, mime) { + _.each( settings.attachmentCounts, function(total, mime) { var type; if ( -1 < mime.indexOf('/') ) { type = mime.split('/')[0]; @@ -1050,7 +963,7 @@ * @param {Object} options * @returns {Array} */ - states : function (options) { + states : function(options) { return [ new media.controller.Library({ id: 'playlist', @@ -1093,7 +1006,7 @@ * @param {Object} options * @returns {Array} */ - videoStates : function (options) { + videoStates : function(options) { return [ new media.controller.Library({ id: 'video-playlist', @@ -1183,7 +1096,7 @@ data = window.decodeURIComponent( $( node ).attr('data-wpview-text') ); frame = media.edit( data ); - frame.on( 'close', function () { + frame.on( 'close', function() { frame.detach(); } ); frame.state( self.state ).on( 'update', function( selection ) { @@ -1219,7 +1132,7 @@ * @param {Event} e * @param {HTMLElement} node */ - setPlayer: function (e, node) { + setPlayer: function(e, node) { // if the ready event fires on an empty node if ( ! node ) { return; @@ -1227,7 +1140,7 @@ var self = this, media, - settings = {}, + firefox = this.ua.is( 'ff' ), className = '.wp-' + this.shortcode.tag + '-shortcode'; if ( this.player ) { @@ -1236,10 +1149,6 @@ media = $( node ).find( className ); - if ( ! _.isUndefined( window._wpmejsSettings ) ) { - settings.pluginPath = _wpmejsSettings.pluginPath; - } - if ( ! this.isCompatible( media ) ) { media.closest( '.wpview-wrap' ).addClass( 'wont-play' ); if ( ! media.parent().hasClass( 'wpview-wrap' ) ) { @@ -1249,7 +1158,7 @@ return; } else { media.closest( '.wpview-wrap' ).removeClass( 'wont-play' ); - if ( this.ua.is( 'ff' ) ) { + if ( firefox ) { media.prop( 'preload', 'metadata' ); } else { media.prop( 'preload', 'none' ); @@ -1259,9 +1168,13 @@ media = wp.media.view.MediaDetails.prepareSrc( media.get(0) ); // Thanks, Firefox! - setTimeout(function () { - self.player = new MediaElementPlayer( media, settings ); - }, 50); + if ( firefox ) { + setTimeout( function() { + self.player = new MediaElementPlayer( media, baseSettings ); + }, 50 ); + } else { + this.player = new MediaElementPlayer( media, baseSettings ); + } }, /** @@ -1270,7 +1183,10 @@ * @returns {string} */ getHtml: function() { - var attrs = this.shortcode.attrs.named; + var attrs = _.defaults( + this.shortcode.attrs.named, + wp.media[ this.shortcode.tag ].defaults + ); return this.template({ model: attrs }); } }); @@ -1332,7 +1248,7 @@ * @param {Event} e * @param {HTMLElement} node */ - setNode: function (e, node) { + setNode: function(e, node) { this.node = node; this.fetch(); }, @@ -1353,7 +1269,7 @@ * @global WPPlaylistView * @global tinymce.editors */ - setPlayer: function () { + setPlayer: function() { var p, html = this.getHtml(), t = this.encodedText, @@ -1365,7 +1281,7 @@ var doc; if ( editor.plugins.wpview ) { doc = editor.getDoc(); - $( doc ).find( '[data-wpview-text="' + t + '"]' ).each(function (i, elem) { + $( doc ).find( '[data-wpview-text="' + t + '"]' ).each(function(i, elem) { var node = $( elem ); node.html( html ); self.node = elem; @@ -1414,8 +1330,8 @@ artists: data.artists }; - _.each( attachments, function (attachment) { - var size = {}, track = { + _.each( attachments, function( attachment ) { + var size = {}, resize = {}, track = { src : attachment.url, type : attachment.mime, title : attachment.title, @@ -1425,15 +1341,24 @@ }; if ( 'video' === type ) { - if ( ! options.width ) { - options.width = attachment.width; - options.height = attachment.height; - } size.width = attachment.width; size.height = attachment.height; + if ( media.view.settings.contentWidth ) { + resize.width = media.view.settings.contentWidth - 22; + resize.height = Math.ceil( ( size.height * resize.width ) / size.width ); + if ( ! options.width ) { + options.width = resize.width; + options.height = resize.height; + } + } else { + if ( ! options.width ) { + options.width = attachment.width; + options.height = attachment.height; + } + } track.dimensions = { original : size, - resized : size + resized : _.isEmpty( resize ) ? size : resize }; } else { options.width = 400; @@ -1483,7 +1408,7 @@ function init() { $(document.body) .on( 'click', '.wp-switch-editor', wp.media.mixin.pauseAllPlayers ) - .on( 'click', '.add-media-source', function () { + .on( 'click', '.add-media-source', function() { media.frame.setState('add-' + media.frame.defaults.id + '-source'); } ); } diff --git a/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css b/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css index f758542193..fba7b06dac 100644 --- a/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css +++ b/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css @@ -164,6 +164,10 @@ embed { max-width: 100%; } +audio { + visibility: hidden; +} + /** * WP Views */ diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index 36d81e5974..82b3abe83d 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -48,14 +48,20 @@ function wp_underscore_audio_template() { function wp_underscore_video_template() { $video_types = wp_get_video_extensions(); ?> -<# -var isYouTube = ! _.isEmpty( data.model.src ) && data.model.src.match(/youtube|youtu\.be/); - w = ! data.model.width || data.model.width > 640 ? 640 : data.model.width, - h = ! data.model.height ? 360 : data.model.height; +<# var w, h, settings = wp.media.view.settings, + isYouTube = ! _.isEmpty( data.model.src ) && data.model.src.match(/youtube|youtu\.be/); -if ( data.model.width && w !== data.model.width ) { - h = Math.ceil( ( h * w ) / data.model.width ); -} + if ( settings.contentWidth && data.model.width >= settings.contentWidth ) { + w = settings.contentWidth; + } else { + w = data.model.width; + } + + if ( w !== data.model.width ) { + h = Math.ceil( ( h * w ) / data.model.width ); + } else { + h = data.model.height; + } #>