MCE View sandboxes:

* Use a `MutationObserver` to listen to the `body` class of the parent editor frame.
* In `wpview_media_sandbox_styles()`, only return the MEjs stylesheets.
* In `wp_ajax_parse_media_shortcode()` and `wp_ajax_parse_embed()`, return an object instead of an HTML blob to allow passing `body` and `head` separately	

Props avryl, azaozz.
Fixes #29048.

Built from https://develop.svn.wordpress.org/trunk@29615


git-svn-id: http://core.svn.wordpress.org/trunk@29389 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Scott Taylor 2014-08-26 04:46:15 +00:00
parent e051fe3341
commit 149346ff6e
8 changed files with 73 additions and 41 deletions

View File

@ -2705,7 +2705,9 @@ function wp_ajax_parse_embed() {
) ); ) );
} }
wp_send_json_success( $parsed ); wp_send_json_success( array(
'body' => $parsed
) );
} }
function wp_ajax_parse_media_shortcode() { function wp_ajax_parse_media_shortcode() {
@ -2729,19 +2731,21 @@ function wp_ajax_parse_media_shortcode() {
) ); ) );
} }
ob_start(); $head = '';
$styles = wpview_media_sandbox_styles(); $styles = wpview_media_sandbox_styles();
foreach ( $styles as $style ) {
printf( '<link rel="stylesheet" href="%s"/>', $style );
}
echo $shortcode; foreach ( $styles as $style ) {
$head .= '<link type="text/css" rel="stylesheet" href="' . $style . '">';
}
if ( ! empty( $wp_scripts ) ) { if ( ! empty( $wp_scripts ) ) {
$wp_scripts->done = array(); $wp_scripts->done = array();
} }
ob_start();
echo $shortcode;
if ( 'playlist' === $_REQUEST['type'] ) { if ( 'playlist' === $_REQUEST['type'] ) {
wp_underscore_playlist_templates(); wp_underscore_playlist_templates();
@ -2750,5 +2754,8 @@ function wp_ajax_parse_media_shortcode() {
wp_print_scripts( 'wp-mediaelement' ); wp_print_scripts( 'wp-mediaelement' );
} }
wp_send_json_success( ob_get_clean() ); wp_send_json_success( array(
'head' => $head,
'body' => ob_get_clean()
) );
} }

View File

@ -123,16 +123,35 @@ window.wp = window.wp || {};
} ); } );
}, },
/* jshint scripturl: true */ /* jshint scripturl: true */
setIframes: function ( html ) { setIframes: function ( head, body ) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
importStyles = this.type === 'video' || this.type === 'audio' || this.type === 'playlist';
if ( html.indexOf( '<script' ) !== -1 ) { if ( head || body.indexOf( '<script' ) !== -1 ) {
this.getNodes( function ( editor, node, content ) { this.getNodes( function ( editor, node, content ) {
var dom = editor.dom, var dom = editor.dom,
styles = '',
bodyClasses = editor.getBody().className || '',
iframe, iframeDoc, i, resize; iframe, iframeDoc, i, resize;
content.innerHTML = ''; content.innerHTML = '';
if ( importStyles ) {
if ( ! wp.mce.views.sandboxStyles ) {
tinymce.each( dom.$( 'link[rel="stylesheet"]', editor.getDoc().head ), 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 ) + '\n';
}
});
wp.mce.views.sandboxStyles = styles;
} else {
styles = wp.mce.views.sandboxStyles;
}
}
// Seems Firefox needs a bit of time to insert/set the view nodes, or the iframe will fail // Seems Firefox needs a bit of time to insert/set the view nodes, or the iframe will fail
// especially when switching Text => Visual. // especially when switching Text => Visual.
setTimeout( function() { setTimeout( function() {
@ -156,6 +175,8 @@ window.wp = window.wp || {};
'<html>' + '<html>' +
'<head>' + '<head>' +
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' + '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' +
head +
styles +
'<style>' + '<style>' +
'html {' + 'html {' +
'background: transparent;' + 'background: transparent;' +
@ -164,13 +185,18 @@ window.wp = window.wp || {};
'}' + '}' +
'body#wpview-iframe-sandbox {' + 'body#wpview-iframe-sandbox {' +
'background: transparent;' + 'background: transparent;' +
'padding: 1px 0;' + 'padding: 1px 0 !important;' +
'margin: -1px 0 0;' + 'margin: -1px 0 0 !important;' +
'}' +
'body#wpview-iframe-sandbox:before,' +
'body#wpview-iframe-sandbox:after {' +
'display: none;' +
'content: "";' +
'}' + '}' +
'</style>' + '</style>' +
'</head>' + '</head>' +
'<body id="wpview-iframe-sandbox">' + '<body id="wpview-iframe-sandbox" class="' + bodyClasses + '">' +
html + body +
'</body>' + '</body>' +
'</html>' '</html>'
); );
@ -195,10 +221,16 @@ window.wp = window.wp || {};
setTimeout( resize, i * 700 ); setTimeout( resize, i * 700 );
} }
} }
if ( importStyles ) {
editor.on( 'wp-body-class-change', function() {
iframeDoc.body.className = editor.getBody().className;
});
}
}, 50 ); }, 50 );
}); });
} else { } else {
this.setContent( html ); this.setContent( body );
} }
}, },
setError: function( message, dashicon ) { setError: function( message, dashicon ) {
@ -560,7 +592,7 @@ window.wp = window.wp || {};
setNodes: function () { setNodes: function () {
if ( this.parsed ) { if ( this.parsed ) {
this.setIframes( this.parsed ); this.setIframes( this.parsed.head, this.parsed.body );
} else { } else {
this.fail(); this.fail();
} }
@ -579,7 +611,7 @@ window.wp = window.wp || {};
.done( function( response ) { .done( function( response ) {
if ( response ) { if ( response ) {
self.parsed = response; self.parsed = response;
self.setIframes( response ); self.setIframes( response.head, response.body );
} else { } else {
self.fail( true ); self.fail( true );
} }

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,3 @@
#wpview-iframe-sandbox {
color: #444;
font-family: "Open Sans", sans-serif;
font-size: 13px;
line-height: 1.4em;
}
.mejs-container { .mejs-container {
clear: both; clear: both;
} }

View File

@ -260,7 +260,8 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
editor.on( 'init', function() { editor.on( 'init', function() {
var scrolled = false, var scrolled = false,
selection = editor.selection; selection = editor.selection,
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
// When a view is selected, ensure content that is being pasted // When a view is selected, ensure content that is being pasted
// or inserted is added to a text node (instead of the view). // or inserted is added to a text node (instead of the view).
@ -333,6 +334,16 @@ tinymce.PluginManager.add( 'wpview', function( editor ) {
scrolled = false; scrolled = false;
} }
}, true ); }, true );
if ( MutationObserver ) {
new MutationObserver( function() {
editor.fire( 'wp-body-class-change' );
} )
.observe( editor.getBody(), {
attributes: true,
attributeFilter: ['class']
} );
}
}); });
editor.on( 'PreProcess', function( event ) { editor.on( 'PreProcess', function( event ) {

File diff suppressed because one or more lines are too long

View File

@ -3310,19 +3310,8 @@ function attachment_url_to_postid( $url ) {
*/ */
function wpview_media_sandbox_styles() { function wpview_media_sandbox_styles() {
$version = 'ver=' . $GLOBALS['wp_version']; $version = 'ver=' . $GLOBALS['wp_version'];
$open_sans = "//fonts.googleapis.com/css?family=Open+Sans%3A300italic%2C400italic%2C600italic%2C300%2C400%2C600&subset=latin%2Clatin-ext&ver=$version";
$dashicons = includes_url( "css/dashicons.css?$version" );
$mediaelement = includes_url( "js/mediaelement/mediaelementplayer.min.css?$version" ); $mediaelement = includes_url( "js/mediaelement/mediaelementplayer.min.css?$version" );
$wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" ); $wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" );
/** return array( $mediaelement, $wpmediaelement );
* For use by themes that need to override the styling of MediaElement based previews in the Visual editor.
* Not intended for adding editor-style.css. Ideally these styles will be applied by using
* the 'seamless' iframe attribute in the future.
*
* @since 4.0
*
* @param array The URLs to the stylesheets that will be loaded in the sandbox iframe.
*/
return apply_filters( 'wpview_media_sandbox_styles', array( $open_sans, $dashicons, $mediaelement, $wpmediaelement ) );
} }