diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php index f7aae0ff52..94e0e6ace8 100644 --- a/src/wp-admin/admin-ajax.php +++ b/src/wp-admin/admin-ajax.php @@ -58,7 +58,7 @@ $core_actions_post = array( 'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment', 'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor', 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs', - 'save-user-color-scheme', 'update-widget', 'query-themes', + 'save-user-color-scheme', 'update-widget', 'query-themes', 'filter-content' ); // Register core Ajax calls. diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 334056af56..15654fbb5b 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2506,3 +2506,24 @@ function wp_ajax_query_themes() { wp_send_json_success( $api ); } + +/** + * Apply `the_content` filters to a string based on the post ID. + * + * @since 4.0.0 + */ +function wp_ajax_filter_content() { + global $post; + + if ( ! $post = get_post( (int) $_REQUEST['post_ID'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'read_post', $post->ID ) ) { + wp_send_json_error(); + } + + setup_postdata( $post ); + + wp_send_json_success( apply_filters( 'the_content', wp_unslash( $_POST['content'] ) ) ); +} diff --git a/src/wp-includes/js/mce-view.js b/src/wp-includes/js/mce-view.js index ec167ca47c..d619e732c4 100644 --- a/src/wp-includes/js/mce-view.js +++ b/src/wp-includes/js/mce-view.js @@ -354,27 +354,7 @@ window.wp = window.wp || {}; */ wp.mce.media = { loaded: false, - /** - * @global wp.shortcode - * - * @param {string} content - * @returns {Object} - */ - toView: function( content ) { - var match = wp.shortcode.next( this.shortcode, content ); - - if ( ! match ) { - return; - } - - return { - index: match.index, - content: match.content, - options: { - shortcode: match.shortcode - } - }; - }, + toView: wp.mce.gallery.toView, /** * Called when a TinyMCE view is clicked for editing. @@ -690,4 +670,79 @@ window.wp = window.wp || {}; View: wp.mce.media.PlaylistView } ); wp.mce.views.register( 'playlist', wp.mce.playlist ); + + wp.mce.embed = { + shortcode: 'embed', + toView: wp.mce.gallery.toView, + View: wp.mce.View.extend( { + className: 'editor-embed', + template: media.template( 'editor-embed' ), + initialize: function( options ) { + this.players = []; + this.content = options.content; + this.parsed = false; + this.shortcode = options.shortcode; + _.bindAll( this, 'setHtml', 'setNode', 'fetch' ); + $( this ).on( 'ready', this.setNode ); + }, + unbind: function() { + var self = this; + this.pauseAllPlayers(); + _.each( this.players, function ( player ) { + self.removePlayer( player ); + } ); + this.players = []; + }, + setNode: function ( e, node ) { + this.node = node; + if ( this.parsed ) { + this.parseMediaShortcodes(); + } else { + this.fetch(); + } + }, + fetch: function () { + wp.ajax.send( 'filter-content', { + data: { + post_ID: $( '#post_ID' ).val(), + content: this.shortcode.string() + } + } ).done( this.setHtml ); + }, + setHtml: function ( content ) { + var scripts = $( content ).find( 'script' ); + + this.parsed = content; + + $( this.node ).html( this.getHtml() ); + if ( scripts ) { + _.each( scripts, function (script) { + var element = document.createElement( 'script' ); + element.type = 'text/javascript'; + element.src = script.src; + tinymce.activeEditor.contentDocument.getElementsByTagName( 'head' )[0].appendChild( element ); + } ); + } + this.parseMediaShortcodes(); + }, + parseMediaShortcodes: function () { + var self = this; + $( '.wp-audio-shortcode, .wp-video-shortcode', this.node ).each( function ( i, element ) { + self.players.push( new MediaElementPlayer( element, self.mejsSettings ) ); + } ); + }, + getHtml: function() { + if ( ! this.parsed ) { + return ''; + } + return this.template({ content: this.parsed }); + } + } ), + edit: function() {} + }; + + _.extend( wp.mce.embed.View.prototype, wp.media.mixin ); + + wp.mce.views.register( 'embed', wp.mce.embed ); + }(jQuery)); diff --git a/src/wp-includes/js/media-audiovideo.js b/src/wp-includes/js/media-audiovideo.js index 47f6d36813..c5b580c513 100644 --- a/src/wp-includes/js/media-audiovideo.js +++ b/src/wp-includes/js/media-audiovideo.js @@ -131,6 +131,10 @@ removePlayer: function(t) { var featureIndex, feature; + if ( ! t.options ) { + return; + } + // invoke features cleanup for ( featureIndex in t.options.features ) { feature = t.options.features[featureIndex]; diff --git a/src/wp-includes/js/tinymce/plugins/wpview/plugin.js b/src/wp-includes/js/tinymce/plugins/wpview/plugin.js index 4e224b0683..4eede11e1f 100644 --- a/src/wp-includes/js/tinymce/plugins/wpview/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wpview/plugin.js @@ -168,6 +168,12 @@ tinymce.PluginManager.add( 'wpview', function( editor ) { event.content = wp.mce.views.toViews( event.content ); }); + editor.on( 'PastePreProcess', function( event ) { + if ( event.content.match( /^\s*(https?:\/\/[^\s"]+)\s*$/im ) ) { + event.content = '[embed]' + event.content + '[/embed]'; + } + } ); + // When the editor's content has been updated and the DOM has been // processed, render the views in the document. editor.on( 'SetContent', function( event ) { diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index a63d68bb3e..f89e32d81c 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -1045,6 +1045,14 @@ function wp_print_media_templates() {
+ +