this.replaceMarkers();
if ( content ) {
- this.setContent( content, function( editor, node, contentNode ) {
+ this.setContent( content, function( editor, node ) {
$( node ).data( 'rendered', true );
- this.bindNode.call( this, editor, node, contentNode );
+ this.bindNode.call( this, editor, node );
}, force ? null : false );
} else {
this.setLoader();
* Runs before their content is removed from the DOM.
*/
unbind: function() {
- this.getNodes( function( editor, node, contentNode ) {
- this.unbindNode.call( this, editor, node, contentNode );
- $( node ).trigger( 'wp-mce-view-unbind' );
+ this.getNodes( function( editor, node ) {
+ this.unbindNode.call( this, editor, node );
}, true );
},
return rendered ? data : ! data;
} )
.each( function() {
- callback.call( self, editor, this, $( this ).find( '.wpview-content' ).get( 0 ) );
+ callback.call( self, editor, this, this /* back compat */ );
} );
} );
},
*/
replaceMarkers: function() {
this.getMarkers( function( editor, node ) {
- var selected = node === editor.selection.getNode(),
- $viewNode;
+ var $viewNode;
if ( ! this.loader && $( node ).text() !== this.text ) {
editor.dom.setAttrib( node, 'data-wpview-marker', null );
}
$viewNode = editor.$(
- '<div class="wpview-wrap" data-wpview-text="' + this.encodedText + '" data-wpview-type="' + this.type + '">' +
- '<p class="wpview-selection-before">\u00a0</p>' +
- '<div class="wpview-body" contenteditable="false">' +
- '<div class="wpview-content wpview-type-' + this.type + '"></div>' +
- '</div>' +
- '<p class="wpview-selection-after">\u00a0</p>' +
- '</div>'
+ '<div class="wpview wpview-wrap" data-wpview-text="' + this.encodedText + '" data-wpview-type="' + this.type + '" contenteditable="false"></div>'
);
editor.$( node ).replaceWith( $viewNode );
-
- if ( selected ) {
- editor.wp.setViewCursor( false, $viewNode[0] );
- }
} );
},
} else if ( _.isString( content ) && content.indexOf( '<script' ) !== -1 ) {
this.setIframes( '', content, callback, rendered );
} else {
- this.getNodes( function( editor, node, contentNode ) {
+ this.getNodes( function( editor, node ) {
content = content.body || content;
if ( content.indexOf( '<iframe' ) !== -1 ) {
- content += '<div class="wpview-overlay"></div>';
+ content += '<span class="mce-shim"></span>';
}
- contentNode.innerHTML = '';
- contentNode.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
+ editor.undoManager.transact( function() {
+ node.innerHTML = '';
+ node.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
+ editor.dom.add( node, 'span', { 'class': 'wpview-end' } );
+ } );
- callback && callback.call( this, editor, node, contentNode );
+ callback && callback.call( this, editor, node );
}, rendered );
}
},
* @param {Boolean} rendered Only set for (un)rendered nodes. Optional.
*/
setIframes: function( head, body, callback, rendered ) {
- var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
- self = this;
+ var self = this;
- this.getNodes( function( editor, node, contentNode ) {
+ this.getNodes( function( editor, node ) {
var dom = editor.dom,
styles = '',
bodyClasses = editor.getBody().className || '',
} );
if ( self.iframeHeight ) {
- dom.add( contentNode, 'div', { style: {
- width: '100%',
- height: self.iframeHeight
- } } );
+ dom.add( node, 'span', {
+ 'data-mce-bogus': 1,
+ style: {
+ display: 'block',
+ width: '100%',
+ height: self.iframeHeight
+ }
+ }, '\u200B' );
}
// 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 iframe, iframeDoc, observer, i, block;
-
- contentNode.innerHTML = '';
+ var iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block;
+
+ editor.undoManager.transact( function() {
+ node.innerHTML = '';
+
+ iframe = dom.add( node, 'iframe', {
+ /* jshint scripturl: true */
+ src: tinymce.Env.ie ? 'javascript:""' : '',
+ frameBorder: '0',
+ allowTransparency: 'true',
+ scrolling: 'no',
+ 'class': 'wpview-sandbox',
+ style: {
+ width: '100%',
+ display: 'block'
+ },
+ height: self.iframeHeight
+ } );
- iframe = dom.add( contentNode, 'iframe', {
- /* jshint scripturl: true */
- src: tinymce.Env.ie ? 'javascript:""' : '',
- frameBorder: '0',
- allowTransparency: 'true',
- scrolling: 'no',
- 'class': 'wpview-sandbox',
- style: {
- width: '100%',
- display: 'block'
- },
- height: self.iframeHeight
+ dom.add( node, 'span', { 'class': 'mce-shim' } );
+ dom.add( node, 'span', { 'class': 'wpview-end' } );
} );
- dom.add( contentNode, 'div', { 'class': 'wpview-overlay' } );
-
- iframeDoc = iframe.contentWindow.document;
+ // Bail if the iframe node is not attached to the DOM.
+ // Happens when the view is dragged in the editor.
+ // There is a browser restriction when iframes are moved in the DOM. They get emptied.
+ // The iframe will be rerendered after dropping the view node at the new location.
+ if ( ! iframe.contentWindow ) {
+ return;
+ }
+ iframeWin = iframe.contentWindow;
+ iframeDoc = iframeWin.document;
iframeDoc.open();
iframeDoc.write(
}, 3000 );
}
- $( iframe.contentWindow ).on( 'load', resize );
+ $( iframeWin ).on( 'load', resize );
+
+ MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver;
if ( MutationObserver ) {
observer = new MutationObserver( _.debounce( resize, 100 ) );
childList: true,
subtree: true
} );
-
- $( node ).one( 'wp-mce-view-unbind', function() {
- observer.disconnect();
- } );
} else {
for ( i = 1; i < 6; i++ ) {
setTimeout( resize, i * 700 );
}
}
- function classChange() {
- iframeDoc.body.className = editor.getBody().className;
- }
-
- editor.on( 'wp-body-class-change', classChange );
-
- $( node ).one( 'wp-mce-view-unbind', function() {
- editor.off( 'wp-body-class-change', classChange );
- } );
-
- callback && callback.call( self, editor, node, contentNode );
+ callback && callback.call( self, editor, node );
}, 50 );
}, rendered );
},
* @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' );
+ this.unbindNode.call( this, editor, node );
editor.dom.remove( node );
editor.focus();
}