diff --git a/wp-includes/js/mce-view.js b/wp-includes/js/mce-view.js index b54470dba1..7552b221ba 100644 --- a/wp-includes/js/mce-view.js +++ b/wp-includes/js/mce-view.js @@ -87,6 +87,8 @@ window.wp = window.wp || {}; * and creates a new instance for every match. * * @param {String} content The string to scan. + * + * @return {String} The string with markers. */ setMarkers: function( content ) { var pieces = [ { content: content } ], @@ -298,11 +300,18 @@ window.wp = window.wp || {}; /** * Renders all view nodes tied to this view instance that are not yet rendered. * + * @param {String} content The content to render. Optional. * @param {Boolean} force Rerender all view nodes tied to this view instance. */ - render: function( force ) { + render: function( content, force ) { + if ( content != null ) { + this.content = content; + } + + content = this.getContent(); + // If there's nothing to render an no loader needs to be shown, stop. - if ( ! this.loader && ! this.getContent() ) { + if ( ! this.loader && ! content ) { return; } @@ -312,21 +321,33 @@ window.wp = window.wp || {}; // Replace any left over markers. this.replaceMarkers(); - if ( this.getContent() ) { - this.setContent( this.getContent(), function( editor, node ) { - $( node ).data( 'rendered', true ).trigger( 'wp-mce-view-bind' ); + if ( content ) { + this.setContent( content, function( editor, node ) { + $( node ).data( 'rendered', true ); + this.bindNode.call( this, editor, node ); }, force ? null : false ); } else { this.setLoader(); } }, + /** + * Binds a given node after its content is added to the DOM. + */ + bindNode: function() {}, + + /** + * Unbinds a given node before its content is removed from the DOM. + */ + unbindNode: function() {}, + /** * Unbinds all view nodes tied to this view instance. * Runs before their content is removed from the DOM. */ unbind: function() { this.getNodes( function( editor, node ) { + this.unbindNode.call( this, editor, node ); $( node ).trigger( 'wp-mce-view-unbind' ); }, true ); }, @@ -447,7 +468,7 @@ window.wp = window.wp || {}; contentNode.innerHTML = ''; contentNode.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content ); - callback && callback.apply( this, arguments ); + callback && callback.call( this, editor, node, contentNode ); }, rendered ); } }, @@ -461,30 +482,27 @@ window.wp = window.wp || {}; * @param {Boolean} rendered Only set for (un)rendered nodes. Optional. */ setIframes: function( head, body, callback, rendered ) { - var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, + self = this; this.getNodes( function( editor, node, content ) { - // Seems Firefox needs a bit of time to insert/set the view nodes, + var dom = editor.dom, + styles = '', + bodyClasses = editor.getBody().className || '', + editorHead = editor.getDoc().getElementsByTagName( 'head' )[0], + iframe, iframeDoc, observer, i; + + tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) { + if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 && + link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) { + + styles += dom.getOuterHTML( link ); + } + } ); + + // Seems the browsers need a bit of time to insert/set the view nodes, // or the iframe will fail especially when switching Text => Visual. setTimeout( function() { - var dom = editor.dom, - styles = '', - bodyClasses = editor.getBody().className || '', - iframe, iframeDoc, observer, i; - - tinymce.each( dom.$( - 'link[rel="stylesheet"]', - editor.getDoc().getElementsByTagName( 'head' )[0] - ), function( link ) { - if ( - link.href && - link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 && - link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 - ) { - styles += dom.getOuterHTML( link ); - } - } ); - content.innerHTML = ''; iframe = dom.add( content, 'iframe', { @@ -582,7 +600,7 @@ window.wp = window.wp || {}; editor.off( 'wp-body-class-change', classChange ); } ); - callback && callback.apply( this, arguments ); + callback && callback.call( self, editor, node ); }, 50 ); }, rendered ); }, @@ -664,6 +682,7 @@ window.wp = window.wp || {}; * @param {HTMLElement} node The view node to remove. */ remove: function( editor, node ) { + this.unbindNode.call( this, editor, node, $( node ).find( '.wpview-content' ).get( 0 ) ); $( node ).trigger( 'wp-mce-view-unbind' ); editor.dom.remove( node ); editor.focus(); @@ -728,12 +747,10 @@ window.wp = window.wp || {}; } } ); - self.content = self.template( { + self.render( self.template( { attachments: attachments, columns: attrs.columns ? parseInt( attrs.columns, 10 ) : wp.media.galleryDefaults.columns - } ); - - self.render(); + } ) ); } ) .fail( function( jqXHR, textStatus ) { self.setError( textStatus ); @@ -754,16 +771,13 @@ window.wp = window.wp || {}; } ); } - wp.ajax.send( this.action, { - data: { - post_ID: postID, - type: this.shortcode.tag, - shortcode: this.shortcode.string() - } + wp.ajax.post( this.action, { + post_ID: postID, + type: this.shortcode.tag, + shortcode: this.shortcode.string() } ) .done( function( response ) { - self.content = response; - self.render(); + self.render( response ); } ) .fail( function( response ) { if ( self.url ) { diff --git a/wp-includes/js/mce-view.min.js b/wp-includes/js/mce-view.min.js index b8bb8aca9c..7d30c672cb 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,b,c){"use strict";var d={},e={};b.mce=b.mce||{},b.mce.views={register:function(a,c){d[a]=b.mce.View.extend(_.extend(c,{type:a}))},unregister:function(a){delete d[a]},get:function(a){return d[a]},unbind:function(){_.each(e,function(a){a.unbind()})},setMarkers:function(a){var b,c,e=[{content:a}],f=this;return _.each(d,function(a,d){c=e.slice(),e=[],_.each(c,function(c){var g,h=c.content;if(c.processed)return void e.push(c);for(;h&&(g=a.prototype.match(h));)g.index&&e.push({content:h.substring(0,g.index)}),b=f.createInstance(d,g.content,g.options),e.push({content:'
'+b.text+"
",processed:!0}),h=h.slice(g.index+g.content.length);h&&e.push({content:h})})}),_.pluck(e,"content").join("")},createInstance:function(a,b,c){var d,f,g=this.get(a);return b=tinymce.DOM.decode(b),d=encodeURIComponent(b),(f=this.getInstance(d))?f:(c=_.extend(c||{},{text:b,encodedText:d}),e[d]=new g(c))},getInstance:function(a){return"string"==typeof a?e[encodeURIComponent(a)]:e[c(a).attr("data-wpview-text")]},getText:function(a){return decodeURIComponent(c(a).attr("data-wpview-text")||"")},render:function(a){_.each(e,function(b){b.render(a)})},update:function(a,b,c){var d=this.getInstance(c);d&&d.update(a,b,c)},edit:function(a,b){var c=this.getInstance(b);c&&c.edit&&c.edit(c.text,function(d){c.update(d,a,b)})},remove:function(a,b){var c=this.getInstance(b);c&&c.remove(a,b)}},b.mce.View=function(a){_.extend(this,a),this.initialize()},b.mce.View.extend=Backbone.View.extend,_.extend(b.mce.View.prototype,{content:null,loader:!0,initialize:function(){},getContent:function(){return this.content},render:function(a){(this.loader||this.getContent())&&(a&&this.unbind(),this.replaceMarkers(),this.getContent()?this.setContent(this.getContent(),function(a,b){c(b).data("rendered",!0).trigger("wp-mce-view-bind")},a?null:!1):this.setLoader())},unbind:function(){this.getNodes(function(a,b){c(b).trigger("wp-mce-view-unbind")},!0)},getEditors:function(a){_.each(tinymce.editors,function(b){b.plugins.wpview&&a.call(this,b)},this)},getNodes:function(a,b){this.getEditors(function(d){var e=this;c(d.getBody()).find('[data-wpview-text="'+e.encodedText+'"]').filter(function(){var a;return null==b?!0:(a=c(this).data("rendered")===!0,b?a:!a)}).each(function(){a.call(e,d,this,c(this).find(".wpview-content").get(0))})})},getMarkers:function(a){this.getEditors(function(b){var d=this;c(b.getBody()).find('[data-wpview-marker="'+this.encodedText+'"]').each(function(){a.call(d,b,this)})})},replaceMarkers:function(){this.getMarkers(function(a,b){return c(b).text()!==this.text?void a.dom.setAttrib(b,"data-wpview-marker",null):void a.dom.replace(a.dom.createFragment('