/*globals Backbone, _ */ /** * wp.media.controller.Region * * A region is a persistent application layout area. * * A region assumes one mode at any time, and can be switched to another. * * When mode changes, events are triggered on the region's parent view. * The parent view will listen to specific events and fill the region with an * appropriate view depending on mode. For example, a frame listens for the * 'browse' mode t be activated on the 'content' view and then fills the region * with an AttachmentsBrowser view. * * @class * * @param {object} options Options hash for the region. * @param {string} options.id Unique identifier for the region. * @param {Backbone.View} options.view A parent view the region exists within. * @param {string} options.selector jQuery selector for the region within the parent view. */ var Region = function( options ) { _.extend( this, _.pick( options || {}, 'id', 'view', 'selector' ) ); }; // Use Backbone's self-propagating `extend` inheritance method. Region.extend = Backbone.Model.extend; _.extend( Region.prototype, { /** * Activate a mode. * * @since 3.5.0 * * @param {string} mode * * @fires this.view#{this.id}:activate:{this._mode} * @fires this.view#{this.id}:activate * @fires this.view#{this.id}:deactivate:{this._mode} * @fires this.view#{this.id}:deactivate * * @returns {wp.media.controller.Region} Returns itself to allow chaining. */ mode: function( mode ) { if ( ! mode ) { return this._mode; } // Bail if we're trying to change to the current mode. if ( mode === this._mode ) { return this; } /** * Region mode deactivation event. * * @event this.view#{this.id}:deactivate:{this._mode} * @event this.view#{this.id}:deactivate */ this.trigger('deactivate'); this._mode = mode; this.render( mode ); /** * Region mode activation event. * * @event this.view#{this.id}:activate:{this._mode} * @event this.view#{this.id}:activate */ this.trigger('activate'); return this; }, /** * Render a mode. * * @since 3.5.0 * * @param {string} mode * * @fires this.view#{this.id}:create:{this._mode} * @fires this.view#{this.id}:create * @fires this.view#{this.id}:render:{this._mode} * @fires this.view#{this.id}:render * * @returns {wp.media.controller.Region} Returns itself to allow chaining */ render: function( mode ) { // If the mode isn't active, activate it. if ( mode && mode !== this._mode ) { return this.mode( mode ); } var set = { view: null }, view; /** * Create region view event. * * Region view creation takes place in an event callback on the frame. * * @event this.view#{this.id}:create:{this._mode} * @event this.view#{this.id}:create */ this.trigger( 'create', set ); view = set.view; /** * Render region view event. * * Region view creation takes place in an event callback on the frame. * * @event this.view#{this.id}:create:{this._mode} * @event this.view#{this.id}:create */ this.trigger( 'render', view ); if ( view ) { this.set( view ); } return this; }, /** * Get the region's view. * * @since 3.5.0 * * @returns {wp.media.View} */ get: function() { return this.view.views.first( this.selector ); }, /** * Set the region's view as a subview of the frame. * * @since 3.5.0 * * @param {Array|Object} views * @param {Object} [options={}] * @returns {wp.Backbone.Subviews} Subviews is returned to allow chaining */ set: function( views, options ) { if ( options ) { options.add = false; } return this.view.views.set( this.selector, views, options ); }, /** * Trigger regional view events on the frame. * * @since 3.5.0 * * @param {string} event * @returns {undefined|wp.media.controller.Region} Returns itself to allow chaining. */ trigger: function( event ) { var base, args; if ( ! this._mode ) { return; } args = _.toArray( arguments ); base = this.id + ':' + event; // Trigger `{this.id}:{event}:{this._mode}` event on the frame. args[0] = base + ':' + this._mode; this.view.trigger.apply( this.view, args ); // Trigger `{this.id}:{event}` event on the frame. args[0] = base; this.view.trigger.apply( this.view, args ); return this; } }); module.exports = Region;