( function( $, _ ) { var isTouchDevice = ( 'ontouchend' in document ); // this controller contains the application logic wp.media.controller.AddExternal = wp.media.controller.State.extend({ initialize: function(){ // this model contains all the relevant data needed for the application this.props = new Backbone.Model({ url: '' }); this.props.on( 'change:url', this.refresh, this ); }, // called each time the model changes refresh: function() { // update the toolbar this.frame.toolbar.get().refresh(); }, // called when the toolbar button is clicked addoEmbed: function( controller ){ wp.media.post( 'add-oembed', { url: this.props.get( 'url' ), width: this.props.get( 'width' ), height: this.props.get( 'height' ), post_id: wp.media.view.settings.post.id, nonce: wp.media.view.settings.post.nonce }).done( function( response ) { var attachment = wp.media.model.Attachment.create( response ); var edit = controller.state( 'insert' ); // add attachment to the media library edit.get( 'library' ).add( attachment ); }).fail( function() { console.log( 'AJAX failed' ); }); } }); // this toolbar contains the buttons at the bottom wp.media.view.Toolbar.AddExternal = wp.media.view.Toolbar.extend({ initialize: function() { _.defaults( this.options, { event: 'add', close: false, items: { add: { text: wp.media.view.l10n.AddExternalMediaButton, // added via 'media_view_strings' filter, style: 'primary', priority: 80, requires: false, click: this.addoEmbed } } }); wp.media.view.Toolbar.prototype.initialize.apply( this, arguments ); }, // called each time the model changes refresh: function() { // disable the button if there is no data var url = this.controller.state().props.get( 'url' ); this.get( 'add' ).model.set( 'disabled', ! url ); // call the parent refresh wp.media.view.Toolbar.prototype.refresh.apply( this, arguments ); }, // triggered when the button is clicked addoEmbed: function(){ this.controller.state().addoEmbed(this.controller); // switch to the library view this.controller.setState( 'insert' ); } }); // this view contains the main content wp.media.view.AddExternal = wp.media.View.extend({ className: 'media-embed', initialize: function() { this.url = new wp.media.view.AddExternalUrl({ controller: this.controller, model: this.model.props }).render(); this.views.set([ this.url ]); this.refresh(); this.model.on( 'change:type', this.refresh, this ); this.model.on( 'change:loading', this.loading, this ); }, settings: function( view ) { if ( this._settings ) { this._settings.remove(); } this._settings = view; this.views.add( view ); }, refresh: function() { this.settings( new wp.media.view.AddExternalSettings({ controller: this.controller, model: this.model.props, priority: 40 }) ); }, loading: function() { this.$el.toggleClass( 'embed-loading', this.model.get( 'loading' ) ); } }); // this view contains the url field wp.media.view.AddExternalUrl = wp.media.View.extend({ tagName: 'label', className: 'embed-url', events: { 'input': 'updateUrl', 'keyup': 'updateUrl', 'change': 'updateUrl' }, initialize: function() { var self = this; this.$input = $('').val( this.model.get( 'url' ) ); this.input = this.$input[0]; this.$el.append( this.input ); this.model.on( 'change:url', this.render, this ); }, render: function() { var $input = this.$input; if ( $input.is(':focus') ) { return; } this.input.value = this.model.get( 'url' ) || 'http://'; wp.media.View.prototype.render.apply( this, arguments ); return this; }, ready: function() { if ( ! isTouchDevice ) { this.focus(); } }, updateUrl: function( event ) { this.model.set( 'url', event.target.value ); }, focus: function() { var $input = this.$input; if ( $input.is( ':visible' ) ) { $input.focus()[0].select(); } } }); // this view contains the oembed preview, width and height fields wp.media.view.AddExternalSettings = wp.media.view.Settings.extend({ className: 'embed-link-settings', template: wp.media.template( 'add-external-settings' ), initialize: function() { this.spinner = $( '' ); this.$el.append( this.spinner[0] ); this.listenTo( this.model, 'change:url', this.updateoEmbed ); }, updateoEmbed: function() { var url = this.model.get( 'url' ); // clear out previous results this.$( '.embed-container' ).hide().find( '.embed-preview' ).html( '' ); // only proceed with embed if the field contains more than 6 characters if ( url && url.length < 6 ) { return; } this.spinner.show(); setTimeout( _.bind( this.fetch, this ), 500 ); }, fetch: function() { // check if they haven't typed in 500 ms if ( $( '#embed-url-field' ).val() !== this.model.get( 'url' ) ) { return; } wp.ajax.send( 'parse-embed', { data : { post_ID: wp.media.view.settings.post.id, shortcode: '[embed]' + this.model.get( 'url' ) + '[/embed]' } } ).done( _.bind( this.renderoEmbed, this ) ); }, renderoEmbed: function( response ) { var html = ( response && response.body ) || ''; this.spinner.hide(); this.$('.embed-container').show().find('.embed-preview').html( html ); } }); // supersede the default MediaFrame.Post view var oldMediaFrame = wp.media.view.MediaFrame.Post; wp.media.view.MediaFrame.Post = oldMediaFrame.extend({ initialize: function() { oldMediaFrame.prototype.initialize.apply( this, arguments ); this.states.add([ new wp.media.controller.AddExternal({ id: 'add-external', menu: 'default', content: 'custom', title: wp.media.view.l10n.AddExternalMediaMenuTitle, // added via 'media_view_strings' filter priority: 200, toolbar: 'add-external', type: 'link' }) ]); this.on( 'content:render:custom', this.createAddExternalContent, this ); this.on( 'toolbar:create:add-external', this.createAddExternalToolbar, this ); }, createAddExternalToolbar: function(toolbar){ toolbar.view = new wp.media.view.Toolbar.AddExternal({ controller: this }); }, createAddExternalContent: function(){ // this view has no router this.$el.addClass('hide-router'); var view = new wp.media.view.AddExternal({ controller: this, model: this.state() }); this.content.set( view ); } }); }(jQuery, _));