From f60e85b0e464428097fd4cf865d95b1f7cef9ace Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Sun, 30 Nov 2014 08:45:22 +0000 Subject: [PATCH] When creating audio and video MCE views, listen to the players within each iframe to capture the "play" event. When a player plays, pause the players in every other iframe sandbox. Fixes #29384. Built from https://develop.svn.wordpress.org/trunk@30642 git-svn-id: http://core.svn.wordpress.org/trunk@30632 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/js/mce-view.js | 63 ++++++++++++++++++++++++++++++++-- wp-includes/js/mce-view.min.js | 2 +- wp-includes/version.php | 2 +- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/wp-includes/js/mce-view.js b/wp-includes/js/mce-view.js index c522d85e57..ab33cb4bcf 100644 --- a/wp-includes/js/mce-view.js +++ b/wp-includes/js/mce-view.js @@ -14,6 +14,9 @@ window.wp = window.wp || {}; var views = {}, instances = {}, media = wp.media, + mediaWindows = [], + windowIdx = 0, + waitInterval = 50, viewOptions = ['encodedText']; // Create the `wp.mce` object if necessary. @@ -228,7 +231,7 @@ window.wp = window.wp || {}; iframeDoc.body.className = editor.getBody().className; }); } - }, 50 ); + }, waitInterval ); }); } else { this.setContent( body ); @@ -591,13 +594,68 @@ window.wp = window.wp || {}; this.fetch(); this.getEditors( function( editor ) { - editor.on( 'hide', self.stopPlayers ); + editor.on( 'hide', function () { + mediaWindows = []; + windowIdx = 0; + self.stopPlayers(); + } ); }); }, + pauseOtherWindows: function ( win ) { + _.each( mediaWindows, function ( mediaWindow ) { + if ( mediaWindow.sandboxId !== win.sandboxId ) { + _.each( mediaWindow.mejs.players, function ( player ) { + player.pause(); + } ); + } + } ); + }, + + iframeLoaded: function (win) { + return _.bind( function () { + var callback; + if ( ! win.mejs || _.isEmpty( win.mejs.players ) ) { + return; + } + + win.sandboxId = windowIdx; + windowIdx++; + mediaWindows.push( win ); + + callback = _.bind( function () { + this.pauseOtherWindows( win ); + }, this ); + + if ( ! _.isEmpty( win.mejs.MediaPluginBridge.pluginMediaElements ) ) { + _.each( win.mejs.MediaPluginBridge.pluginMediaElements, function ( mediaElement ) { + mediaElement.addEventListener( 'play', callback ); + } ); + } + + _.each( win.mejs.players, function ( player ) { + $( player.node ).on( 'play', callback ); + }, this ); + }, this ); + }, + + listenToSandboxes: function () { + _.each( this.getNodes(), function ( node ) { + var win, iframe = $( '.wpview-sandbox', node ).get( 0 ); + if ( iframe && ( win = iframe.contentWindow ) ) { + $( win ).load( _.bind( this.iframeLoaded( win ), this ) ); + } + }, this ); + }, + + deferredListen: function () { + window.setTimeout( _.bind( this.listenToSandboxes, this ), this.getNodes().length * waitInterval ); + }, + setNodes: function () { if ( this.parsed ) { this.setIframes( this.parsed.head, this.parsed.body ); + this.deferredListen(); } else { this.fail(); } @@ -617,6 +675,7 @@ window.wp = window.wp || {}; if ( response ) { self.parsed = response; self.setIframes( response.head, response.body ); + self.deferredListen(); } else { self.fail( true ); } diff --git a/wp-includes/js/mce-view.min.js b/wp-includes/js/mce-view.min.js index 6a77e881ff..3c809ff4e2 100644 --- a/wp-includes/js/mce-view.min.js +++ b/wp-includes/js/mce-view.min.js @@ -1 +1 @@ -window.wp=window.wp||{},function(a){"use strict";var b={},c={},d=wp.media,e=["encodedText"];wp.mce=wp.mce||{},wp.mce.View=function(a){a=a||{},this.type=a.type,_.extend(this,_.pick(a,e)),this.initialize.apply(this,arguments)},_.extend(wp.mce.View.prototype,{initialize:function(){},getHtml:function(){return""},loadingPlaceholder:function(){return'
'},render:function(c){(c||!this.rendered())&&(this.unbind(),this.setContent('

 

'+(_.isFunction(b[this.type].edit)?'
':"")+'
'+(this.getHtml()||this.loadingPlaceholder())+"
"+(this.overlay?'
':"")+'

 

',"wrap"),a(this).trigger("ready"),this.rendered(!0))},unbind:function(){},getEditors:function(a){var b=[];return _.each(tinymce.editors,function(c){c.plugins.wpview&&(a&&a(c),b.push(c))},this),b},getNodes:function(b){var c=[],d=this;return this.getEditors(function(e){a(e.getBody()).find('[data-wpview-text="'+d.encodedText+'"]').each(function(d,f){b&&b(e,f,a(f).find(".wpview-content").get(0)),c.push(f)})}),c},setContent:function(a,b){this.getNodes(function(c,d,e){var f="wrap"===b||"replace"===b?d:e,g=a;_.isString(g)&&(g=c.dom.createFragment(g)),"replace"===b?c.dom.replace(g,f):(f.innerHTML="",f.appendChild(g))})},setIframes:function(b,c){var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,e="video"===this.type||"audio"===this.type||"playlist"===this.type;b||-1!==c.indexOf("'+b+n+''+c+""),j.close(),l=function(){i.contentWindow&&a(i).height(a(j.body).height())},d)new d(_.debounce(function(){l()},100)).observe(j.body,{attributes:!0,childList:!0,subtree:!0});else for(k=1;6>k;k++)setTimeout(l,700*k);e&&f.on("wp-body-class-change",function(){j.body.className=f.getBody().className})},50)}):this.setContent(c)},setError:function(a,b){this.setContent('

'+a+"

")},rendered:function(b){var c;return this.getNodes(function(d,e){null!=b?a(e).data("rendered",b===!0):c=c||!a(e).data("rendered")}),!c}}),wp.mce.View.extend=Backbone.View.extend,wp.mce.views={register:function(a,c){var d={type:a,View:{},toView:function(a){var b=wp.shortcode.next(this.type,a);if(b)return{index:b.index,content:b.content,options:{shortcode:b.shortcode}}}};c=_.defaults(c,d),c.View=wp.mce.View.extend(c.View),b[a]=c},get:function(a){return b[a]},unregister:function(a){delete b[a]},unbind:function(){_.each(c,function(a){a.unbind()})},toViews:function(a){var c,d=[{content:a}];return _.each(b,function(a,b){c=d.slice(),d=[],_.each(c,function(c){var e,f=c.content;if(c.processed)return void d.push(c);for(;f&&(e=a.toView(f));)e.index&&d.push({content:f.substring(0,e.index)}),d.push({content:wp.mce.views.toView(b,e.content,e.options),processed:!0}),f=f.slice(e.index+e.content.length);f&&d.push({content:f})})}),_.pluck(d,"content").join("")},toView:function(a,b,d){var e,f,g=wp.mce.views.get(a),h=window.encodeURIComponent(b);return g?(wp.mce.views.getInstance(h)||(f=d,f.type=a,f.encodedText=h,e=new g.View(f),c[h]=e),wp.html.string({tag:"div",attrs:{"class":"wpview-wrap","data-wpview-text":h,"data-wpview-type":a},content:" "})):b},refreshView:function(a,b,d){var e,f,g,h=window.encodeURIComponent(b);g=wp.mce.views.getInstance(h),g||(f=a.toView(b),e=f.options,e.type=a.type,e.encodedText=h,g=new a.View(e),c[h]=g),g.render(d)},getInstance:function(a){return c[a]},render:function(a){_.each(c,function(b){b.render(a)})},edit:function(b){var c=a(b).data("wpview-type"),d=wp.mce.views.get(c);d&&d.edit(b)}},wp.mce.views.register("gallery",{View:{template:d.template("editor-gallery"),postID:a("#post_ID").val(),initialize:function(a){this.shortcode=a.shortcode,this.fetch()},fetch:function(){var a=this;this.attachments=wp.media.gallery.attachments(this.shortcode,this.postID),this.dfd=this.attachments.more().done(function(){a.render(!0)})},getHtml:function(){var a,b=this.shortcode.attrs.named,c=!1;return this.dfd&&"pending"===this.dfd.state()&&!this.attachments.length?"":(this.attachments.length&&(c=this.attachments.toJSON(),_.each(c,function(a){a.sizes&&(b.size&&a.sizes[b.size]?a.thumbnail=a.sizes[b.size]:a.sizes.thumbnail?a.thumbnail=a.sizes.thumbnail:a.sizes.full&&(a.thumbnail=a.sizes.full))})),a={attachments:c,columns:b.columns?parseInt(b.columns,10):wp.media.galleryDefaults.columns},this.template(a))}},edit:function(b){var c,d,e=wp.media.gallery,f=this;d=window.decodeURIComponent(a(b).attr("data-wpview-text")),c=e.edit(d),c.state("gallery-edit").on("update",function(c){var g,h=e.shortcode(c).string();a(b).attr("data-wpview-text",window.encodeURIComponent(h)),g=d!==h,wp.mce.views.refreshView(f,h,g)}),c.on("close",function(){c.detach()})}}),wp.mce.av={View:{overlay:!0,action:"parse-media-shortcode",initialize:function(b){var c=this;this.shortcode=b.shortcode,_.bindAll(this,"setIframes","setNodes","fetch","stopPlayers"),a(this).on("ready",this.setNodes),a(document).on("media:edit",this.stopPlayers),this.fetch(),this.getEditors(function(a){a.on("hide",c.stopPlayers)})},setNodes:function(){this.parsed?this.setIframes(this.parsed.head,this.parsed.body):this.fail()},fetch:function(){var b=this;wp.ajax.send(this.action,{data:{post_ID:a("#post_ID").val()||0,type:this.shortcode.tag,shortcode:this.shortcode.string()}}).done(function(a){a?(b.parsed=a,b.setIframes(a.head,a.body)):b.fail(!0)}).fail(function(a){b.fail(a||!0)})},fail:function(a){if(!this.error){if(!a)return;this.error=a}this.error.message?"not-embeddable"===this.error.type&&"embed"===this.type||"not-ssl"===this.error.type||"no-items"===this.error.type?this.setError(this.error.message,"admin-media"):this.setContent("

"+this.original+"

","replace"):this.error.statusText?this.setError(this.error.statusText,"admin-media"):this.original&&this.setContent("

"+this.original+"

","replace")},stopPlayers:function(b){var c="remove"===b;this.getNodes(function(b,d,e){var f,g,h=a("iframe.wpview-sandbox",e).get(0);if(h&&(g=h.contentWindow)&&g.mejs)try{for(f in g.mejs.players)g.mejs.players[f].pause(),c&&g.mejs.players[f].remove()}catch(i){}})},unbind:function(){this.stopPlayers("remove")}},edit:function(b){var c,d,e,f=wp.media[this.type],g=this;a(document).trigger("media:edit"),d=window.decodeURIComponent(a(b).attr("data-wpview-text")),c=f.edit(d),c.on("close",function(){c.detach()}),e=function(d){var e=wp.media[g.type].shortcode(d).string();a(b).attr("data-wpview-text",window.encodeURIComponent(e)),wp.mce.views.refreshView(g,e),c.detach()},_.isArray(g.state)?_.each(g.state,function(a){c.state(a).on("update",e)}):c.state(g.state).on("update",e),c.open()}},wp.mce.views.register("video",_.extend({},wp.mce.av,{state:"video-details"})),wp.mce.views.register("audio",_.extend({},wp.mce.av,{state:"audio-details"})),wp.mce.views.register("playlist",_.extend({},wp.mce.av,{state:["playlist-edit","video-playlist-edit"]})),wp.mce.embedMixin={View:_.extend({},wp.mce.av.View,{overlay:!0,action:"parse-embed",initialize:function(b){this.content=b.content,this.original=b.url||b.shortcode.string(),this.shortcode=b.url?d.embed.shortcode({url:b.url}):b.shortcode,_.bindAll(this,"setIframes","setNodes","fetch"),a(this).on("ready",this.setNodes),this.fetch()}}),edit:function(b){var c,e,f=d.embed,g=this,h="embedURL"===this.type;a(document).trigger("media:edit"),e=window.decodeURIComponent(a(b).attr("data-wpview-text")),c=f.edit(e,h),c.on("close",function(){c.detach()}),c.state("embed").props.on("change:url",function(a,b){b&&(c.state("embed").metadata=a.toJSON())}),c.state("embed").on("select",function(){var d;d=h?c.state("embed").metadata.url:f.shortcode(c.state("embed").metadata).string(),a(b).attr("data-wpview-text",window.encodeURIComponent(d)),wp.mce.views.refreshView(g,d),c.detach()}),c.open()}},wp.mce.views.register("embed",_.extend({},wp.mce.embedMixin)),wp.mce.views.register("embedURL",_.extend({},wp.mce.embedMixin,{toView:function(a){var b=/(?:^|

)(https?:\/\/[^\s"]+?)(?:<\/p>\s*|$)/gi,c=b.exec(tinymce.trim(a));if(c)return{index:c.index,content:c[0],options:{url:c[1]}}}}))}(jQuery); \ No newline at end of file +window.wp=window.wp||{},function(a){"use strict";var b={},c={},d=wp.media,e=[],f=0,g=50,h=["encodedText"];wp.mce=wp.mce||{},wp.mce.View=function(a){a=a||{},this.type=a.type,_.extend(this,_.pick(a,h)),this.initialize.apply(this,arguments)},_.extend(wp.mce.View.prototype,{initialize:function(){},getHtml:function(){return""},loadingPlaceholder:function(){return'

'},render:function(c){(c||!this.rendered())&&(this.unbind(),this.setContent('

 

'+(_.isFunction(b[this.type].edit)?'
':"")+'
'+(this.getHtml()||this.loadingPlaceholder())+"
"+(this.overlay?'
':"")+'

 

',"wrap"),a(this).trigger("ready"),this.rendered(!0))},unbind:function(){},getEditors:function(a){var b=[];return _.each(tinymce.editors,function(c){c.plugins.wpview&&(a&&a(c),b.push(c))},this),b},getNodes:function(b){var c=[],d=this;return this.getEditors(function(e){a(e.getBody()).find('[data-wpview-text="'+d.encodedText+'"]').each(function(d,f){b&&b(e,f,a(f).find(".wpview-content").get(0)),c.push(f)})}),c},setContent:function(a,b){this.getNodes(function(c,d,e){var f="wrap"===b||"replace"===b?d:e,g=a;_.isString(g)&&(g=c.dom.createFragment(g)),"replace"===b?c.dom.replace(g,f):(f.innerHTML="",f.appendChild(g))})},setIframes:function(b,c){var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,e="video"===this.type||"audio"===this.type||"playlist"===this.type;b||-1!==c.indexOf("'+b+o+''+c+""),k.close(),m=function(){j.contentWindow&&a(j).height(a(k.body).height())},d)new d(_.debounce(function(){m()},100)).observe(k.body,{attributes:!0,childList:!0,subtree:!0});else for(l=1;6>l;l++)setTimeout(m,700*l);e&&f.on("wp-body-class-change",function(){k.body.className=f.getBody().className})},g)}):this.setContent(c)},setError:function(a,b){this.setContent('

'+a+"

")},rendered:function(b){var c;return this.getNodes(function(d,e){null!=b?a(e).data("rendered",b===!0):c=c||!a(e).data("rendered")}),!c}}),wp.mce.View.extend=Backbone.View.extend,wp.mce.views={register:function(a,c){var d={type:a,View:{},toView:function(a){var b=wp.shortcode.next(this.type,a);if(b)return{index:b.index,content:b.content,options:{shortcode:b.shortcode}}}};c=_.defaults(c,d),c.View=wp.mce.View.extend(c.View),b[a]=c},get:function(a){return b[a]},unregister:function(a){delete b[a]},unbind:function(){_.each(c,function(a){a.unbind()})},toViews:function(a){var c,d=[{content:a}];return _.each(b,function(a,b){c=d.slice(),d=[],_.each(c,function(c){var e,f=c.content;if(c.processed)return void d.push(c);for(;f&&(e=a.toView(f));)e.index&&d.push({content:f.substring(0,e.index)}),d.push({content:wp.mce.views.toView(b,e.content,e.options),processed:!0}),f=f.slice(e.index+e.content.length);f&&d.push({content:f})})}),_.pluck(d,"content").join("")},toView:function(a,b,d){var e,f,g=wp.mce.views.get(a),h=window.encodeURIComponent(b);return g?(wp.mce.views.getInstance(h)||(f=d,f.type=a,f.encodedText=h,e=new g.View(f),c[h]=e),wp.html.string({tag:"div",attrs:{"class":"wpview-wrap","data-wpview-text":h,"data-wpview-type":a},content:" "})):b},refreshView:function(a,b,d){var e,f,g,h=window.encodeURIComponent(b);g=wp.mce.views.getInstance(h),g||(f=a.toView(b),e=f.options,e.type=a.type,e.encodedText=h,g=new a.View(e),c[h]=g),g.render(d)},getInstance:function(a){return c[a]},render:function(a){_.each(c,function(b){b.render(a)})},edit:function(b){var c=a(b).data("wpview-type"),d=wp.mce.views.get(c);d&&d.edit(b)}},wp.mce.views.register("gallery",{View:{template:d.template("editor-gallery"),postID:a("#post_ID").val(),initialize:function(a){this.shortcode=a.shortcode,this.fetch()},fetch:function(){var a=this;this.attachments=wp.media.gallery.attachments(this.shortcode,this.postID),this.dfd=this.attachments.more().done(function(){a.render(!0)})},getHtml:function(){var a,b=this.shortcode.attrs.named,c=!1;return this.dfd&&"pending"===this.dfd.state()&&!this.attachments.length?"":(this.attachments.length&&(c=this.attachments.toJSON(),_.each(c,function(a){a.sizes&&(b.size&&a.sizes[b.size]?a.thumbnail=a.sizes[b.size]:a.sizes.thumbnail?a.thumbnail=a.sizes.thumbnail:a.sizes.full&&(a.thumbnail=a.sizes.full))})),a={attachments:c,columns:b.columns?parseInt(b.columns,10):wp.media.galleryDefaults.columns},this.template(a))}},edit:function(b){var c,d,e=wp.media.gallery,f=this;d=window.decodeURIComponent(a(b).attr("data-wpview-text")),c=e.edit(d),c.state("gallery-edit").on("update",function(c){var g,h=e.shortcode(c).string();a(b).attr("data-wpview-text",window.encodeURIComponent(h)),g=d!==h,wp.mce.views.refreshView(f,h,g)}),c.on("close",function(){c.detach()})}}),wp.mce.av={View:{overlay:!0,action:"parse-media-shortcode",initialize:function(b){var c=this;this.shortcode=b.shortcode,_.bindAll(this,"setIframes","setNodes","fetch","stopPlayers"),a(this).on("ready",this.setNodes),a(document).on("media:edit",this.stopPlayers),this.fetch(),this.getEditors(function(a){a.on("hide",function(){e=[],f=0,c.stopPlayers()})})},pauseOtherWindows:function(a){_.each(e,function(b){b.sandboxId!==a.sandboxId&&_.each(b.mejs.players,function(a){a.pause()})})},iframeLoaded:function(b){return _.bind(function(){var c;b.mejs&&!_.isEmpty(b.mejs.players)&&(b.sandboxId=f,f++,e.push(b),c=_.bind(function(){this.pauseOtherWindows(b)},this),_.isEmpty(b.mejs.MediaPluginBridge.pluginMediaElements)||_.each(b.mejs.MediaPluginBridge.pluginMediaElements,function(a){a.addEventListener("play",c)}),_.each(b.mejs.players,function(b){a(b.node).on("play",c)},this))},this)},listenToSandboxes:function(){_.each(this.getNodes(),function(b){var c,d=a(".wpview-sandbox",b).get(0);d&&(c=d.contentWindow)&&a(c).load(_.bind(this.iframeLoaded(c),this))},this)},deferredListen:function(){window.setTimeout(_.bind(this.listenToSandboxes,this),this.getNodes().length*g)},setNodes:function(){this.parsed?(this.setIframes(this.parsed.head,this.parsed.body),this.deferredListen()):this.fail()},fetch:function(){var b=this;wp.ajax.send(this.action,{data:{post_ID:a("#post_ID").val()||0,type:this.shortcode.tag,shortcode:this.shortcode.string()}}).done(function(a){a?(b.parsed=a,b.setIframes(a.head,a.body),b.deferredListen()):b.fail(!0)}).fail(function(a){b.fail(a||!0)})},fail:function(a){if(!this.error){if(!a)return;this.error=a}this.error.message?"not-embeddable"===this.error.type&&"embed"===this.type||"not-ssl"===this.error.type||"no-items"===this.error.type?this.setError(this.error.message,"admin-media"):this.setContent("

"+this.original+"

","replace"):this.error.statusText?this.setError(this.error.statusText,"admin-media"):this.original&&this.setContent("

"+this.original+"

","replace")},stopPlayers:function(b){var c="remove"===b;this.getNodes(function(b,d,e){var f,g,h=a("iframe.wpview-sandbox",e).get(0);if(h&&(g=h.contentWindow)&&g.mejs)try{for(f in g.mejs.players)g.mejs.players[f].pause(),c&&g.mejs.players[f].remove()}catch(i){}})},unbind:function(){this.stopPlayers("remove")}},edit:function(b){var c,d,e,f=wp.media[this.type],g=this;a(document).trigger("media:edit"),d=window.decodeURIComponent(a(b).attr("data-wpview-text")),c=f.edit(d),c.on("close",function(){c.detach()}),e=function(d){var e=wp.media[g.type].shortcode(d).string();a(b).attr("data-wpview-text",window.encodeURIComponent(e)),wp.mce.views.refreshView(g,e),c.detach()},_.isArray(g.state)?_.each(g.state,function(a){c.state(a).on("update",e)}):c.state(g.state).on("update",e),c.open()}},wp.mce.views.register("video",_.extend({},wp.mce.av,{state:"video-details"})),wp.mce.views.register("audio",_.extend({},wp.mce.av,{state:"audio-details"})),wp.mce.views.register("playlist",_.extend({},wp.mce.av,{state:["playlist-edit","video-playlist-edit"]})),wp.mce.embedMixin={View:_.extend({},wp.mce.av.View,{overlay:!0,action:"parse-embed",initialize:function(b){this.content=b.content,this.original=b.url||b.shortcode.string(),this.shortcode=b.url?d.embed.shortcode({url:b.url}):b.shortcode,_.bindAll(this,"setIframes","setNodes","fetch"),a(this).on("ready",this.setNodes),this.fetch()}}),edit:function(b){var c,e,f=d.embed,g=this,h="embedURL"===this.type;a(document).trigger("media:edit"),e=window.decodeURIComponent(a(b).attr("data-wpview-text")),c=f.edit(e,h),c.on("close",function(){c.detach()}),c.state("embed").props.on("change:url",function(a,b){b&&(c.state("embed").metadata=a.toJSON())}),c.state("embed").on("select",function(){var d;d=h?c.state("embed").metadata.url:f.shortcode(c.state("embed").metadata).string(),a(b).attr("data-wpview-text",window.encodeURIComponent(d)),wp.mce.views.refreshView(g,d),c.detach()}),c.open()}},wp.mce.views.register("embed",_.extend({},wp.mce.embedMixin)),wp.mce.views.register("embedURL",_.extend({},wp.mce.embedMixin,{toView:function(a){var b=/(?:^|

)(https?:\/\/[^\s"]+?)(?:<\/p>\s*|$)/gi,c=b.exec(tinymce.trim(a));if(c)return{index:c.index,content:c[0],options:{url:c[1]}}}}))}(jQuery); \ No newline at end of file diff --git a/wp-includes/version.php b/wp-includes/version.php index d5e5db2689..8a5fd936f0 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.1-beta2-30641'; +$wp_version = '4.1-beta2-30642'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.