diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php
index 8516fa56c2..6feed8d849 100644
--- a/wp-admin/includes/media.php
+++ b/wp-admin/includes/media.php
@@ -1275,12 +1275,12 @@ function get_media_item( $attachment_id, $args = null ) {
* @since 2.5.0
*/
function media_upload_header() {
- ?>
-
-
- post_id = ' . intval( $_REQUEST['post_id'] ) . ";\n";
+ if ( empty( $_GET['chromeless'] ) ) {
+ echo '';
+ }
}
/**
diff --git a/wp-includes/css/media-views.css b/wp-includes/css/media-views.css
index b3ecc14f7a..c8951f837e 100644
--- a/wp-includes/css/media-views.css
+++ b/wp-includes/css/media-views.css
@@ -253,6 +253,18 @@
display: none;
}
+/**
+ * Iframes
+ */
+.media-frame .media-iframe {
+ overflow: hidden;
+}
+
+.media-iframe iframe {
+ height: 100%;
+ width: 100%;
+}
+
/**
* Search
*/
diff --git a/wp-includes/js/media-models.js b/wp-includes/js/media-models.js
index 5005ff724e..25becb231e 100644
--- a/wp-includes/js/media-models.js
+++ b/wp-includes/js/media-models.js
@@ -30,6 +30,9 @@ window.wp = window.wp || {};
frame = new MediaFrame.Post( attributes );
delete attributes.frame;
+ // Set the default state.
+ frame.state( frame.options.state );
+ // Render, attach, and open the frame.
return frame.render().attach().open();
};
diff --git a/wp-includes/js/media-views.js b/wp-includes/js/media-views.js
index d5b9648875..e51ede8b28 100644
--- a/wp-includes/js/media-views.js
+++ b/wp-includes/js/media-views.js
@@ -8,6 +8,10 @@
// Link any localized strings.
l10n = media.view.l10n = _.isUndefined( _wpMediaViewsL10n ) ? {} : _wpMediaViewsL10n;
+ // Link any settings.
+ media.view.settings = l10n.settings || {};
+ delete l10n.settings;
+
// Check if the browser supports CSS 3.0 transitions
$.support.transition = (function(){
var style = document.documentElement.style,
@@ -550,7 +554,9 @@
_createStates: function() {
// Create the default `states` collection.
- this.states = new Backbone.Collection();
+ this.states = new Backbone.Collection( null, {
+ model: media.controller.State
+ });
// Ensure states have a reference to the frame.
this.states.on( 'add', function( model ) {
@@ -625,12 +631,87 @@
this.uploader.render().$el.appendTo( this.$el );
return this;
+ },
+
+ createIframeStates: function( options ) {
+ var settings = media.view.settings,
+ tabs = settings.tabs,
+ tabUrl = settings.tabUrl,
+ $postId;
+
+ if ( ! tabs || ! tabUrl )
+ return;
+
+ // Add the post ID to the tab URL if it exists.
+ $postId = $('#post_ID');
+ if ( $postId.length )
+ tabUrl += '&post_id=' + $postId.val();
+
+ // Generate the tab states.
+ _.each( tabs, function( title, id ) {
+ var frame = this.get( 'iframe:' + id ).set( _.defaults({
+ tab: id,
+ src: tabUrl + '&tab=' + id,
+ title: title,
+ content: 'iframe',
+ menu: 'main'
+ }, options ) );
+ }, this );
+
+ this.content.on( 'activate:iframe', this.iframeContent, this );
+ this.menu.on( 'activate:main', this.iframeMenu, this );
+ this.on( 'open', this.hijackThickbox, this );
+ this.on( 'close', this.restoreThickbox, this );
+ },
+
+ iframeContent: function() {
+ this.$el.addClass('hide-toolbar hide-sidebar');
+ this.content.view( new media.view.Iframe({
+ controller: this
+ }).render() );
+ },
+
+ iframeMenu: function() {
+ var views = {};
+
+ _.each( media.view.settings.tabs, function( title, id ) {
+ views[ 'iframe:' + id ] = {
+ text: this.get( 'iframe:' + id ).get('title'),
+ priority: 200
+ };
+ }, this );
+
+ this.menu.view().add( views );
+ },
+
+ hijackThickbox: function() {
+ var frame = this;
+
+ if ( ! window.tb_remove || this._tb_remove )
+ return;
+
+ this._tb_remove = window.tb_remove;
+ window.tb_remove = function() {
+ frame.close();
+ frame.reset();
+ frame.state( frame.options.state );
+ frame._tb_remove.call( window );
+ };
+ },
+
+ restoreThickbox: function() {
+ if ( ! this._tb_remove )
+ return;
+
+ window.tb_remove = this._tb_remove;
+ delete this._tb_remove;
}
});
// Map some of the modal's methods to the frame.
_.each(['open','close','attach','detach'], function( method ) {
media.view.MediaFrame.prototype[ method ] = function( view ) {
+ this.trigger( method );
if ( this.modal )
this.modal[ method ].apply( this.modal, arguments );
return this;
@@ -654,9 +735,6 @@
this.createSelection();
this.createStates();
this.bindHandlers();
-
- // Set the default state.
- this.state( this.options.state );
},
createSelection: function() {
@@ -809,6 +887,7 @@
});
media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
+ this.createIframeStates();
},
createStates: function() {
@@ -2505,4 +2584,20 @@
'change .describe': 'describe'
}
});
+
+ /**
+ * wp.media.view.Iframe
+ */
+ media.view.Iframe = Backbone.View.extend({
+ className: 'media-iframe',
+
+ initialize: function() {
+ this.controller = this.options.controller;
+ },
+
+ render: function() {
+ this.$el.html( '' );
+ return this;
+ }
+ });
}(jQuery));
\ No newline at end of file
diff --git a/wp-includes/media.php b/wp-includes/media.php
index 9ee46e2307..f05a5518ef 100644
--- a/wp-includes/media.php
+++ b/wp-includes/media.php
@@ -1297,7 +1297,30 @@ function wp_prepare_attachment_for_js( $attachment ) {
* @since 3.5.0
*/
function wp_enqueue_media() {
+ // We're going to pass the old thickbox media tabs to `media_upload_tabs`
+ // to ensure plugins will work. We will then unset those tabs.
+ $tabs = array(
+ // handler action suffix => tab text
+ 'type' => __('From Computer'),
+ 'type_url' => __('From URL'),
+ 'gallery' => __('Gallery'),
+ 'library' => __('Media Library'),
+ );
+
+ $tabs = apply_filters( 'media_upload_tabs', $tabs );
+ unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] );
+
+ $settings = array(
+ 'tabs' => $tabs,
+ 'tabUrl' => add_query_arg( array(
+ 'chromeless' => true
+ ), admin_url('media-upload.php') ),
+ );
+
wp_localize_script( 'media-views', '_wpMediaViewsL10n', array(
+ // Settings
+ 'settings' => $settings,
+
// Generic
'insertMedia' => __( 'Insert Media' ),
'search' => __( 'Search' ),