mirror of
https://github.com/WordPress/WordPress.git
synced 2024-11-15 07:05:37 +01:00
TinyMCE wpView:
- Fix editor undo levels. - Remove views and markers in the DOM before serialization. - Unbind views before removing them on hide. - Empty the content in the timeout, so it doesn't render iframes twice. Props iseulde. Fixes #31669. Built from https://develop.svn.wordpress.org/trunk@32022 git-svn-id: http://core.svn.wordpress.org/trunk@32001 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
a7341b7c3f
commit
0186bbcb95
@ -87,6 +87,8 @@ window.wp = window.wp || {};
|
|||||||
* and creates a new instance for every match.
|
* and creates a new instance for every match.
|
||||||
*
|
*
|
||||||
* @param {String} content The string to scan.
|
* @param {String} content The string to scan.
|
||||||
|
*
|
||||||
|
* @return {String} The string with markers.
|
||||||
*/
|
*/
|
||||||
setMarkers: function( content ) {
|
setMarkers: function( content ) {
|
||||||
var pieces = [ { content: 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.
|
* 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.
|
* @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 there's nothing to render an no loader needs to be shown, stop.
|
||||||
if ( ! this.loader && ! this.getContent() ) {
|
if ( ! this.loader && ! content ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,21 +321,33 @@ window.wp = window.wp || {};
|
|||||||
// Replace any left over markers.
|
// Replace any left over markers.
|
||||||
this.replaceMarkers();
|
this.replaceMarkers();
|
||||||
|
|
||||||
if ( this.getContent() ) {
|
if ( content ) {
|
||||||
this.setContent( this.getContent(), function( editor, node ) {
|
this.setContent( content, function( editor, node ) {
|
||||||
$( node ).data( 'rendered', true ).trigger( 'wp-mce-view-bind' );
|
$( node ).data( 'rendered', true );
|
||||||
|
this.bindNode.call( this, editor, node );
|
||||||
}, force ? null : false );
|
}, force ? null : false );
|
||||||
} else {
|
} else {
|
||||||
this.setLoader();
|
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.
|
* Unbinds all view nodes tied to this view instance.
|
||||||
* Runs before their content is removed from the DOM.
|
* Runs before their content is removed from the DOM.
|
||||||
*/
|
*/
|
||||||
unbind: function() {
|
unbind: function() {
|
||||||
this.getNodes( function( editor, node ) {
|
this.getNodes( function( editor, node ) {
|
||||||
|
this.unbindNode.call( this, editor, node );
|
||||||
$( node ).trigger( 'wp-mce-view-unbind' );
|
$( node ).trigger( 'wp-mce-view-unbind' );
|
||||||
}, true );
|
}, true );
|
||||||
},
|
},
|
||||||
@ -447,7 +468,7 @@ window.wp = window.wp || {};
|
|||||||
contentNode.innerHTML = '';
|
contentNode.innerHTML = '';
|
||||||
contentNode.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
|
contentNode.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
|
||||||
|
|
||||||
callback && callback.apply( this, arguments );
|
callback && callback.call( this, editor, node, contentNode );
|
||||||
}, rendered );
|
}, rendered );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -461,30 +482,27 @@ window.wp = window.wp || {};
|
|||||||
* @param {Boolean} rendered Only set for (un)rendered nodes. Optional.
|
* @param {Boolean} rendered Only set for (un)rendered nodes. Optional.
|
||||||
*/
|
*/
|
||||||
setIframes: function( head, body, callback, rendered ) {
|
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 ) {
|
this.getNodes( function( editor, node, content ) {
|
||||||
// Seems Firefox needs 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,
|
var dom = editor.dom,
|
||||||
styles = '',
|
styles = '',
|
||||||
bodyClasses = editor.getBody().className || '',
|
bodyClasses = editor.getBody().className || '',
|
||||||
|
editorHead = editor.getDoc().getElementsByTagName( 'head' )[0],
|
||||||
iframe, iframeDoc, observer, i;
|
iframe, iframeDoc, observer, i;
|
||||||
|
|
||||||
tinymce.each( dom.$(
|
tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) {
|
||||||
'link[rel="stylesheet"]',
|
if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&
|
||||||
editor.getDoc().getElementsByTagName( 'head' )[0]
|
link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) {
|
||||||
), 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 );
|
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() {
|
||||||
content.innerHTML = '';
|
content.innerHTML = '';
|
||||||
|
|
||||||
iframe = dom.add( content, 'iframe', {
|
iframe = dom.add( content, 'iframe', {
|
||||||
@ -582,7 +600,7 @@ window.wp = window.wp || {};
|
|||||||
editor.off( 'wp-body-class-change', classChange );
|
editor.off( 'wp-body-class-change', classChange );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
callback && callback.apply( this, arguments );
|
callback && callback.call( self, editor, node );
|
||||||
}, 50 );
|
}, 50 );
|
||||||
}, rendered );
|
}, rendered );
|
||||||
},
|
},
|
||||||
@ -664,6 +682,7 @@ window.wp = window.wp || {};
|
|||||||
* @param {HTMLElement} node The view node to remove.
|
* @param {HTMLElement} node The view node to remove.
|
||||||
*/
|
*/
|
||||||
remove: function( editor, node ) {
|
remove: function( editor, node ) {
|
||||||
|
this.unbindNode.call( this, editor, node, $( node ).find( '.wpview-content' ).get( 0 ) );
|
||||||
$( node ).trigger( 'wp-mce-view-unbind' );
|
$( node ).trigger( 'wp-mce-view-unbind' );
|
||||||
editor.dom.remove( node );
|
editor.dom.remove( node );
|
||||||
editor.focus();
|
editor.focus();
|
||||||
@ -728,12 +747,10 @@ window.wp = window.wp || {};
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
self.content = self.template( {
|
self.render( self.template( {
|
||||||
attachments: attachments,
|
attachments: attachments,
|
||||||
columns: attrs.columns ? parseInt( attrs.columns, 10 ) : wp.media.galleryDefaults.columns
|
columns: attrs.columns ? parseInt( attrs.columns, 10 ) : wp.media.galleryDefaults.columns
|
||||||
} );
|
} ) );
|
||||||
|
|
||||||
self.render();
|
|
||||||
} )
|
} )
|
||||||
.fail( function( jqXHR, textStatus ) {
|
.fail( function( jqXHR, textStatus ) {
|
||||||
self.setError( textStatus );
|
self.setError( textStatus );
|
||||||
@ -754,16 +771,13 @@ window.wp = window.wp || {};
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
wp.ajax.send( this.action, {
|
wp.ajax.post( this.action, {
|
||||||
data: {
|
|
||||||
post_ID: postID,
|
post_ID: postID,
|
||||||
type: this.shortcode.tag,
|
type: this.shortcode.tag,
|
||||||
shortcode: this.shortcode.string()
|
shortcode: this.shortcode.string()
|
||||||
}
|
|
||||||
} )
|
} )
|
||||||
.done( function( response ) {
|
.done( function( response ) {
|
||||||
self.content = response;
|
self.render( response );
|
||||||
self.render();
|
|
||||||
} )
|
} )
|
||||||
.fail( function( response ) {
|
.fail( function( response ) {
|
||||||
if ( self.url ) {
|
if ( self.url ) {
|
||||||
|
2
wp-includes/js/mce-view.min.js
vendored
2
wp-includes/js/mce-view.min.js
vendored
File diff suppressed because one or more lines are too long
@ -4,7 +4,8 @@
|
|||||||
* WordPress View plugin.
|
* WordPress View plugin.
|
||||||
*/
|
*/
|
||||||
tinymce.PluginManager.add( 'wpview', function( editor ) {
|
tinymce.PluginManager.add( 'wpview', function( editor ) {
|
||||||
var selected,
|
var $ = editor.$,
|
||||||
|
selected,
|
||||||
Env = tinymce.Env,
|
Env = tinymce.Env,
|
||||||
VK = tinymce.util.VK,
|
VK = tinymce.util.VK,
|
||||||
TreeWalker = tinymce.dom.TreeWalker,
|
TreeWalker = tinymce.dom.TreeWalker,
|
||||||
@ -153,13 +154,17 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
|||||||
|
|
||||||
// Remove the content of view wrappers from HTML string
|
// Remove the content of view wrappers from HTML string
|
||||||
function emptyViews( content ) {
|
function emptyViews( content ) {
|
||||||
return content.replace(/<div[^>]+data-wpview-text=\"([^"]+)"[^>]*>[\s\S]+?wpview-selection-after[^>]+>(?: |\u00a0)*<\/p><\/div>/g, '$1' );
|
content = content.replace( /<div[^>]+data-wpview-text="([^"]+)"[^>]*>[\s\S]+?wpview-selection-after[^>]+>[^<>]*<\/p>\s*<\/div>/g, function( all, match ) {
|
||||||
|
return '<p>' + window.decodeURIComponent( match ) + '</p>';
|
||||||
|
});
|
||||||
|
|
||||||
|
return content.replace( / data-wpview-marker="[^"]+"/g, '' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent adding undo levels on changes inside a view wrapper
|
// Prevent adding undo levels on changes inside a view wrapper
|
||||||
editor.on( 'BeforeAddUndo', function( event ) {
|
editor.on( 'BeforeAddUndo', function( event ) {
|
||||||
if ( event.lastLevel && emptyViews( event.level.content ) === emptyViews( event.lastLevel.content ) ) {
|
if ( event.level.content ) {
|
||||||
event.preventDefault();
|
event.level.content = emptyViews( event.level.content );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -169,6 +174,10 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
|||||||
editor.on( 'BeforeSetContent', function( event ) {
|
editor.on( 'BeforeSetContent', function( event ) {
|
||||||
var node;
|
var node;
|
||||||
|
|
||||||
|
if ( ! event.selection ) {
|
||||||
|
wp.mce.views.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! event.content ) {
|
if ( ! event.content ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -339,22 +348,30 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.on( 'PreProcess', function( event ) {
|
function resetViews( rootNode ) {
|
||||||
// Empty the wpview wrap nodes
|
// Replace view nodes
|
||||||
tinymce.each( editor.dom.select( 'div[data-wpview-text]', event.node ), function( node ) {
|
$( 'div[data-wpview-text]', rootNode ).each( function( i, node ) {
|
||||||
node.textContent = node.innerText = '\u00a0';
|
var $node = $( node ),
|
||||||
});
|
text = window.decodeURIComponent( $node.attr( 'data-wpview-text' ) || '' );
|
||||||
|
|
||||||
|
if ( text && node.parentNode ) {
|
||||||
|
$node.replaceWith( $( editor.dom.create('p') ).text( text ) );
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.on( 'PostProcess', function( event ) {
|
// Remove marker attributes
|
||||||
if ( event.content ) {
|
$( 'p[data-wpview-marker]', rootNode ).attr( 'data-wpview-marker', null );
|
||||||
event.content = event.content.replace( /<div [^>]*?data-wpview-text="([^"]*)"[^>]*>[\s\S]*?<\/div>/g, function( match, shortcode ) {
|
|
||||||
if ( shortcode ) {
|
|
||||||
return '<p>' + window.decodeURIComponent( shortcode ) + '</p>';
|
|
||||||
}
|
|
||||||
return ''; // If error, remove the view wrapper
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editor.on( 'PreProcess', function( event ) {
|
||||||
|
// Replace the view nodes with their text in the DOM clone.
|
||||||
|
resetViews( event.node );
|
||||||
|
}, true );
|
||||||
|
|
||||||
|
editor.on( 'hide', function() {
|
||||||
|
// Replace the view nodes with their text directly in the editor body.
|
||||||
|
wp.mce.views.unbind();
|
||||||
|
resetViews( editor.getBody() );
|
||||||
});
|
});
|
||||||
|
|
||||||
// Excludes arrow keys, delete, backspace, enter, space bar.
|
// Excludes arrow keys, delete, backspace, enter, space bar.
|
||||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '4.2-beta4-32021';
|
$wp_version = '4.2-beta4-32022';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
@ -18,7 +18,7 @@ $wp_db_version = 31532;
|
|||||||
*
|
*
|
||||||
* @global string $tinymce_version
|
* @global string $tinymce_version
|
||||||
*/
|
*/
|
||||||
$tinymce_version = '4109-20150310';
|
$tinymce_version = '4109-20150404';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the required PHP version
|
* Holds the required PHP version
|
||||||
|
Loading…
Reference in New Issue
Block a user