Make WordPress Core

Ticket #26870: 26870-media-views.diff

File 26870-media-views.diff, 91.7 KB (added by wonderboymusic, 11 years ago)
  • src/wp-includes/js/media-views.js

     
    11/* global _wpMediaViewsL10n, confirm, getUserSetting, setUserSetting */
    22(function($){
    3         var media       = wp.media,
    4                 Attachment  = media.model.Attachment,
    5                 Attachments = media.model.Attachments,
    6                 l10n;
     3        var media = wp.media, l10n;
    74
    85        // Link any localized strings.
    96        l10n = media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n;
     
    3431                };
    3532        }());
    3633
    37         // Makes it easier to bind events using transitions.
     34        /**
     35         * Makes it easier to bind events using transitions.
     36         *
     37         * @param {string} selector
     38         * @param {Number} sensitivity
     39         * @returns {Promise}
     40         */
    3841        media.transition = function( selector, sensitivity ) {
    3942                var deferred = $.Deferred();
    4043
     
    6669
    6770        /**
    6871         * wp.media.controller.Region
     72         *
     73         * @constructor
     74         * @augments Backbone.Model
     75         *
     76         * @param {Object} [options={}]
    6977         */
    7078        media.controller.Region = function( options ) {
    7179                _.extend( this, _.pick( options || {}, 'id', 'view', 'selector' ) );
     
    7583        media.controller.Region.extend = Backbone.Model.extend;
    7684
    7785        _.extend( media.controller.Region.prototype, {
     86                /**
     87                 * Switch modes
     88                 *
     89                 * @param {string} mode
     90                 *
     91                 * @fires wp.media.controller.Region#{id}:activate:{mode}
     92                 * @fires wp.media.controller.Region#{id}:deactivate:{mode}
     93                 *
     94                 * @returns {wp.media.controller.Region} Returns itself to allow chaining
     95                 */
    7896                mode: function( mode ) {
    79                         if ( ! mode )
     97                        if ( ! mode ) {
    8098                                return this._mode;
    81 
     99                        }
    82100                        // Bail if we're trying to change to the current mode.
    83                         if ( mode === this._mode )
     101                        if ( mode === this._mode ) {
    84102                                return this;
     103                        }
    85104
    86105                        this.trigger('deactivate');
    87106                        this._mode = mode;
     
    89108                        this.trigger('activate');
    90109                        return this;
    91110                },
    92 
     111                /**
     112                 * Render a new mode, the view is set in the `create` callback method
     113                 *   of the extending class
     114                 *
     115                 * If no mode is provided, just re-render the current mode.
     116                 * If the provided mode isn't active, perform a full switch.
     117                 *
     118                 * @param {string} mode
     119                 *
     120                 * @fires wp.media.controller.Region#{id}:create:{mode}
     121                 * @fires wp.media.controller.Region#{id}:render:{mode}
     122                 *
     123                 * @returns {wp.media.controller.Region} Returns itself to allow chaining
     124                 */
    93125                render: function( mode ) {
    94                         // If no mode is provided, just re-render the current mode.
    95                         // If the provided mode isn't active, perform a full switch.
    96                         if ( mode && mode !== this._mode )
     126                        if ( mode && mode !== this._mode ) {
    97127                                return this.mode( mode );
     128                        }
    98129
    99130                        var set = { view: null },
    100131                                view;
     
    102133                        this.trigger( 'create', set );
    103134                        view = set.view;
    104135                        this.trigger( 'render', view );
    105                         if ( view )
     136                        if ( view ) {
    106137                                this.set( view );
     138                        }
    107139                        return this;
    108140                },
    109141
     142                /**
     143                 * @returns {wp.media.View} Returns the selector's first subview
     144                 */
    110145                get: function() {
    111146                        return this.view.views.first( this.selector );
    112147                },
    113148
     149                /**
     150                 * @param {Array|Object} views
     151                 * @param {Object} [options={}]
     152                 * @returns {wp.Backbone.Subviews} Subviews is returned to allow chaining
     153                 */
    114154                set: function( views, options ) {
    115                         if ( options )
     155                        if ( options ) {
    116156                                options.add = false;
     157                        }
    117158                        return this.view.views.set( this.selector, views, options );
    118159                },
    119160
     161                /**
     162                 * Helper function to trigger view events based on {id}:{event}:{mode}
     163                 *
     164                 * @param {string} event
     165                 * @returns {undefined|wp.media.controller.Region} Returns itself to allow chaining
     166                 */
    120167                trigger: function( event ) {
    121168                        var base, args;
    122169
    123                         if ( ! this._mode )
     170                        if ( ! this._mode ) {
    124171                                return;
     172                        }
    125173
    126174                        args = _.toArray( arguments );
    127175                        base = this.id + ':' + event;
     
    139187
    140188        /**
    141189         * wp.media.controller.StateMachine
     190         *
     191         * @constructor
     192         * @augments Backbone.Model
     193         * @mixin
     194         * @mixes Backbone.Events
     195         *
     196         * @param {Array} states
    142197         */
    143198        media.controller.StateMachine = function( states ) {
    144199                this.states = new Backbone.Collection( states );
     
    149204
    150205        // Add events to the `StateMachine`.
    151206        _.extend( media.controller.StateMachine.prototype, Backbone.Events, {
    152 
    153                 // Fetch a state.
    154                 //
    155                 // If no `id` is provided, returns the active state.
    156                 //
    157                 // Implicitly creates states.
     207                /**
     208                 * Fetch a state.
     209                 *
     210                 * If no `id` is provided, returns the active state.
     211                 *
     212                 * Implicitly creates states.
     213                 *
     214                 * Ensure that the `states` collection exists so the `StateMachine`
     215                 *   can be used as a mixin.
     216                 *
     217                 * @param {string} id
     218                 * @returns {wp.media.controller.State} Returns a State model
     219                 *       from the StateMachine collection
     220                 */
    158221                state: function( id ) {
    159                         // Ensure that the `states` collection exists so the `StateMachine`
    160                         // can be used as a mixin.
    161222                        this.states = this.states || new Backbone.Collection();
    162223
    163224                        // Default to the active state.
    164225                        id = id || this._state;
    165226
    166                         if ( id && ! this.states.get( id ) )
     227                        if ( id && ! this.states.get( id ) ) {
    167228                                this.states.add({ id: id });
     229                        }
    168230                        return this.states.get( id );
    169231                },
    170232
    171                 // Sets the active state.
     233                /**
     234                 * Sets the active state.
     235                 *
     236                 * Bail if we're trying to select the current state, if we haven't
     237                 * created the `states` collection, or are trying to select a state
     238                 * that does not exist.
     239                 *
     240                 * @param {string} id
     241                 *
     242                 * @fires wp.media.controller.State#deactivate
     243                 * @fires wp.media.controller.State#activate
     244                 *
     245                 * @returns {wp.media.controller.StateMachine} Returns itself to allow chaining
     246                 */
    172247                setState: function( id ) {
    173248                        var previous = this.state();
    174249
    175                         // Bail if we're trying to select the current state, if we haven't
    176                         // created the `states` collection, or are trying to select a state
    177                         // that does not exist.
    178                         if ( ( previous && id === previous.id ) || ! this.states || ! this.states.get( id ) )
     250                        if ( ( previous && id === previous.id ) || ! this.states || ! this.states.get( id ) ) {
    179251                                return this;
     252                        }
    180253
    181254                        if ( previous ) {
    182255                                previous.trigger('deactivate');
     
    189262                        return this;
    190263                },
    191264
    192                 // Returns the previous active state.
    193                 //
    194                 // Call the `state()` method with no parameters to retrieve the current
    195                 // active state.
     265                /**
     266                 * Returns the previous active state.
     267                 *
     268                 * Call the `state()` method with no parameters to retrieve the current
     269                 * active state.
     270                 *
     271                 * @returns {wp.media.controller.State} Returns a State model
     272                 *       from the StateMachine collection
     273                 */
    196274                lastState: function() {
    197                         if ( this._lastState )
     275                        if ( this._lastState ) {
    198276                                return this.state( this._lastState );
     277                        }
    199278                }
    200279        });
    201280
    202281        // Map methods from the `states` collection to the `StateMachine` itself.
    203282        _.each([ 'on', 'off', 'trigger' ], function( method ) {
     283                /**
     284                 * @returns {wp.media.controller.StateMachine} Returns itself to allow chaining
     285                 */
    204286                media.controller.StateMachine.prototype[ method ] = function() {
    205287                        // Ensure that the `states` collection exists so the `StateMachine`
    206288                        // can be used as a mixin.
     
    211293                };
    212294        });
    213295
    214 
    215         // wp.media.controller.State
    216         // ---------------------------
     296        /**
     297         * wp.media.controller.State
     298         *
     299         * @constructor
     300         * @augments Backbone.Model
     301         */
    217302        media.controller.State = Backbone.Model.extend({
    218303                constructor: function() {
    219304                        this.on( 'activate', this._preActivate, this );
     
    224309                        this.on( 'reset', this.reset, this );
    225310                        this.on( 'ready', this._ready, this );
    226311                        this.on( 'ready', this.ready, this );
     312                        /**
     313                         * Call parent constructor with passed arguments
     314                         */
    227315                        Backbone.Model.apply( this, arguments );
    228316                        this.on( 'change:menu', this._updateMenu, this );
    229317                },
    230318
     319                /**
     320                 * @abstract
     321                 */
    231322                ready: function() {},
     323                /**
     324                 * @abstract
     325                 */
    232326                activate: function() {},
     327                /**
     328                 * @abstract
     329                 */
    233330                deactivate: function() {},
     331                /**
     332                 * @abstract
     333                 */
    234334                reset: function() {},
    235 
     335                /**
     336                 * @access private
     337                 */
    236338                _ready: function() {
    237339                        this._updateMenu();
    238340                },
    239 
     341                /**
     342                 * @access private
     343                 */
    240344                _preActivate: function() {
    241345                        this.active = true;
    242346                },
    243 
     347                /**
     348                 * @access private
     349                 */
    244350                _postActivate: function() {
    245351                        this.on( 'change:menu', this._menu, this );
    246352                        this.on( 'change:titleMode', this._title, this );
     
    255361                        this._content();
    256362                        this._router();
    257363                },
    258 
    259 
     364                /**
     365                 * @access private
     366                 */
    260367                _deactivate: function() {
    261368                        this.active = false;
    262369
     
    267374                        this.off( 'change:content', this._content, this );
    268375                        this.off( 'change:toolbar', this._toolbar, this );
    269376                },
    270 
     377                /**
     378                 * @access private
     379                 */
    271380                _title: function() {
    272381                        this.frame.title.render( this.get('titleMode') || 'default' );
    273382                },
    274 
     383                /**
     384                 * @access private
     385                 */
    275386                _renderTitle: function( view ) {
    276387                        view.$el.text( this.get('title') || '' );
    277388                },
    278 
     389                /**
     390                 * @access private
     391                 */
    279392                _router: function() {
    280393                        var router = this.frame.router,
    281394                                mode = this.get('router'),
    282395                                view;
    283396
    284397                        this.frame.$el.toggleClass( 'hide-router', ! mode );
    285                         if ( ! mode )
     398                        if ( ! mode ) {
    286399                                return;
     400                        }
    287401
    288402                        this.frame.router.render( mode );
    289403
    290404                        view = router.get();
    291                         if ( view && view.select )
     405                        if ( view && view.select ) {
    292406                                view.select( this.frame.content.mode() );
     407                        }
    293408                },
    294 
     409                /**
     410                 * @access private
     411                 */
    295412                _menu: function() {
    296413                        var menu = this.frame.menu,
    297414                                mode = this.get('menu'),
    298415                                view;
    299416
    300                         if ( ! mode )
     417                        if ( ! mode ) {
    301418                                return;
     419                        }
    302420
    303421                        menu.mode( mode );
    304422
    305423                        view = menu.get();
    306                         if ( view && view.select )
     424                        if ( view && view.select ) {
    307425                                view.select( this.id );
     426                        }
    308427                },
    309 
     428                /**
     429                 * @access private
     430                 */
    310431                _updateMenu: function() {
    311432                        var previous = this.previous('menu'),
    312433                                menu = this.get('menu');
    313434
    314                         if ( previous )
     435                        if ( previous ) {
    315436                                this.frame.off( 'menu:render:' + previous, this._renderMenu, this );
     437                        }
    316438
    317                         if ( menu )
     439                        if ( menu ) {
    318440                                this.frame.on( 'menu:render:' + menu, this._renderMenu, this );
     441                        }
    319442                },
    320 
     443                /**
     444                 * @access private
     445                 */
    321446                _renderMenu: function( view ) {
    322447                        var menuItem = this.get('menuItem'),
    323448                                title = this.get('title'),
     
    326451                        if ( ! menuItem && title ) {
    327452                                menuItem = { text: title };
    328453
    329                                 if ( priority )
     454                                if ( priority ) {
    330455                                        menuItem.priority = priority;
     456                                }
    331457                        }
    332458
    333                         if ( ! menuItem )
     459                        if ( ! menuItem ) {
    334460                                return;
     461                        }
    335462
    336463                        view.set( this.id, menuItem );
    337464                }
    338465        });
    339466
    340467        _.each(['toolbar','content'], function( region ) {
     468                /**
     469                 * @access private
     470                 */
    341471                media.controller.State.prototype[ '_' + region ] = function() {
    342472                        var mode = this.get( region );
    343                         if ( mode )
     473                        if ( mode ) {
    344474                                this.frame[ region ].render( mode );
     475                        }
    345476                };
    346477        });
    347478
    348         // wp.media.controller.Library
    349         // ---------------------------
     479        /**
     480         * wp.media.controller.Library
     481         *
     482         * @constructor
     483         * @augments wp.media.controller.State
     484         * @augments Backbone.Model
     485         */
    350486        media.controller.Library = media.controller.State.extend({
    351487                defaults: {
    352488                        id:         'library',
     
    369505                        syncSelection: true
    370506                },
    371507
     508                /**
     509                 * If a library isn't provided, query all media items.
     510                 * If a selection instance isn't provided, create one.
     511                 */
    372512                initialize: function() {
    373513                        var selection = this.get('selection'),
    374514                                props;
    375515
    376                         // If a library isn't provided, query all media items.
    377                         if ( ! this.get('library') )
     516                        if ( ! this.get('library') ) {
    378517                                this.set( 'library', media.query() );
     518                        }
    379519
    380                         // If a selection instance isn't provided, create one.
    381520                        if ( ! (selection instanceof media.model.Selection) ) {
    382521                                props = selection;
    383522
     
    446585                        };
    447586                },
    448587
     588                /**
     589                 * @param {wp.media.model.Attachment} attachment
     590                 * @returns {Backbone.Model}
     591                 */
    449592                display: function( attachment ) {
    450593                        var displays = this._displays;
    451594
    452                         if ( ! displays[ attachment.cid ] )
     595                        if ( ! displays[ attachment.cid ] ) {
    453596                                displays[ attachment.cid ] = new Backbone.Model( this.defaultDisplaySettings( attachment ) );
    454 
     597                        }
    455598                        return displays[ attachment.cid ];
    456599                },
    457600
     601                /**
     602                 * @param {wp.media.model.Attachment} attachment
     603                 * @returns {Object}
     604                 */
    458605                defaultDisplaySettings: function( attachment ) {
    459606                        var settings = this._defaultDisplaySettings;
    460                         if ( settings.canEmbed = this.canEmbed( attachment ) )
     607                        if ( settings.canEmbed = this.canEmbed( attachment ) ) {
    461608                                settings.link = 'embed';
     609                        }
    462610                        return settings;
    463611                },
    464612
     613                /**
     614                 * @param {wp.media.model.Attachment} attachment
     615                 * @returns {Boolean}
     616                 */
    465617                canEmbed: function( attachment ) {
    466618                        // If uploading, we know the filename but not the mime type.
    467619                        if ( ! attachment.get('uploading') ) {
    468620                                var type = attachment.get('type');
    469                                 if ( type !== 'audio' && type !== 'video' )
     621                                if ( type !== 'audio' && type !== 'video' ) {
    470622                                        return false;
     623                                }
    471624                        }
    472625
    473626                        return _.contains( media.view.settings.embedExts, attachment.get('filename').split('.').pop() );
     
    477630                        var selection = this.get('selection'),
    478631                                manager = this.frame._selection;
    479632
    480                         if ( ! this.get('syncSelection') || ! manager || ! selection )
     633                        if ( ! this.get('syncSelection') || ! manager || ! selection ) {
    481634                                return;
     635                        }
    482636
    483637                        // If the selection supports multiple items, validate the stored
    484638                        // attachments based on the new selection's conditions. Record
     
    494648                        selection.single( manager.single );
    495649                },
    496650
     651                /**
     652                 * Record the currently active attachments, which is a combination
     653                 * of the selection's attachments and the set of selected
     654                 * attachments that this specific selection considered invalid.
     655                 * Reset the difference and record the single attachment.
     656                 */
    497657                recordSelection: function() {
    498658                        var selection = this.get('selection'),
    499659                                manager = this.frame._selection;
    500660
    501                         if ( ! this.get('syncSelection') || ! manager || ! selection )
     661                        if ( ! this.get('syncSelection') || ! manager || ! selection ) {
    502662                                return;
     663                        }
    503664
    504                         // Record the currently active attachments, which is a combination
    505                         // of the selection's attachments and the set of selected
    506                         // attachments that this specific selection considered invalid.
    507                         // Reset the difference and record the single attachment.
    508665                        if ( selection.multiple ) {
    509666                                manager.attachments.reset( selection.toArray().concat( manager.difference ) );
    510667                                manager.difference = [];
     
    515672                        manager.single = selection._single;
    516673                },
    517674
     675                /**
     676                 * If the state is active, no items are selected, and the current
     677                 * content mode is not an option in the state's router (provided
     678                 * the state has a router), reset the content mode to the default.
     679                 */
    518680                refreshContent: function() {
    519681                        var selection = this.get('selection'),
    520682                                frame = this.frame,
    521683                                router = frame.router.get(),
    522684                                mode = frame.content.mode();
    523685
    524                         // If the state is active, no items are selected, and the current
    525                         // content mode is not an option in the state's router (provided
    526                         // the state has a router), reset the content mode to the default.
    527                         if ( this.active && ! selection.length && router && ! router.get( mode ) )
     686                        if ( this.active && ! selection.length && router && ! router.get( mode ) ) {
    528687                                this.frame.content.render( this.get('content') );
     688                        }
    529689                },
    530690
     691                /**
     692                 * If the uploader was selected, navigate to the browser.
     693                 *
     694                 * Automatically select any uploading attachments.
     695                 *
     696                 * Selections that don't support multiple attachments automatically
     697                 * limit themselves to one attachment (in this case, the last
     698                 * attachment in the upload queue).
     699                 *
     700                 * @param {wp.media.model.Attachment} attachment
     701                 */
    531702                uploading: function( attachment ) {
    532703                        var content = this.frame.content;
    533704
    534                         // If the uploader was selected, navigate to the browser.
    535                         if ( 'upload' === content.mode() )
     705                        if ( 'upload' === content.mode() ) {
    536706                                this.frame.content.mode('browse');
    537 
    538                         // Automatically select any uploading attachments.
    539                         //
    540                         // Selections that don't support multiple attachments automatically
    541                         // limit themselves to one attachment (in this case, the last
    542                         // attachment in the upload queue).
     707                        }
    543708                        this.get('selection').add( attachment );
    544709                },
    545710
     711                /**
     712                 * Only track the browse router on library states.
     713                 */
    546714                saveContentMode: function() {
    547                         // Only track the browse router on library states.
    548                         if ( 'browse' !== this.get('router') )
     715                        if ( 'browse' !== this.get('router') ) {
    549716                                return;
     717                        }
    550718
    551719                        var mode = this.frame.content.mode(),
    552720                                view = this.frame.router.get();
    553721
    554                         if ( view && view.get( mode ) )
     722                        if ( view && view.get( mode ) ) {
    555723                                setUserSetting( 'libraryContent', mode );
     724                        }
    556725                }
    557726        });
    558727
    559         // wp.media.controller.GalleryEdit
    560         // -------------------------------
     728        /**
     729         * wp.media.controller.GalleryEdit
     730         *
     731         * @constructor
     732         * @augments wp.media.controller.Library
     733         * @augments wp.media.controller.State
     734         * @augments Backbone.Model
     735         */
    561736        media.controller.GalleryEdit = media.controller.Library.extend({
    562737                defaults: {
    563738                        id:         'gallery-edit',
     
    580755
    581756                initialize: function() {
    582757                        // If we haven't been provided a `library`, create a `Selection`.
    583                         if ( ! this.get('library') )
     758                        if ( ! this.get('library') ) {
    584759                                this.set( 'library', new media.model.Selection() );
     760                        }
    585761
    586762                        // The single `Attachment` view to be used in the `Attachments` view.
    587                         if ( ! this.get('AttachmentView') )
     763                        if ( ! this.get('AttachmentView') ) {
    588764                                this.set( 'AttachmentView', media.view.Attachment.EditLibrary );
     765                        }
     766                        /**
     767                         * call 'initialize' directly on the parent class
     768                         */
    589769                        media.controller.Library.prototype.initialize.apply( this, arguments );
    590770                },
    591771
     
    599779                        this.get('library').observe( wp.Uploader.queue );
    600780
    601781                        this.frame.on( 'content:render:browse', this.gallerySettings, this );
    602 
     782                        /**
     783                         * call 'activate' directly on the parent class
     784                         */
    603785                        media.controller.Library.prototype.activate.apply( this, arguments );
    604786                },
    605787
     
    608790                        this.get('library').unobserve( wp.Uploader.queue );
    609791
    610792                        this.frame.off( 'content:render:browse', this.gallerySettings, this );
    611 
     793                        /**
     794                         * call 'deactivate' directly on the parent class
     795                         */
    612796                        media.controller.Library.prototype.deactivate.apply( this, arguments );
    613797                },
    614798
     799                /**
     800                 * @param {Object} browser
     801                 */
    615802                gallerySettings: function( browser ) {
    616803                        var library = this.get('library');
    617804
    618                         if ( ! library || ! browser )
     805                        if ( ! library || ! browser ) {
    619806                                return;
     807                        }
    620808
    621809                        library.gallery = library.gallery || new Backbone.Model();
    622810
     
    639827                }
    640828        });
    641829
    642         // wp.media.controller.GalleryAdd
    643         // ---------------------------------
     830        /**
     831         * wp.media.controller.GalleryAdd
     832         *
     833         * @constructor
     834         * @augments wp.media.controller.Library
     835         * @augments wp.media.controller.State
     836         * @augments Backbone.Model
     837         */
    644838        media.controller.GalleryAdd = media.controller.Library.extend({
    645839                defaults: _.defaults({
    646840                        id:           'gallery-library',
     
    656850                        syncSelection: false
    657851                }, media.controller.Library.prototype.defaults ),
    658852
     853                /**
     854                 * If we haven't been provided a `library`, create a `Selection`.
     855                 */
    659856                initialize: function() {
    660                         // If we haven't been provided a `library`, create a `Selection`.
    661                         if ( ! this.get('library') )
     857                        if ( ! this.get('library') ) {
    662858                                this.set( 'library', media.query({ type: 'image' }) );
    663 
     859                        }
     860                        /**
     861                         * call 'initialize' directly on the parent class
     862                         */
    664863                        media.controller.Library.prototype.initialize.apply( this, arguments );
    665864                },
    666865
     
    674873                        // Accepts attachments that exist in the original library and
    675874                        // that do not exist in gallery's library.
    676875                        library.validator = function( attachment ) {
    677                                 return !! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && media.model.Selection.prototype.validator.apply( this, arguments );
     876                                return !! this.mirroring.get( attachment.cid )
     877                                        && ! edit.get( attachment.cid )
     878                                        /**
     879                                         * call 'validator' directly on wp.media.model.Selection
     880                                         */
     881                                        && media.model.Selection.prototype.validator.apply( this, arguments );
    678882                        };
    679883
    680884                        // Reset the library to ensure that all attachments are re-added
     
    683887                        library.reset( library.mirroring.models, { silent: true });
    684888                        library.observe( edit );
    685889                        this.editLibrary = edit;
    686 
     890                        /**
     891                         * call 'activate' directly on the parent class
     892                         */
    687893                        media.controller.Library.prototype.activate.apply( this, arguments );
    688894                }
    689895        });
    690896
    691         // wp.media.controller.FeaturedImage
    692         // ---------------------------------
     897        /**
     898         * wp.media.controller.FeaturedImage
     899         *
     900         * @constructor
     901         * @augments wp.media.controller.Library
     902         * @augments wp.media.controller.State
     903         * @augments Backbone.Model
     904         */
    693905        media.controller.FeaturedImage = media.controller.Library.extend({
    694906                defaults: _.defaults({
    695907                        id:         'featured-image',
     
    706918                        var library, comparator;
    707919
    708920                        // If we haven't been provided a `library`, create a `Selection`.
    709                         if ( ! this.get('library') )
     921                        if ( ! this.get('library') ) {
    710922                                this.set( 'library', media.query({ type: 'image' }) );
    711 
     923                        }
     924                        /**
     925                         * call 'initialize' directly on the parent class
     926                         */
    712927                        media.controller.Library.prototype.initialize.apply( this, arguments );
    713928
    714929                        library    = this.get('library');
     
    720935                                var aInQuery = !! this.mirroring.get( a.cid ),
    721936                                        bInQuery = !! this.mirroring.get( b.cid );
    722937
    723                                 if ( ! aInQuery && bInQuery )
     938                                if ( ! aInQuery && bInQuery ) {
    724939                                        return -1;
    725                                 else if ( aInQuery && ! bInQuery )
     940                                } else if ( aInQuery && ! bInQuery ) {
    726941                                        return 1;
    727                                 else
     942                                } else {
    728943                                        return comparator.apply( this, arguments );
     944                                }
    729945                        };
    730946
    731947                        // Add all items in the selection to the library, so any featured
     
    736952                activate: function() {
    737953                        this.updateSelection();
    738954                        this.frame.on( 'open', this.updateSelection, this );
     955                        /**
     956                         * call 'activate' directly on the parent class
     957                         */
    739958                        media.controller.Library.prototype.activate.apply( this, arguments );
    740959                },
    741960
    742961                deactivate: function() {
    743962                        this.frame.off( 'open', this.updateSelection, this );
     963                        /**
     964                         * call 'deactivate' directly on the parent class
     965                         */
    744966                        media.controller.Library.prototype.deactivate.apply( this, arguments );
    745967                },
    746968
     
    750972                                attachment;
    751973
    752974                        if ( '' !== id && -1 !== id ) {
    753                                 attachment = Attachment.get( id );
     975                                attachment = media.model.Attachment.get( id );
    754976                                attachment.fetch();
    755977                        }
    756978
     
    758980                }
    759981        });
    760982
    761 
    762         // wp.media.controller.Embed
    763         // -------------------------
     983        /**
     984         * wp.media.controller.Embed
     985         *
     986         * @constructor
     987         * @augments wp.media.controller.State
     988         * @augments Backbone.Model
     989         */
    764990        media.controller.Embed = media.controller.State.extend({
    765991                defaults: {
    766992                        id:      'embed',
     
    7851011                        this.on( 'scan', this.scanImage, this );
    7861012                },
    7871013
     1014                /**
     1015                 * @fires wp.media.controller.Embed#scan
     1016                 */
    7881017                scan: function() {
    7891018                        var scanners,
    7901019                                embed = this,
     
    7961025                        // Scan is triggered with the list of `attributes` to set on the
    7971026                        // state, useful for the 'type' attribute and 'scanners' attribute,
    7981027                        // an array of promise objects for asynchronous scan operations.
    799                         if ( this.props.get('url') )
     1028                        if ( this.props.get('url') ) {
    8001029                                this.trigger( 'scan', attributes );
     1030                        }
    8011031
    8021032                        if ( attributes.scanners.length ) {
    8031033                                scanners = attributes.scanners = $.when.apply( $, attributes.scanners );
     
    8121042                        attributes.loading = !! attributes.scanners;
    8131043                        this.set( attributes );
    8141044                },
    815 
     1045                /**
     1046                 * @param {Object} attributes
     1047                 */
    8161048                scanImage: function( attributes ) {
    8171049                        var frame = this.frame,
    8181050                                state = this,
     
    8261058                        image.onload = function() {
    8271059                                deferred.resolve();
    8281060
    829                                 if ( state !== frame.state() || url !== state.props.get('url') )
     1061                                if ( state !== frame.state() || url !== state.props.get('url') ) {
    8301062                                        return;
     1063                                }
    8311064
    8321065                                state.set({
    8331066                                        type: 'image'
     
    8501083                reset: function() {
    8511084                        this.props.clear().set({ url: '' });
    8521085
    853                         if ( this.active )
     1086                        if ( this.active ) {
    8541087                                this.refresh();
     1088                        }
    8551089                }
    8561090        });
    8571091
     
    8611095         * ========================================================================
    8621096         */
    8631097
    864         // wp.media.View
    865         // -------------
    866         //
    867         // The base view class.
    868         //
    869         // Undelegating events, removing events from the model, and
    870         // removing events from the controller mirror the code for
    871         // `Backbone.View.dispose` in Backbone 0.9.8 development.
    872         //
    873         // This behavior has since been removed, and should not be used
    874         // outside of the media manager.
     1098        /**
     1099         * wp.media.View
     1100         * -------------
     1101         *
     1102         * The base view class.
     1103         *
     1104         * Undelegating events, removing events from the model, and
     1105         * removing events from the controller mirror the code for
     1106         * `Backbone.View.dispose` in Backbone 0.9.8 development.
     1107         *
     1108         * This behavior has since been removed, and should not be used
     1109         * outside of the media manager.
     1110         *
     1111         * @constructor
     1112         * @augments wp.Backbone.View
     1113         * @augments Backbone.View
     1114         */
    8751115        media.View = wp.Backbone.View.extend({
    8761116                constructor: function( options ) {
    877                         if ( options && options.controller )
     1117                        if ( options && options.controller ) {
    8781118                                this.controller = options.controller;
    879 
     1119                        }
    8801120                        wp.Backbone.View.apply( this, arguments );
    8811121                },
    882 
     1122                /**
     1123                 * @returns {wp.media.View} Returns itself to allow chaining
     1124                 */
    8831125                dispose: function() {
    8841126                        // Undelegating events, removing events from the model, and
    8851127                        // removing events from the controller mirror the code for
    8861128                        // `Backbone.View.dispose` in Backbone 0.9.8 development.
    8871129                        this.undelegateEvents();
    8881130
    889                         if ( this.model && this.model.off )
     1131                        if ( this.model && this.model.off ) {
    8901132                                this.model.off( null, null, this );
     1133                        }
    8911134
    892                         if ( this.collection && this.collection.off )
     1135                        if ( this.collection && this.collection.off ) {
    8931136                                this.collection.off( null, null, this );
     1137                        }
    8941138
    8951139                        // Unbind controller events.
    896                         if ( this.controller && this.controller.off )
     1140                        if ( this.controller && this.controller.off ) {
    8971141                                this.controller.off( null, null, this );
     1142                        }
    8981143
    8991144                        return this;
    9001145                },
    901 
     1146                /**
     1147                 * @returns {wp.media.View} Returns itself to allow chaining
     1148                 */
    9021149                remove: function() {
    9031150                        this.dispose();
     1151                        /**
     1152                         * call 'remove' directly on the parent class
     1153                         */
    9041154                        return wp.Backbone.View.prototype.remove.apply( this, arguments );
    9051155                }
    9061156        });
    9071157
    9081158        /**
    9091159         * wp.media.view.Frame
     1160         *
     1161         * @constructor
     1162         * @augments wp.media.View
     1163         * @augments wp.Backbone.View
     1164         * @augments Backbone.View
     1165         * @mixes wp.media.controller.StateMachine
    9101166         */
    9111167        media.view.Frame = media.View.extend({
    9121168                initialize: function() {
     
    9271183                                });
    9281184                        }, this );
    9291185                },
    930 
     1186                /**
     1187                 * @fires wp.media.controller.State#ready
     1188                 */
    9311189                _createStates: function() {
    9321190                        // Create the default `states` collection.
    9331191                        this.states = new Backbone.Collection( null, {
     
    9401198                                model.trigger('ready');
    9411199                        }, this );
    9421200
    943                         if ( this.options.states )
     1201                        if ( this.options.states ) {
    9441202                                this.states.add( this.options.states );
     1203                        }
    9451204                },
    946 
     1205                /**
     1206                 * @returns {wp.media.view.Frame} Returns itself to allow chaining
     1207                 */
    9471208                reset: function() {
    9481209                        this.states.invoke( 'trigger', 'reset' );
    9491210                        return this;
     
    9551216
    9561217        /**
    9571218         * wp.media.view.MediaFrame
     1219         *
     1220         * @constructor
     1221         * @augments wp.media.view.Frame
     1222         * @augments wp.media.View
     1223         * @augments wp.Backbone.View
     1224         * @augments Backbone.View
     1225         * @mixes wp.media.controller.StateMachine
    9581226         */
    9591227        media.view.MediaFrame = media.view.Frame.extend({
    9601228                className: 'media-frame',
    9611229                template:  media.template('media-frame'),
    9621230                regions:   ['menu','title','content','toolbar','router'],
    9631231
     1232                /**
     1233                 * @global wp.Uploader
     1234                 */
    9641235                initialize: function() {
     1236                        /**
     1237                         * call 'initialize' directly on the parent class
     1238                         */
    9651239                        media.view.Frame.prototype.initialize.apply( this, arguments );
    9661240
    9671241                        _.defaults( this.options, {
     
    9851259
    9861260                        // Force the uploader off if the upload limit has been exceeded or
    9871261                        // if the browser isn't supported.
    988                         if ( wp.Uploader.limitExceeded || ! wp.Uploader.browser.supported )
     1262                        if ( wp.Uploader.limitExceeded || ! wp.Uploader.browser.supported ) {
    9891263                                this.options.uploader = false;
     1264                        }
    9901265
    9911266                        // Initialize window-wide uploader.
    9921267                        if ( this.options.uploader ) {
     
    10091284                        // Bind default menu.
    10101285                        this.on( 'menu:create:default', this.createMenu, this );
    10111286                },
    1012 
     1287                /**
     1288                 * @returns {wp.media.view.MediaFrame} Returns itself to allow chaining
     1289                 */
    10131290                render: function() {
    10141291                        // Activate the default state if no active state exists.
    1015                         if ( ! this.state() && this.options.state )
     1292                        if ( ! this.state() && this.options.state ) {
    10161293                                this.setState( this.options.state );
    1017 
     1294                        }
     1295                        /**
     1296                         * call 'render' directly on the parent class
     1297                         */
    10181298                        return media.view.Frame.prototype.render.apply( this, arguments );
    10191299                },
    1020 
     1300                /**
     1301                 * @param {Object} title
     1302                 * @this wp.media.controller.Region
     1303                 */
    10211304                createTitle: function( title ) {
    10221305                        title.view = new media.View({
    10231306                                controller: this,
    10241307                                tagName: 'h1'
    10251308                        });
    10261309                },
    1027 
     1310                /**
     1311                 * @param {Object} menu
     1312                 * @this wp.media.controller.Region
     1313                 */
    10281314                createMenu: function( menu ) {
    10291315                        menu.view = new media.view.Menu({
    10301316                                controller: this
    10311317                        });
    10321318                },
    1033 
     1319                /**
     1320                 * @param {Object} toolbar
     1321                 * @this wp.media.controller.Region
     1322                 */
    10341323                createToolbar: function( toolbar ) {
    10351324                        toolbar.view = new media.view.Toolbar({
    10361325                                controller: this
    10371326                        });
    10381327                },
    1039 
     1328                /**
     1329                 * @param {Object} router
     1330                 * @this wp.media.controller.Region
     1331                 */
    10401332                createRouter: function( router ) {
    10411333                        router.view = new media.view.Router({
    10421334                                controller: this
    10431335                        });
    10441336                },
    1045 
     1337                /**
     1338                 * @param {Object} options
     1339                 */
    10461340                createIframeStates: function( options ) {
    10471341                        var settings = media.view.settings,
    10481342                                tabs = settings.tabs,
    10491343                                tabUrl = settings.tabUrl,
    10501344                                $postId;
    10511345
    1052                         if ( ! tabs || ! tabUrl )
     1346                        if ( ! tabs || ! tabUrl ) {
    10531347                                return;
     1348                        }
    10541349
    10551350                        // Add the post ID to the tab URL if it exists.
    10561351                        $postId = $('#post_ID');
    1057                         if ( $postId.length )
     1352                        if ( $postId.length ) {
    10581353                                tabUrl += '&post_id=' + $postId.val();
     1354                        }
    10591355
    10601356                        // Generate the tab states.
    10611357                        _.each( tabs, function( title, id ) {
     
    10741370                        this.on( 'close', this.restoreThickbox, this );
    10751371                },
    10761372
     1373                /**
     1374                 * @param {Object} content
     1375                 * @this wp.media.controller.Region
     1376                 */
    10771377                iframeContent: function( content ) {
    10781378                        this.$el.addClass('hide-toolbar');
    10791379                        content.view = new media.view.Iframe({
     
    10841384                iframeMenu: function( view ) {
    10851385                        var views = {};
    10861386
    1087                         if ( ! view )
     1387                        if ( ! view ) {
    10881388                                return;
     1389                        }
    10891390
    10901391                        _.each( media.view.settings.tabs, function( title, id ) {
    10911392                                views[ 'iframe:' + id ] = {
     
    11001401                hijackThickbox: function() {
    11011402                        var frame = this;
    11021403
    1103                         if ( ! window.tb_remove || this._tb_remove )
     1404                        if ( ! window.tb_remove || this._tb_remove ) {
    11041405                                return;
     1406                        }
    11051407
    11061408                        this._tb_remove = window.tb_remove;
    11071409                        window.tb_remove = function() {
     
    11131415                },
    11141416
    11151417                restoreThickbox: function() {
    1116                         if ( ! this._tb_remove )
     1418                        if ( ! this._tb_remove ) {
    11171419                                return;
     1420                        }
    11181421
    11191422                        window.tb_remove = this._tb_remove;
    11201423                        delete this._tb_remove;
     
    11231426
    11241427        // Map some of the modal's methods to the frame.
    11251428        _.each(['open','close','attach','detach','escape'], function( method ) {
     1429                /**
     1430                 * @returns {wp.media.view.MediaFrame} Returns itself to allow chaining
     1431                 */
    11261432                media.view.MediaFrame.prototype[ method ] = function() {
    1127                         if ( this.modal )
     1433                        if ( this.modal ) {
    11281434                                this.modal[ method ].apply( this.modal, arguments );
     1435                        }
    11291436                        return this;
    11301437                };
    11311438        });
    11321439
    11331440        /**
    11341441         * wp.media.view.MediaFrame.Select
     1442         *
     1443         * @constructor
     1444         * @augments wp.media.view.MediaFrame
     1445         * @augments wp.media.view.Frame
     1446         * @augments wp.media.View
     1447         * @augments wp.Backbone.View
     1448         * @augments Backbone.View
     1449         * @mixes wp.media.controller.StateMachine
    11351450         */
    11361451        media.view.MediaFrame.Select = media.view.MediaFrame.extend({
    11371452                initialize: function() {
     1453                        /**
     1454                         * call 'initialize' directly on the parent class
     1455                         */
    11381456                        media.view.MediaFrame.prototype.initialize.apply( this, arguments );
    11391457
    11401458                        _.defaults( this.options, {
     
    11591477                        }
    11601478
    11611479                        this._selection = {
    1162                                 attachments: new Attachments(),
     1480                                attachments: new media.model.Attachments(),
    11631481                                difference: []
    11641482                        };
    11651483                },
     
    11671485                createStates: function() {
    11681486                        var options = this.options;
    11691487
    1170                         if ( this.options.states )
     1488                        if ( this.options.states ) {
    11711489                                return;
     1490                        }
    11721491
    11731492                        // Add the default states.
    11741493                        this.states.add([
     
    12041523                        });
    12051524                },
    12061525
    1207                 // Content
     1526                /**
     1527                 * Content
     1528                 *
     1529                 * @param {Object} content
     1530                 * @this wp.media.controller.Region
     1531                 */
    12081532                browseContent: function( content ) {
    12091533                        var state = this.state();
    12101534
     
    12261550                        });
    12271551                },
    12281552
     1553                /**
     1554                 *
     1555                 * @this wp.media.controller.Region
     1556                 */
    12291557                uploadContent: function() {
    12301558                        this.$el.removeClass('hide-toolbar');
    12311559                        this.content.set( new media.view.UploaderInline({
     
    12331561                        }) );
    12341562                },
    12351563
    1236                 // Toolbars
     1564                /**
     1565                 * Toolbars
     1566                 *
     1567                 * @param {Object} toolbar
     1568                 * @param {Object} [options={}]
     1569                 * @this wp.media.controller.Region
     1570                 */
    12371571                createSelectToolbar: function( toolbar, options ) {
    12381572                        options = options || this.options.button || {};
    12391573                        options.controller = this;
     
    12441578
    12451579        /**
    12461580         * wp.media.view.MediaFrame.Post
     1581         *
     1582         * @constructor
     1583         * @augments wp.media.view.MediaFrame.Select
     1584         * @augments wp.media.view.MediaFrame
     1585         * @augments wp.media.view.Frame
     1586         * @augments wp.media.View
     1587         * @augments wp.Backbone.View
     1588         * @augments Backbone.View
     1589         * @mixes wp.media.controller.StateMachine
    12471590         */
    12481591        media.view.MediaFrame.Post = media.view.MediaFrame.Select.extend({
    12491592                initialize: function() {
     
    12521595                                editing:   false,
    12531596                                state:    'insert'
    12541597                        });
    1255 
     1598                        /**
     1599                         * call 'initialize' directly on the parent class
     1600                         */
    12561601                        media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments );
    12571602                        this.createIframeStates();
    12581603                },
     
    13181663                },
    13191664
    13201665                bindHandlers: function() {
     1666                        /**
     1667                         * call 'bindHandlers' directly on the parent class
     1668                         */
    13211669                        media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments );
    13221670                        this.on( 'menu:create:gallery', this.createMenu, this );
    13231671                        this.on( 'toolbar:create:main-insert', this.createToolbar, this );
     
    13261674                        this.on( 'toolbar:create:main-embed', this.mainEmbedToolbar, this );
    13271675
    13281676                        var handlers = {
    1329                                         menu: {
    1330                                                 'default': 'mainMenu',
    1331                                                 'gallery': 'galleryMenu'
    1332                                         },
     1677                                menu: {
     1678                                        'default': 'mainMenu',
     1679                                        'gallery': 'galleryMenu'
     1680                                },
    13331681
    1334                                         content: {
    1335                                                 'embed':          'embedContent',
    1336                                                 'edit-selection': 'editSelectionContent'
    1337                                         },
     1682                                content: {
     1683                                        'embed':          'embedContent',
     1684                                        'edit-selection': 'editSelectionContent'
     1685                                },
    13381686
    1339                                         toolbar: {
    1340                                                 'main-insert':      'mainInsertToolbar',
    1341                                                 'main-gallery':     'mainGalleryToolbar',
    1342                                                 'gallery-edit':     'galleryEditToolbar',
    1343                                                 'gallery-add':      'galleryAddToolbar'
    1344                                         }
    1345                                 };
     1687                                toolbar: {
     1688                                        'main-insert':      'mainInsertToolbar',
     1689                                        'main-gallery':     'mainGalleryToolbar',
     1690                                        'gallery-edit':     'galleryEditToolbar',
     1691                                        'gallery-add':      'galleryAddToolbar'
     1692                                }
     1693                        };
    13461694
    13471695                        _.each( handlers, function( regionHandlers, region ) {
    13481696                                _.each( regionHandlers, function( callback, handler ) {
     
    13521700                },
    13531701
    13541702                // Menus
     1703                /**
     1704                 * @param {wp.Backbone.View} view
     1705                 */
    13551706                mainMenu: function( view ) {
    13561707                        view.set({
    13571708                                'library-separator': new media.View({
     
    13601711                                })
    13611712                        });
    13621713                },
    1363 
     1714                /**
     1715                 * @param {wp.Backbone.View} view
     1716                 */
    13641717                galleryMenu: function( view ) {
    13651718                        var lastState = this.lastState(),
    13661719                                previous = lastState && lastState.id,
     
    14261779                },
    14271780
    14281781                // Toolbars
     1782
     1783                /**
     1784                 * @param {wp.Backbone.View} view
     1785                 */
    14291786                selectionStatusToolbar: function( view ) {
    14301787                        var editable = this.state().get('editable');
    14311788
     
    14421799                        }).render() );
    14431800                },
    14441801
     1802                /**
     1803                 * @param {wp.Backbone.View} view
     1804                 */
    14451805                mainInsertToolbar: function( view ) {
    14461806                        var controller = this;
    14471807
     
    14531813                                text:     l10n.insertIntoPost,
    14541814                                requires: { selection: true },
    14551815
     1816                                /**
     1817                                 * @fires wp.media.controller.State#insert
     1818                                 */
    14561819                                click: function() {
    14571820                                        var state = controller.state(),
    14581821                                                selection = state.get('selection');
     
    14631826                        });
    14641827                },
    14651828
     1829                /**
     1830                 * @param {wp.Backbone.View} view
     1831                 */
    14661832                mainGalleryToolbar: function( view ) {
    14671833                        var controller = this;
    14681834
     
    15131879                                                priority: 80,
    15141880                                                requires: { library: true },
    15151881
     1882                                                /**
     1883                                                 * @fires wp.media.controller.State#update
     1884                                                 */
    15161885                                                click: function() {
    15171886                                                        var controller = this.controller,
    15181887                                                                state = controller.state();
     
    15391908                                                priority: 80,
    15401909                                                requires: { selection: true },
    15411910
     1911                                                /**
     1912                                                 * @fires wp.media.controller.State#reset
     1913                                                 */
    15421914                                                click: function() {
    15431915                                                        var controller = this.controller,
    15441916                                                                state = controller.state(),
     
    15561928
    15571929        /**
    15581930         * wp.media.view.Modal
     1931         *
     1932         * @constructor
     1933         * @augments wp.media.View
     1934         * @augments wp.Backbone.View
     1935         * @augments Backbone.View
    15591936         */
    15601937        media.view.Modal = media.View.extend({
    15611938                tagName:  'div',
     
    15781955                                freeze:    true
    15791956                        });
    15801957                },
    1581 
     1958                /**
     1959                 * @returns {Object}
     1960                 */
    15821961                prepare: function() {
    15831962                        return {
    15841963                                title: this.options.title
    15851964                        };
    15861965                },
    15871966
     1967                /**
     1968                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     1969                 */
    15881970                attach: function() {
    1589                         if ( this.views.attached )
     1971                        if ( this.views.attached ) {
    15901972                                return this;
     1973                        }
    15911974
    1592                         if ( ! this.views.rendered )
     1975                        if ( ! this.views.rendered ) {
    15931976                                this.render();
     1977                        }
    15941978
    15951979                        this.$el.appendTo( this.options.container );
    15961980
     
    16011985                        return this.propagate('attach');
    16021986                },
    16031987
     1988                /**
     1989                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     1990                 */
    16041991                detach: function() {
    1605                         if ( this.$el.is(':visible') )
     1992                        if ( this.$el.is(':visible') ) {
    16061993                                this.close();
     1994                        }
    16071995
    16081996                        this.$el.detach();
    16091997                        this.views.attached = false;
    16101998                        return this.propagate('detach');
    16111999                },
    16122000
     2001                /**
     2002                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     2003                 */
    16132004                open: function() {
    16142005                        var $el = this.$el,
    16152006                                options = this.options;
    16162007
    1617                         if ( $el.is(':visible') )
     2008                        if ( $el.is(':visible') ) {
    16182009                                return this;
     2010                        }
    16192011
    1620                         if ( ! this.views.attached )
     2012                        if ( ! this.views.attached ) {
    16212013                                this.attach();
     2014                        }
    16222015
    16232016                        // If the `freeze` option is set, record the window's scroll position.
    16242017                        if ( options.freeze ) {
     
    16312024                        return this.propagate('open');
    16322025                },
    16332026
     2027                /**
     2028                 * @param {Object} options
     2029                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     2030                 */
    16342031                close: function( options ) {
    16352032                        var freeze = this._freeze;
    16362033
    1637                         if ( ! this.views.attached || ! this.$el.is(':visible') )
     2034                        if ( ! this.views.attached || ! this.$el.is(':visible') ) {
    16382035                                return this;
     2036                        }
    16392037
    16402038                        this.$el.hide();
    16412039                        this.propagate('close');
     
    16452043                                $( window ).scrollTop( freeze.scrollTop );
    16462044                        }
    16472045
    1648                         if ( options && options.escape )
     2046                        if ( options && options.escape ) {
    16492047                                this.propagate('escape');
     2048                        }
    16502049
    16512050                        return this;
    16522051                },
    1653 
     2052                /**
     2053                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     2054                 */
    16542055                escape: function() {
    16552056                        return this.close({ escape: true });
    16562057                },
    1657 
     2058                /**
     2059                 * @param {Object} event
     2060                 */
    16582061                escapeHandler: function( event ) {
    16592062                        event.preventDefault();
    16602063                        this.escape();
    16612064                },
    16622065
     2066                /**
     2067                 * @param {Array|Object} content Views to register to '.media-modal-content'
     2068                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     2069                 */
    16632070                content: function( content ) {
    16642071                        this.views.set( '.media-modal-content', content );
    16652072                        return this;
    16662073                },
    16672074
    1668                 // Triggers a modal event and if the `propagate` option is set,
    1669                 // forwards events to the modal's controller.
     2075                /**
     2076                 * Triggers a modal event and if the `propagate` option is set,
     2077                 * forwards events to the modal's controller.
     2078                 *
     2079                 * @param {string} id
     2080                 * @returns {wp.media.view.Modal} Returns itself to allow chaining
     2081                 */
    16702082                propagate: function( id ) {
    16712083                        this.trigger( id );
    16722084
    1673                         if ( this.options.propagate )
     2085                        if ( this.options.propagate ) {
    16742086                                this.controller.trigger( id );
     2087                        }
    16752088
    16762089                        return this;
    16772090                },
    1678 
     2091                /**
     2092                 * @param {Object} event
     2093                 */
    16792094                keydown: function( event ) {
    16802095                        // Close the modal when escape is pressed.
    16812096                        if ( 27 === event.which ) {
     
    16862101                }
    16872102        });
    16882103
    1689         // wp.media.view.FocusManager
    1690         // ----------------------------
     2104        /**
     2105         * wp.media.view.FocusManager
     2106         *
     2107         * @constructor
     2108         * @augments wp.media.View
     2109         * @augments wp.Backbone.View
     2110         * @augments Backbone.View
     2111         */
    16912112        media.view.FocusManager = media.View.extend({
    16922113                events: {
    16932114                        keydown: 'recordTab',
     
    16952116                },
    16962117
    16972118                focus: function() {
    1698                         if ( _.isUndefined( this.index ) )
     2119                        if ( _.isUndefined( this.index ) ) {
    16992120                                return;
     2121                        }
    17002122
    17012123                        // Update our collection of `$tabbables`.
    17022124                        this.$tabbables = this.$(':tabbable');
     
    17042126                        // If tab is saved, focus it.
    17052127                        this.$tabbables.eq( this.index ).focus();
    17062128                },
    1707 
     2129                /**
     2130                 * @param {Object} event
     2131                 */
    17082132                recordTab: function( event ) {
    17092133                        // Look for the tab key.
    1710                         if ( 9 !== event.keyCode )
     2134                        if ( 9 !== event.keyCode ) {
    17112135                                return;
     2136                        }
    17122137
    17132138                        // First try to update the index.
    1714                         if ( _.isUndefined( this.index ) )
     2139                        if ( _.isUndefined( this.index ) ) {
    17152140                                this.updateIndex( event );
     2141                        }
    17162142
    17172143                        // If we still don't have an index, bail.
    1718                         if ( _.isUndefined( this.index ) )
     2144                        if ( _.isUndefined( this.index ) ) {
    17192145                                return;
     2146                        }
    17202147
    17212148                        var index = this.index + ( event.shiftKey ? -1 : 1 );
    17222149
    1723                         if ( index >= 0 && index < this.$tabbables.length )
     2150                        if ( index >= 0 && index < this.$tabbables.length ) {
    17242151                                this.index = index;
    1725                         else
     2152                        } else {
    17262153                                delete this.index;
     2154                        }
    17272155                },
    1728 
     2156                /**
     2157                 * @param {Object} event
     2158                 */
    17292159                updateIndex: function( event ) {
    17302160                        this.$tabbables = this.$(':tabbable');
    17312161
    17322162                        var index = this.$tabbables.index( event.target );
    17332163
    1734                         if ( -1 === index )
     2164                        if ( -1 === index ) {
    17352165                                delete this.index;
    1736                         else
     2166                        } else {
    17372167                                this.index = index;
     2168                        }
    17382169                }
    17392170        });
    17402171
    1741         // wp.media.view.UploaderWindow
    1742         // ----------------------------
     2172        /**
     2173         * wp.media.view.UploaderWindow
     2174         *
     2175         * @constructor
     2176         * @augments wp.media.View
     2177         * @augments wp.Backbone.View
     2178         * @augments Backbone.View
     2179         */
    17432180        media.view.UploaderWindow = media.View.extend({
    17442181                tagName:   'div',
    17452182                className: 'uploader-window',
     
    17572194                        });
    17582195
    17592196                        // Ensure the dropzone is a jQuery collection.
    1760                         if ( uploader.dropzone && ! (uploader.dropzone instanceof $) )
     2197                        if ( uploader.dropzone && ! (uploader.dropzone instanceof $) ) {
    17612198                                uploader.dropzone = $( uploader.dropzone );
     2199                        }
    17622200
    17632201                        this.controller.on( 'activate', this.refresh, this );
    17642202                },
    17652203
    17662204                refresh: function() {
    1767                         if ( this.uploader )
     2205                        if ( this.uploader ) {
    17682206                                this.uploader.refresh();
     2207                        }
    17692208                },
    17702209
    17712210                ready: function() {
     
    17732212                                dropzone;
    17742213
    17752214                        // If the uploader already exists, bail.
    1776                         if ( this.uploader )
     2215                        if ( this.uploader ) {
    17772216                                return;
     2217                        }
    17782218
    1779                         if ( postId )
     2219                        if ( postId ) {
    17802220                                this.options.uploader.params.post_id = postId;
    1781 
     2221                        }
    17822222                        this.uploader = new wp.Uploader( this.options.uploader );
    17832223
    17842224                        dropzone = this.uploader.dropzone;
     
    18082248                }
    18092249        });
    18102250
     2251        /**
     2252         * wp.media.view.UploaderInline
     2253         *
     2254         * @constructor
     2255         * @augments wp.media.View
     2256         * @augments wp.Backbone.View
     2257         * @augments Backbone.View
     2258         */
    18112259        media.view.UploaderInline = media.View.extend({
    18122260                tagName:   'div',
    18132261                className: 'uploader-inline',
     
    18192267                                status:  true
    18202268                        });
    18212269
    1822                         if ( ! this.options.$browser && this.controller.uploader )
     2270                        if ( ! this.options.$browser && this.controller.uploader ) {
    18232271                                this.options.$browser = this.controller.uploader.$browser;
     2272                        }
    18242273
    1825                         if ( _.isUndefined( this.options.postId ) )
     2274                        if ( _.isUndefined( this.options.postId ) ) {
    18262275                                this.options.postId = media.view.settings.post.id;
     2276                        }
    18272277
    18282278                        if ( this.options.status ) {
    18292279                                this.views.set( '.upload-inline-status', new media.view.UploaderStatus({
     
    18312281                                }) );
    18322282                        }
    18332283                },
    1834 
     2284                /**
     2285                 * @returns {wp.media.view.UploaderInline} Returns itself to allow chaining
     2286                 */
    18352287                dispose: function() {
    1836                         if ( this.disposing )
     2288                        if ( this.disposing ) {
     2289                                /**
     2290                                 * call 'dispose' directly on the parent class
     2291                                 */
    18372292                                return media.View.prototype.dispose.apply( this, arguments );
     2293                        }
    18382294
    18392295                        // Run remove on `dispose`, so we can be sure to refresh the
    18402296                        // uploader with a view-less DOM. Track whether we're disposing
     
    18422298                        this.disposing = true;
    18432299                        return this.remove();
    18442300                },
    1845 
     2301                /**
     2302                 * @returns {wp.media.view.UploaderInline} Returns itself to allow chaining
     2303                 */
    18462304                remove: function() {
     2305                        /**
     2306                         * call 'remove' directly on the parent class
     2307                         */
    18472308                        var result = media.View.prototype.remove.apply( this, arguments );
    18482309
    18492310                        _.defer( _.bind( this.refresh, this ) );
     
    18532314                refresh: function() {
    18542315                        var uploader = this.controller.uploader;
    18552316
    1856                         if ( uploader )
     2317                        if ( uploader ) {
    18572318                                uploader.refresh();
     2319                        }
    18582320                },
    1859 
     2321                /**
     2322                 * @returns {wp.media.view.UploaderInline}
     2323                 */
    18602324                ready: function() {
    18612325                        var $browser = this.options.$browser,
    18622326                                $placeholder;
     
    18652329                                $placeholder = this.$('.browser');
    18662330
    18672331                                // Check if we've already replaced the placeholder.
    1868                                 if ( $placeholder[0] === $browser[0] )
     2332                                if ( $placeholder[0] === $browser[0] ) {
    18692333                                        return;
     2334                                }
    18702335
    18712336                                $browser.detach().text( $placeholder.text() );
    18722337                                $browser[0].className = $placeholder[0].className;
     
    18802345
    18812346        /**
    18822347         * wp.media.view.UploaderStatus
     2348         *
     2349         * @constructor
     2350         * @augments wp.media.View
     2351         * @augments wp.Backbone.View
     2352         * @augments Backbone.View
    18832353         */
    18842354        media.view.UploaderStatus = media.View.extend({
    18852355                className: 'media-uploader-status',
     
    19002370                        this.errors.on( 'add remove reset', this.visibility, this );
    19012371                        this.errors.on( 'add', this.error, this );
    19022372                },
    1903 
     2373                /**
     2374                 * @global wp.Uploader
     2375                 * @returns {wp.media.view.UploaderStatus}
     2376                 */
    19042377                dispose: function() {
    19052378                        wp.Uploader.queue.off( null, null, this );
     2379                        /**
     2380                         * call 'dispose' directly on the parent class
     2381                         */
    19062382                        media.View.prototype.dispose.apply( this, arguments );
    19072383                        return this;
    19082384                },
     
    19322408                        var queue = this.queue,
    19332409                                $bar = this.$bar;
    19342410
    1935                         if ( ! $bar || ! queue.length )
     2411                        if ( ! $bar || ! queue.length ) {
    19362412                                return;
     2413                        }
    19372414
    19382415                        $bar.width( ( queue.reduce( function( memo, attachment ) {
    1939                                 if ( ! attachment.get('uploading') )
     2416                                if ( ! attachment.get('uploading') ) {
    19402417                                        return memo + 100;
     2418                                }
    19412419
    19422420                                var percent = attachment.get('percent');
    19432421                                return memo + ( _.isNumber( percent ) ? percent : 100 );
     
    19482426                        var queue = this.queue,
    19492427                                index = 0, active;
    19502428
    1951                         if ( ! queue.length )
     2429                        if ( ! queue.length ) {
    19522430                                return;
     2431                        }
    19532432
    19542433                        active = this.queue.find( function( attachment, i ) {
    19552434                                index = i;
     
    19602439                        this.$total.text( queue.length );
    19612440                        this.$filename.html( active ? this.filename( active.get('filename') ) : '' );
    19622441                },
    1963 
     2442                /**
     2443                 * @param {string} filename
     2444                 * @returns {string}
     2445                 */
    19642446                filename: function( filename ) {
    19652447                        return media.truncate( _.escape( filename ), 24 );
    19662448                },
    1967 
     2449                /**
     2450                 * @param {Backbone.Model} error
     2451                 */
    19682452                error: function( error ) {
    19692453                        this.views.add( '.upload-errors', new media.view.UploaderStatusError({
    19702454                                filename: this.filename( error.get('file').name ),
     
    19722456                        }), { at: 0 });
    19732457                },
    19742458
     2459                /**
     2460                 * @global wp.Uploader
     2461                 *
     2462                 * @param {Object} event
     2463                 */
    19752464                dismiss: function( event ) {
    19762465                        var errors = this.views.get('.upload-errors');
    19772466
    19782467                        event.preventDefault();
    19792468
    1980                         if ( errors )
     2469                        if ( errors ) {
    19812470                                _.invoke( errors, 'remove' );
     2471                        }
    19822472                        wp.Uploader.errors.reset();
    19832473                }
    19842474        });
    19852475
     2476        /**
     2477         * wp.media.view.UploaderStatusError
     2478         *
     2479         * @constructor
     2480         * @augments wp.media.View
     2481         * @augments wp.Backbone.View
     2482         * @augments Backbone.View
     2483         */
    19862484        media.view.UploaderStatusError = media.View.extend({
    19872485                className: 'upload-error',
    19882486                template:  media.template('uploader-status-error')
     
    19902488
    19912489        /**
    19922490         * wp.media.view.Toolbar
     2491         *
     2492         * @constructor
     2493         * @augments wp.media.View
     2494         * @augments wp.Backbone.View
     2495         * @augments Backbone.View
    19932496         */
    19942497        media.view.Toolbar = media.View.extend({
    19952498                tagName:   'div',
     
    20102513
    20112514                        this.views.set([ this.secondary, this.primary ]);
    20122515
    2013                         if ( this.options.items )
     2516                        if ( this.options.items ) {
    20142517                                this.set( this.options.items, { silent: true });
     2518                        }
    20152519
    2016                         if ( ! this.options.silent )
     2520                        if ( ! this.options.silent ) {
    20172521                                this.render();
     2522                        }
    20182523
    2019                         if ( selection )
     2524                        if ( selection ) {
    20202525                                selection.on( 'add remove reset', this.refresh, this );
    2021                         if ( library )
     2526                        }
     2527
     2528                        if ( library ) {
    20222529                                library.on( 'add remove reset', this.refresh, this );
     2530                        }
    20232531                },
    2024 
     2532                /**
     2533                 * @returns {wp.media.view.Toolbar} Returns itsef to allow chaining
     2534                 */
    20252535                dispose: function() {
    2026                         if ( this.selection )
     2536                        if ( this.selection ) {
    20272537                                this.selection.off( null, null, this );
    2028                         if ( this.library )
     2538                        }
     2539
     2540                        if ( this.library ) {
    20292541                                this.library.off( null, null, this );
     2542                        }
     2543                        /**
     2544                         * call 'dispose' directly on the parent class
     2545                         */
    20302546                        return media.View.prototype.dispose.apply( this, arguments );
    20312547                },
    20322548
     
    20342550                        this.refresh();
    20352551                },
    20362552
     2553                /**
     2554                 * @param {string} id
     2555                 * @param {Backbone.View|Object} view
     2556                 * @param {Object} [options={}]
     2557                 * @returns {wp.media.view.Toolbar} Returns itself to allow chaining
     2558                 */
    20372559                set: function( id, view, options ) {
    20382560                        var list;
    20392561                        options = options || {};
     
    20582580                                this[ list ].set( id, view, options );
    20592581                        }
    20602582
    2061                         if ( ! options.silent )
     2583                        if ( ! options.silent ) {
    20622584                                this.refresh();
     2585                        }
    20632586
    20642587                        return this;
    20652588                },
    2066 
     2589                /**
     2590                 * @param {string} id
     2591                 * @returns {wp.media.view.Button}
     2592                 */
    20672593                get: function( id ) {
    20682594                        return this._views[ id ];
    20692595                },
    2070 
     2596                /**
     2597                 * @param {string} id
     2598                 * @param {Object} options
     2599                 * @returns {wp.media.view.Toolbar} Returns itself to allow chaining
     2600                 */
    20712601                unset: function( id, options ) {
    20722602                        delete this._views[ id ];
    20732603                        this.primary.unset( id, options );
    20742604                        this.secondary.unset( id, options );
    20752605
    2076                         if ( ! options || ! options.silent )
     2606                        if ( ! options || ! options.silent ) {
    20772607                                this.refresh();
     2608                        }
    20782609                        return this;
    20792610                },
    20802611
     
    20842615                                selection = state.get('selection');
    20852616
    20862617                        _.each( this._views, function( button ) {
    2087                                 if ( ! button.model || ! button.options || ! button.options.requires )
     2618                                if ( ! button.model || ! button.options || ! button.options.requires ) {
    20882619                                        return;
     2620                                }
    20892621
    20902622                                var requires = button.options.requires,
    20912623                                        disabled = false;
     
    20952627                                        return attachment.get('uploading') === true;
    20962628                                });
    20972629
    2098                                 if ( requires.selection && selection && ! selection.length )
     2630                                if ( requires.selection && selection && ! selection.length ) {
    20992631                                        disabled = true;
    2100                                 else if ( requires.library && library && ! library.length )
     2632                                } else if ( requires.library && library && ! library.length ) {
    21012633                                        disabled = true;
    2102 
     2634                                }
    21032635                                button.model.set( 'disabled', disabled );
    21042636                        });
    21052637                }
    21062638        });
    21072639
    2108         // wp.media.view.Toolbar.Select
    2109         // ----------------------------
     2640        /**
     2641         * wp.media.view.Toolbar.Select
     2642         *
     2643         * @constructor
     2644         * @augments wp.media.view.Toolbar
     2645         * @augments wp.media.View
     2646         * @augments wp.Backbone.View
     2647         * @augments Backbone.View
     2648         */
    21102649        media.view.Toolbar.Select = media.view.Toolbar.extend({
    21112650                initialize: function() {
    21122651                        var options = this.options;
     
    21352674                                        requires: options.requires
    21362675                                }
    21372676                        });
    2138 
     2677                        /**
     2678                         * call 'initialize' directly on the parent class
     2679                         */
    21392680                        media.view.Toolbar.prototype.initialize.apply( this, arguments );
    21402681                },
    21412682
     
    21432684                        var options = this.options,
    21442685                                controller = this.controller;
    21452686
    2146                         if ( options.close )
     2687                        if ( options.close ) {
    21472688                                controller.close();
     2689                        }
    21482690
    2149                         if ( options.event )
     2691                        if ( options.event ) {
    21502692                                controller.state().trigger( options.event );
     2693                        }
    21512694
    2152                         if ( options.state )
     2695                        if ( options.state ) {
    21532696                                controller.setState( options.state );
     2697                        }
    21542698
    2155                         if ( options.reset )
     2699                        if ( options.reset ) {
    21562700                                controller.reset();
     2701                        }
    21572702                }
    21582703        });
    21592704
    2160         // wp.media.view.Toolbar.Embed
    2161         // ---------------------------
     2705        /**
     2706         * wp.media.view.Toolbar.Embed
     2707         *
     2708         * @constructor
     2709         * @augments wp.media.view.Toolbar.Select
     2710         * @augments wp.media.view.Toolbar
     2711         * @augments wp.media.View
     2712         * @augments wp.Backbone.View
     2713         * @augments Backbone.View
     2714         */
    21622715        media.view.Toolbar.Embed = media.view.Toolbar.Select.extend({
    21632716                initialize: function() {
    21642717                        _.defaults( this.options, {
    21652718                                text: l10n.insertIntoPost,
    21662719                                requires: false
    21672720                        });
    2168 
     2721                        /**
     2722                         * call 'initialize' directly on the parent class
     2723                         */
    21692724                        media.view.Toolbar.Select.prototype.initialize.apply( this, arguments );
    21702725                },
    21712726
    21722727                refresh: function() {
    21732728                        var url = this.controller.state().props.get('url');
    21742729                        this.get('select').model.set( 'disabled', ! url || url === 'http://' );
    2175 
     2730                        /**
     2731                         * call 'refresh' directly on the parent class
     2732                         */
    21762733                        media.view.Toolbar.Select.prototype.refresh.apply( this, arguments );
    21772734                }
    21782735        });
    21792736
    21802737        /**
    21812738         * wp.media.view.Button
     2739         *
     2740         * @constructor
     2741         * @augments wp.media.View
     2742         * @augments wp.Backbone.View
     2743         * @augments Backbone.View
    21822744         */
    21832745        media.view.Button = media.View.extend({
    21842746                tagName:    'a',
     
    21972759                },
    21982760
    21992761                initialize: function() {
    2200                         // Create a model with the provided `defaults`.
     2762                        /**
     2763                         * Create a model with the provided `defaults`.
     2764                         *
     2765                         * @member {Backbone.Model}
     2766                         */
    22012767                        this.model = new Backbone.Model( this.defaults );
    22022768
    22032769                        // If any of the `options` have a key from `defaults`, apply its
     
    22132779
    22142780                        this.model.on( 'change', this.render, this );
    22152781                },
    2216 
     2782                /**
     2783                 * @returns {wp.media.view.Button} Returns itself to allow chaining
     2784                 */
    22172785                render: function() {
    22182786                        var classes = [ 'button', this.className ],
    22192787                                model = this.model.toJSON();
    22202788
    2221                         if ( model.style )
     2789                        if ( model.style ) {
    22222790                                classes.push( 'button-' + model.style );
     2791                        }
    22232792
    2224                         if ( model.size )
     2793                        if ( model.size ) {
    22252794                                classes.push( 'button-' + model.size );
     2795                        }
    22262796
    22272797                        classes = _.uniq( classes.concat( this.options.classes ) );
    22282798                        this.el.className = classes.join(' ');
     
    22322802
    22332803                        return this;
    22342804                },
    2235 
     2805                /**
     2806                 * @param {Object} event
     2807                 */
    22362808                click: function( event ) {
    2237                         if ( '#' === this.attributes.href )
     2809                        if ( '#' === this.attributes.href ) {
    22382810                                event.preventDefault();
     2811                        }
    22392812
    2240                         if ( this.options.click && ! this.model.get('disabled') )
     2813                        if ( this.options.click && ! this.model.get('disabled') ) {
    22412814                                this.options.click.apply( this, arguments );
     2815                        }
    22422816                }
    22432817        });
    22442818
    22452819        /**
    22462820         * wp.media.view.ButtonGroup
     2821         *
     2822         * @constructor
     2823         * @augments wp.media.View
     2824         * @augments wp.Backbone.View
     2825         * @augments Backbone.View
    22472826         */
    22482827        media.view.ButtonGroup = media.View.extend({
    22492828                tagName:   'div',
    22502829                className: 'button-group button-large media-button-group',
    22512830
    22522831                initialize: function() {
     2832                        /**
     2833                         * @member {wp.media.view.Button[]}
     2834                         */
    22532835                        this.buttons = _.map( this.options.buttons || [], function( button ) {
    2254                                 if ( button instanceof Backbone.View )
     2836                                if ( button instanceof Backbone.View ) {
    22552837                                        return button;
    2256                                 else
     2838                                } else {
    22572839                                        return new media.view.Button( button ).render();
     2840                                }
    22582841                        });
    22592842
    22602843                        delete this.options.buttons;
    22612844
    2262                         if ( this.options.classes )
     2845                        if ( this.options.classes ) {
    22632846                                this.$el.addClass( this.options.classes );
     2847                        }
    22642848                },
    22652849
     2850                /**
     2851                 * @returns {wp.media.view.ButtonGroup}
     2852                 */
    22662853                render: function() {
    22672854                        this.$el.html( $( _.pluck( this.buttons, 'el' ) ).detach() );
    22682855                        return this;
     
    22712858
    22722859        /**
    22732860         * wp.media.view.PriorityList
     2861         *
     2862         * @constructor
     2863         * @augments wp.media.View
     2864         * @augments wp.Backbone.View
     2865         * @augments Backbone.View
    22742866         */
    2275 
    22762867        media.view.PriorityList = media.View.extend({
    22772868                tagName:   'div',
    22782869
     
    22822873                        this.set( _.extend( {}, this._views, this.options.views ), { silent: true });
    22832874                        delete this.options.views;
    22842875
    2285                         if ( ! this.options.silent )
     2876                        if ( ! this.options.silent ) {
    22862877                                this.render();
     2878                        }
    22872879                },
    2288 
     2880                /**
     2881                 * @param {string} id
     2882                 * @param {wp.media.View|Object} view
     2883                 * @param {Object} options
     2884                 * @returns {wp.media.view.PriorityList} Returns itself to allow chaining
     2885                 */
    22892886                set: function( id, view, options ) {
    22902887                        var priority, views, index;
    22912888
     
    22992896                                return this;
    23002897                        }
    23012898
    2302                         if ( ! (view instanceof Backbone.View) )
     2899                        if ( ! (view instanceof Backbone.View) ) {
    23032900                                view = this.toView( view, id, options );
    2304 
     2901                        }
    23052902                        view.controller = view.controller || this.controller;
    23062903
    23072904                        this.unset( id );
     
    23232920
    23242921                        return this;
    23252922                },
    2326 
     2923                /**
     2924                 * @param {string} id
     2925                 * @returns {wp.media.View}
     2926                 */
    23272927                get: function( id ) {
    23282928                        return this._views[ id ];
    23292929                },
    2330 
     2930                /**
     2931                 * @param {string} id
     2932                 * @returns {wp.media.view.PriorityList}
     2933                 */
    23312934                unset: function( id ) {
    23322935                        var view = this.get( id );
    23332936
    2334                         if ( view )
     2937                        if ( view ) {
    23352938                                view.remove();
     2939                        }
    23362940
    23372941                        delete this._views[ id ];
    23382942                        return this;
    23392943                },
    2340 
     2944                /**
     2945                 * @param {Object} options
     2946                 * @returns {wp.media.View}
     2947                 */
    23412948                toView: function( options ) {
    23422949                        return new media.View( options );
    23432950                }
     
    23452952
    23462953        /**
    23472954         * wp.media.view.MenuItem
     2955         *
     2956         * @constructor
     2957         * @augments wp.media.View
     2958         * @augments wp.Backbone.View
     2959         * @augments Backbone.View
    23482960         */
    23492961        media.view.MenuItem = media.View.extend({
    23502962                tagName:   'a',
     
    23572969                events: {
    23582970                        'click': '_click'
    23592971                },
    2360 
     2972                /**
     2973                 * @param {Object} event
     2974                 */
    23612975                _click: function( event ) {
    23622976                        var clickOverride = this.options.click;
    23632977
    2364                         if ( event )
     2978                        if ( event ) {
    23652979                                event.preventDefault();
     2980                        }
    23662981
    2367                         if ( clickOverride )
     2982                        if ( clickOverride ) {
    23682983                                clickOverride.call( this );
    2369                         else
     2984                        } else {
    23702985                                this.click();
     2986                        }
    23712987                },
    23722988
    23732989                click: function() {
    23742990                        var state = this.options.state;
    2375                         if ( state )
     2991                        if ( state ) {
    23762992                                this.controller.setState( state );
     2993                        }
    23772994                },
    2378 
     2995                /**
     2996                 * @returns {wp.media.view.MenuItem} returns itself to allow chaining
     2997                 */
    23792998                render: function() {
    23802999                        var options = this.options;
    23813000
    2382                         if ( options.text )
     3001                        if ( options.text ) {
    23833002                                this.$el.text( options.text );
    2384                         else if ( options.html )
     3003                        } else if ( options.html ) {
    23853004                                this.$el.html( options.html );
     3005                        }
    23863006
    23873007                        return this;
    23883008                }
     
    23903010
    23913011        /**
    23923012         * wp.media.view.Menu
     3013         *
     3014         * @constructor
     3015         * @augments wp.media.view.PriorityList
     3016         * @augments wp.media.View
     3017         * @augments wp.Backbone.View
     3018         * @augments Backbone.View
    23933019         */
    23943020        media.view.Menu = media.view.PriorityList.extend({
    23953021                tagName:   'div',
     
    23973023                property:  'state',
    23983024                ItemView:  media.view.MenuItem,
    23993025                region:    'menu',
    2400 
     3026                /**
     3027                 * @param {Object} options
     3028                 * @param {string} id
     3029                 * @returns {wp.media.View}
     3030                 */
    24013031                toView: function( options, id ) {
    24023032                        options = options || {};
    24033033                        options[ this.property ] = options[ this.property ] || id;
     
    24053035                },
    24063036
    24073037                ready: function() {
     3038                        /**
     3039                         * call 'ready' directly on the parent class
     3040                         */
    24083041                        media.view.PriorityList.prototype.ready.apply( this, arguments );
    24093042                        this.visibility();
    24103043                },
    24113044
    24123045                set: function() {
     3046                        /**
     3047                         * call 'set' directly on the parent class
     3048                         */
    24133049                        media.view.PriorityList.prototype.set.apply( this, arguments );
    24143050                        this.visibility();
    24153051                },
    24163052
    24173053                unset: function() {
     3054                        /**
     3055                         * call 'unset' directly on the parent class
     3056                         */
    24183057                        media.view.PriorityList.prototype.unset.apply( this, arguments );
    24193058                        this.visibility();
    24203059                },
     
    24253064                                views = this.views.get(),
    24263065                                hide = ! views || views.length < 2;
    24273066
    2428                         if ( this === view )
     3067                        if ( this === view ) {
    24293068                                this.controller.$el.toggleClass( 'hide-' + region, hide );
     3069                        }
    24303070                },
    2431 
     3071                /**
     3072                 * @param {string} id
     3073                 */
    24323074                select: function( id ) {
    24333075                        var view = this.get( id );
    24343076
    2435                         if ( ! view )
     3077                        if ( ! view ) {
    24363078                                return;
     3079                        }
    24373080
    24383081                        this.deselect();
    24393082                        view.$el.addClass('active');
     
    24463089
    24473090        /**
    24483091         * wp.media.view.RouterItem
     3092         *
     3093         * @constructor
     3094         * @augments wp.media.view.MenuItem
     3095         * @augments wp.media.View
     3096         * @augments wp.Backbone.View
     3097         * @augments Backbone.View
    24493098         */
    24503099        media.view.RouterItem = media.view.MenuItem.extend({
    24513100                click: function() {
    24523101                        var contentMode = this.options.contentMode;
    2453                         if ( contentMode )
     3102                        if ( contentMode ) {
    24543103                                this.controller.content.mode( contentMode );
     3104                        }
    24553105                }
    24563106        });
    24573107
    24583108        /**
    24593109         * wp.media.view.Router
     3110         *
     3111         * @constructor
     3112         * @augments wp.media.view.Menu
     3113         * @augments wp.media.view.PriorityList
     3114         * @augments wp.media.View
     3115         * @augments wp.Backbone.View
     3116         * @augments Backbone.View
    24603117         */
    24613118        media.view.Router = media.view.Menu.extend({
    24623119                tagName:   'div',
     
    24673124
    24683125                initialize: function() {
    24693126                        this.controller.on( 'content:render', this.update, this );
     3127                        /**
     3128                         * call 'initialize' directly on the parent class
     3129                         */
    24703130                        media.view.Menu.prototype.initialize.apply( this, arguments );
    24713131                },
    24723132
    24733133                update: function() {
    24743134                        var mode = this.controller.content.mode();
    2475                         if ( mode )
     3135                        if ( mode ) {
    24763136                                this.select( mode );
     3137                        }
    24773138                }
    24783139        });
    24793140
    2480 
    24813141        /**
    24823142         * wp.media.view.Sidebar
     3143         *
     3144         * @constructor
     3145         * @augments wp.media.view.PriorityList
     3146         * @augments wp.media.View
     3147         * @augments wp.Backbone.View
     3148         * @augments Backbone.View
    24833149         */
    24843150        media.view.Sidebar = media.view.PriorityList.extend({
    24853151                className: 'media-sidebar'
     
    24873153
    24883154        /**
    24893155         * wp.media.view.Attachment
     3156         *
     3157         * @constructor
     3158         * @augments wp.media.View
     3159         * @augments wp.Backbone.View
     3160         * @augments Backbone.View
    24903161         */
    24913162        media.view.Attachment = media.View.extend({
    24923163                tagName:   'li',
     
    25173188                        // Update the selection.
    25183189                        this.model.on( 'add', this.select, this );
    25193190                        this.model.on( 'remove', this.deselect, this );
    2520                         if ( selection )
     3191                        if ( selection ) {
    25213192                                selection.on( 'reset', this.updateSelect, this );
     3193                        }
    25223194
    25233195                        // Update the model's details view.
    25243196                        this.model.on( 'selection:single selection:unsingle', this.details, this );
    25253197                        this.details( this.model, this.controller.state().get('selection') );
    25263198                },
    2527 
     3199                /**
     3200                 * @returns {wp.media.view.Attachment} Returns itself to allow chaining
     3201                 */
    25283202                dispose: function() {
    25293203                        var selection = this.options.selection;
    25303204
    25313205                        // Make sure all settings are saved before removing the view.
    25323206                        this.updateAll();
    25333207
    2534                         if ( selection )
     3208                        if ( selection ) {
    25353209                                selection.off( null, null, this );
    2536 
     3210                        }
     3211                        /**
     3212                         * call 'dispose' directly on the parent class
     3213                         */
    25373214                        media.View.prototype.dispose.apply( this, arguments );
    25383215                        return this;
    25393216                },
    2540 
     3217                /**
     3218                 * @returns {wp.media.view.Attachment} Returns itself to allow chaining
     3219                 */
    25413220                render: function() {
    25423221                        var options = _.defaults( this.model.toJSON(), {
    25433222                                        orientation:   'landscape',
     
    25923271                },
    25933272
    25943273                progress: function() {
    2595                         if ( this.$bar && this.$bar.length )
     3274                        if ( this.$bar && this.$bar.length ) {
    25963275                                this.$bar.width( this.model.get('percent') + '%' );
     3276                        }
    25973277                },
    2598 
     3278                /**
     3279                 * @param {Object} event
     3280                 */
    25993281                toggleSelectionHandler: function( event ) {
    26003282                        var method;
    26013283
    2602                         if ( event.shiftKey )
     3284                        if ( event.shiftKey ) {
    26033285                                method = 'between';
    2604                         else if ( event.ctrlKey || event.metaKey )
     3286                        } else if ( event.ctrlKey || event.metaKey ) {
    26053287                                method = 'toggle';
     3288                        }
    26063289
    26073290                        this.toggleSelection({
    26083291                                method: method
    26093292                        });
    26103293                },
    2611 
     3294                /**
     3295                 * @param {Object} options
     3296                 */
    26123297                toggleSelection: function( options ) {
    26133298                        var collection = this.collection,
    26143299                                selection = this.options.selection,
     
    26163301                                method = options && options.method,
    26173302                                single, models, singleIndex, modelIndex;
    26183303
    2619                         if ( ! selection )
     3304                        if ( ! selection ) {
    26203305                                return;
     3306                        }
    26213307
    26223308                        single = selection.single();
    26233309                        method = _.isUndefined( method ) ? selection.multiple : method;
     
    26263312                        // exist between the current and the selected model.
    26273313                        if ( 'between' === method && single && selection.multiple ) {
    26283314                                // If the models are the same, short-circuit.
    2629                                 if ( single === model )
     3315                                if ( single === model ) {
    26303316                                        return;
     3317                                }
    26313318
    26323319                                singleIndex = collection.indexOf( single );
    26333320                                modelIndex  = collection.indexOf( this.model );
    26343321
    2635                                 if ( singleIndex < modelIndex )
     3322                                if ( singleIndex < modelIndex ) {
    26363323                                        models = collection.models.slice( singleIndex, modelIndex + 1 );
    2637                                 else
     3324                                } else {
    26383325                                        models = collection.models.slice( modelIndex, singleIndex + 1 );
     3326                                }
    26393327
    26403328                                selection.add( models ).single( model );
    26413329                                return;
     
    26473335                                return;
    26483336                        }
    26493337
    2650                         if ( method !== 'add' )
     3338                        if ( method !== 'add' ) {
    26513339                                method = 'reset';
     3340                        }
    26523341
    26533342                        if ( this.selected() ) {
    26543343                                // If the model is the single model, remove it.
     
    26663355                updateSelect: function() {
    26673356                        this[ this.selected() ? 'select' : 'deselect' ]();
    26683357                },
    2669 
     3358                /**
     3359                 * @returns {unresolved|Boolean}
     3360                 */
    26703361                selected: function() {
    26713362                        var selection = this.options.selection;
    2672                         if ( selection )
     3363                        if ( selection ) {
    26733364                                return !! selection.get( this.model.cid );
     3365                        }
    26743366                },
    2675 
     3367                /**
     3368                 * @param {Backbone.Model} model
     3369                 * @param {Backbone.Collection} collection
     3370                 */
    26763371                select: function( model, collection ) {
    26773372                        var selection = this.options.selection;
    26783373
    26793374                        // Check if a selection exists and if it's the collection provided.
    26803375                        // If they're not the same collection, bail; we're in another
    26813376                        // selection's event loop.
    2682                         if ( ! selection || ( collection && collection !== selection ) )
     3377                        if ( ! selection || ( collection && collection !== selection ) ) {
    26833378                                return;
     3379                        }
    26843380
    26853381                        this.$el.addClass('selected');
    26863382                },
    2687 
     3383                /**
     3384                 * @param {Backbone.Model} model
     3385                 * @param {Backbone.Collection} collection
     3386                 */
    26883387                deselect: function( model, collection ) {
    26893388                        var selection = this.options.selection;
    26903389
    26913390                        // Check if a selection exists and if it's the collection provided.
    26923391                        // If they're not the same collection, bail; we're in another
    26933392                        // selection's event loop.
    2694                         if ( ! selection || ( collection && collection !== selection ) )
     3393                        if ( ! selection || ( collection && collection !== selection ) ) {
    26953394                                return;
    2696 
     3395                        }
    26973396                        this.$el.removeClass('selected');
    26983397                },
    2699 
     3398                /**
     3399                 * @param {Backbone.Model} model
     3400                 * @param {Backbone.Collection} collection
     3401                 */
    27003402                details: function( model, collection ) {
    27013403                        var selection = this.options.selection,
    27023404                                details;
    27033405
    2704                         if ( selection !== collection )
     3406                        if ( selection !== collection ) {
    27053407                                return;
     3408                        }
    27063409
    27073410                        details = selection.single();
    27083411                        this.$el.toggleClass( 'details', details === this.model );
    27093412                },
    2710 
     3413                /**
     3414                 * @param {Object} event
     3415                 */
    27113416                preventDefault: function( event ) {
    27123417                        event.preventDefault();
    27133418                },
    2714 
     3419                /**
     3420                 * @param {string} size
     3421                 * @returns {Object}
     3422                 */
    27153423                imageSize: function( size ) {
    27163424                        var sizes = this.model.get('sizes');
    27173425
     
    27293437                                };
    27303438                        }
    27313439                },
    2732 
     3440                /**
     3441                 * @param {Object} event
     3442                 */
    27333443                updateSetting: function( event ) {
    27343444                        var $setting = $( event.target ).closest('[data-setting]'),
    27353445                                setting, value;
    27363446
    2737                         if ( ! $setting.length )
     3447                        if ( ! $setting.length ) {
    27383448                                return;
     3449                        }
    27393450
    27403451                        setting = $setting.data('setting');
    27413452                        value   = event.target.value;
    27423453
    2743                         if ( this.model.get( setting ) !== value )
     3454                        if ( this.model.get( setting ) !== value ) {
    27443455                                this.save( setting, value );
     3456                        }
    27453457                },
    27463458
    2747                 // Pass all the arguments to the model's save method.
    2748                 //
    2749                 // Records the aggregate status of all save requests and updates the
    2750                 // view's classes accordingly.
     3459                /**
     3460                 * Pass all the arguments to the model's save method.
     3461                 *
     3462                 * Records the aggregate status of all save requests and updates the
     3463                 * view's classes accordingly.
     3464                 */
    27513465                save: function() {
    27523466                        var view = this,
    27533467                                save = this._save = this._save || { status: 'ready' },
     
    27553469                                requests = save.requests ? $.when( request, save.requests ) : request;
    27563470
    27573471                        // If we're waiting to remove 'Saved.', stop.
    2758                         if ( save.savedTimer )
     3472                        if ( save.savedTimer ) {
    27593473                                clearTimeout( save.savedTimer );
     3474                        }
    27603475
    27613476                        this.updateSave('waiting');
    27623477                        save.requests = requests;
    27633478                        requests.always( function() {
    27643479                                // If we've performed another request since this one, bail.
    2765                                 if ( save.requests !== requests )
     3480                                if ( save.requests !== requests ) {
    27663481                                        return;
     3482                                }
    27673483
    27683484                                view.updateSave( requests.state() === 'resolved' ? 'complete' : 'error' );
    27693485                                save.savedTimer = setTimeout( function() {
     
    27713487                                        delete save.savedTimer;
    27723488                                }, 2000 );
    27733489                        });
    2774 
    27753490                },
    2776 
     3491                /**
     3492                 * @param {string} status
     3493                 * @returns {wp.media.view.Attachment} Returns itself to allow chaining
     3494                 */
    27773495                updateSave: function( status ) {
    27783496                        var save = this._save = this._save || { status: 'ready' };
    27793497
     
    27953513                                var $input = $('input, textarea, select, [value]', el ),
    27963514                                        setting, value;
    27973515
    2798                                 if ( ! $input.length )
     3516                                if ( ! $input.length ) {
    27993517                                        return;
     3518                                }
    28003519
    28013520                                setting = $(el).data('setting');
    28023521                                value = $input.val();
    28033522
    28043523                                // Record the value if it changed.
    2805                                 if ( model.get( setting ) !== value )
     3524                                if ( model.get( setting ) !== value ) {
    28063525                                        return [ setting, value ];
     3526                                }
    28073527                        }).compact().object().value();
    28083528
    2809                         if ( ! _.isEmpty( changed ) )
     3529                        if ( ! _.isEmpty( changed ) ) {
    28103530                                model.save( changed );
     3531                        }
    28113532                },
    2812 
     3533                /**
     3534                 * @param {Object} event
     3535                 */
    28133536                removeFromLibrary: function( event ) {
    28143537                        // Stop propagation so the model isn't selected.
    28153538                        event.stopPropagation();
    28163539
    28173540                        this.collection.remove( this.model );
    28183541                },
    2819 
     3542                /**
     3543                 * @param {Object} event
     3544                 */
    28203545                removeFromSelection: function( event ) {
    28213546                        var selection = this.options.selection;
    2822                         if ( ! selection )
     3547                        if ( ! selection ) {
    28233548                                return;
     3549                        }
    28243550
    28253551                        // Stop propagation so the model isn't selected.
    28263552                        event.stopPropagation();
     
    28343560                caption: '_syncCaption',
    28353561                title:   '_syncTitle'
    28363562        }, function( method, setting ) {
     3563                /**
     3564                 * @param {Backbone.Model} model
     3565                 * @param {string} value
     3566                 * @returns {wp.media.view.Attachment} Returns itself to allow chaining
     3567                 */
    28373568                media.view.Attachment.prototype[ method ] = function( model, value ) {
    28383569                        var $setting = this.$('[data-setting="' + setting + '"]');
    28393570
    2840                         if ( ! $setting.length )
     3571                        if ( ! $setting.length ) {
    28413572                                return this;
     3573                        }
    28423574
    28433575                        // If the updated value is in sync with the value in the DOM, there
    28443576                        // is no need to re-render. If we're currently editing the value,
    28453577                        // it will automatically be in sync, suppressing the re-render for
    28463578                        // the view we're editing, while updating any others.
    2847                         if ( value === $setting.find('input, textarea, select, [value]').val() )
     3579                        if ( value === $setting.find('input, textarea, select, [value]').val() ) {
    28483580                                return this;
     3581                        }
    28493582
    28503583                        return this.render();
    28513584                };
     
    28533586
    28543587        /**
    28553588         * wp.media.view.Attachment.Library
     3589         *
     3590         * @constructor
     3591         * @augments wp.media.view.Attachment
     3592         * @augments wp.media.View
     3593         * @augments wp.Backbone.View
     3594         * @augments Backbone.View
    28563595         */
    28573596        media.view.Attachment.Library = media.view.Attachment.extend({
    28583597                buttons: {
     
    28623601
    28633602        /**
    28643603         * wp.media.view.Attachment.EditLibrary
     3604         *
     3605         * @constructor
     3606         * @augments wp.media.view.Attachment
     3607         * @augments wp.media.View
     3608         * @augments wp.Backbone.View
     3609         * @augments Backbone.View
    28653610         */
    28663611        media.view.Attachment.EditLibrary = media.view.Attachment.extend({
    28673612                buttons: {
     
    28713616
    28723617        /**
    28733618         * wp.media.view.Attachments
     3619         *
     3620         * @constructor
     3621         * @augments wp.media.View
     3622         * @augments wp.Backbone.View
     3623         * @augments Backbone.View
    28743624         */
    28753625        media.view.Attachments = media.View.extend({
    28763626                tagName:   'ul',
     
    29053655                                var view = this._viewsByCid[ attachment.cid ];
    29063656                                delete this._viewsByCid[ attachment.cid ];
    29073657
    2908                                 if ( view )
     3658                                if ( view ) {
    29093659                                        view.remove();
     3660                                }
    29103661                        }, this );
    29113662
    29123663                        this.collection.on( 'reset', this.render, this );
     
    29193670                        _.bindAll( this, 'css' );
    29203671                        this.model.on( 'change:edge change:gutter', this.css, this );
    29213672                        this._resizeCss = _.debounce( _.bind( this.css, this ), this.refreshSensitivity );
    2922                         if ( this.options.resize )
     3673                        if ( this.options.resize ) {
    29233674                                $(window).on( 'resize.attachments', this._resizeCss );
     3675                        }
    29243676                        this.css();
    29253677                },
    29263678
    29273679                dispose: function() {
    29283680                        this.collection.props.off( null, null, this );
    29293681                        $(window).off( 'resize.attachments', this._resizeCss );
     3682                        /**
     3683                         * call 'dispose' directly on the parent class
     3684                         */
    29303685                        media.View.prototype.dispose.apply( this, arguments );
    29313686                },
    29323687
    29333688                css: function() {
    29343689                        var $css = $( '#' + this.el.id + '-css' );
    29353690
    2936                         if ( $css.length )
     3691                        if ( $css.length ) {
    29373692                                $css.remove();
     3693                        }
    29383694
    29393695                        media.view.Attachments.$head().append( this.cssTemplate({
    29403696                                id:     this.el.id,
     
    29423698                                gutter: this.model.get('gutter')
    29433699                        }) );
    29443700                },
    2945 
     3701                /**
     3702                 * @returns {Number}
     3703                 */
    29463704                edge: function() {
    29473705                        var edge = this.model.get('edge'),
    29483706                                gutter, width, columns;
    29493707
    2950                         if ( ! this.$el.is(':visible') )
     3708                        if ( ! this.$el.is(':visible') ) {
    29513709                                return edge;
     3710                        }
    29523711
    29533712                        gutter  = this.model.get('gutter') * 2;
    29543713                        width   = this.$el.width() - gutter;
     
    29603719                initSortable: function() {
    29613720                        var collection = this.collection;
    29623721
    2963                         if ( ! this.options.sortable || ! $.fn.sortable )
     3722                        if ( ! this.options.sortable || ! $.fn.sortable ) {
    29643723                                return;
     3724                        }
    29653725
    29663726                        this.$el.sortable( _.extend({
    29673727                                // If the `collection` has a `comparator`, disable sorting.
     
    30323792                        this.$el.sortable( 'option', 'disabled', ! enabled );
    30333793                },
    30343794
     3795                /**
     3796                 * @param {wp.media.model.Attachment} attachment
     3797                 * @returns {wp.media.View}
     3798                 */
    30353799                createAttachmentView: function( attachment ) {
    30363800                        var view = new this.options.AttachmentView({
    30373801                                controller: this.controller,
     
    30643828
    30653829                scroll: function() {
    30663830                        // @todo: is this still necessary?
    3067                         if ( ! this.$el.is(':visible') )
     3831                        if ( ! this.$el.is(':visible') ) {
    30683832                                return;
     3833                        }
    30693834
    30703835                        if ( this.collection.hasMore() && this.el.scrollHeight < this.el.scrollTop + ( this.el.clientHeight * this.options.refreshThreshold ) ) {
    30713836                                this.collection.more().done( this.scroll );
     
    30823847
    30833848        /**
    30843849         * wp.media.view.Search
     3850         *
     3851         * @constructor
     3852         * @augments wp.media.View
     3853         * @augments wp.Backbone.View
     3854         * @augments Backbone.View
    30853855         */
    30863856        media.view.Search = media.View.extend({
    30873857                tagName:   'input',
     
    30993869                        'search': 'search'
    31003870                },
    31013871
     3872                /**
     3873                 * @returns {wp.media.view.Search} Returns itself to allow chaining
     3874                 */
    31023875                render: function() {
    31033876                        this.el.value = this.model.escape('search');
    31043877                        return this;
    31053878                },
    31063879
    31073880                search: function( event ) {
    3108                         if ( event.target.value )
     3881                        if ( event.target.value ) {
    31093882                                this.model.set( 'search', event.target.value );
    3110                         else
     3883                        } else {
    31113884                                this.model.unset('search');
     3885                        }
    31123886                }
    31133887        });
    31143888
    31153889        /**
    31163890         * wp.media.view.AttachmentFilters
     3891         *
     3892         * @constructor
     3893         * @augments wp.media.View
     3894         * @augments wp.Backbone.View
     3895         * @augments Backbone.View
    31173896         */
    31183897        media.view.AttachmentFilters = media.View.extend({
    31193898                tagName:   'select',
     
    31483927                change: function() {
    31493928                        var filter = this.filters[ this.el.value ];
    31503929
    3151                         if ( filter )
     3930                        if ( filter ) {
    31523931                                this.model.set( filter.props );
     3932                        }
    31533933                },
    31543934
    31553935                select: function() {
     
    31623942                                        return prop === ( _.isUndefined( props[ key ] ) ? null : props[ key ] );
    31633943                                });
    31643944
    3165                                 if ( equal )
     3945                                if ( equal ) {
    31663946                                        return value = id;
     3947                                }
    31673948                        });
    31683949
    31693950                        this.$el.val( value );
    31703951                }
    31713952        });
    31723953
     3954        /**
     3955         * wp.media.view.AttachmentFilters.Uploaded
     3956         *
     3957         * @constructor
     3958         * @augments wp.media.view.AttachmentFilters
     3959         * @augments wp.media.View
     3960         * @augments wp.Backbone.View
     3961         * @augments Backbone.View
     3962         */
    31733963        media.view.AttachmentFilters.Uploaded = media.view.AttachmentFilters.extend({
    31743964                createFilters: function() {
    31753965                        var type = this.model.get('type'),
    31763966                                types = media.view.settings.mimeTypes,
    31773967                                text;
    31783968
    3179                         if ( types && type )
     3969                        if ( types && type ) {
    31803970                                text = types[ type ];
     3971                        }
    31813972
    31823973                        this.filters = {
    31833974                                all: {
     
    32033994                }
    32043995        });
    32053996
     3997        /**
     3998         * wp.media.view.AttachmentFilters.All
     3999         *
     4000         * @constructor
     4001         * @augments wp.media.view.AttachmentFilters
     4002         * @augments wp.media.View
     4003         * @augments wp.Backbone.View
     4004         * @augments Backbone.View
     4005         */
    32064006        media.view.AttachmentFilters.All = media.view.AttachmentFilters.extend({
    32074007                createFilters: function() {
    32084008                        var filters = {};
     
    32464046        });
    32474047
    32484048
    3249 
    32504049        /**
    32514050         * wp.media.view.AttachmentsBrowser
     4051         *
     4052         * @constructor
     4053         * @augments wp.media.View
     4054         * @augments wp.Backbone.View
     4055         * @augments Backbone.View
    32524056         */
    32534057        media.view.AttachmentsBrowser = media.View.extend({
    32544058                tagName:   'div',
     
    32694073
    32704074                        this.collection.on( 'add remove reset', this.updateContent, this );
    32714075                },
    3272 
     4076                /**
     4077                 * @returns {wp.media.view.AttachmentsBrowser} Returns itself to allow chaining
     4078                 */
    32734079                dispose: function() {
    32744080                        this.options.selection.off( null, null, this );
    32754081                        media.View.prototype.dispose.apply( this, arguments );
     
    32794085                createToolbar: function() {
    32804086                        var filters, FiltersConstructor;
    32814087
     4088                        /**
     4089                         * @member {wp.media.view.Toolbar}
     4090                         */
    32824091                        this.toolbar = new media.view.Toolbar({
    32834092                                controller: this.controller
    32844093                        });
     
    32864095                        this.views.add( this.toolbar );
    32874096
    32884097                        filters = this.options.filters;
    3289                         if ( 'uploaded' === filters )
     4098                        if ( 'uploaded' === filters ) {
    32904099                                FiltersConstructor = media.view.AttachmentFilters.Uploaded;
    3291                         else if ( 'all' === filters )
     4100                        } else if ( 'all' === filters ) {
    32924101                                FiltersConstructor = media.view.AttachmentFilters.All;
     4102                        }
    32934103
    32944104                        if ( FiltersConstructor ) {
    32954105                                this.toolbar.set( 'filters', new FiltersConstructor({
     
    33184128                updateContent: function() {
    33194129                        var view = this;
    33204130
    3321                         if( ! this.attachments )
     4131                        if( ! this.attachments ) {
    33224132                                this.createAttachments();
     4133                        }
    33234134
    33244135                        if ( ! this.collection.length ) {
    33254136                                this.collection.more().done( function() {
     
    33864197                        selection.on( 'selection:single', this.createSingle, this );
    33874198                        selection.on( 'selection:unsingle', this.disposeSingle, this );
    33884199
    3389                         if ( selection.single() )
     4200                        if ( selection.single() ) {
    33904201                                this.createSingle();
     4202                        }
    33914203                },
    33924204
    33934205                createSingle: function() {
     
    34274239
    34284240        /**
    34294241         * wp.media.view.Selection
     4242         *
     4243         * @constructor
     4244         * @augments wp.media.View
     4245         * @augments wp.Backbone.View
     4246         * @augments Backbone.View
    34304247         */
    34314248        media.view.Selection = media.View.extend({
    34324249                tagName:   'div',
     
    34444261                                clearable: true
    34454262                        });
    34464263
     4264                        /**
     4265                         * @member {wp.media.view.Attachments.Selection}
     4266                         */
    34474267                        this.attachments = new media.view.Attachments.Selection({
    34484268                                controller: this.controller,
    34494269                                collection: this.collection,
     
    34654285
    34664286                refresh: function() {
    34674287                        // If the selection hasn't been rendered, bail.
    3468                         if ( ! this.$el.children().length )
     4288                        if ( ! this.$el.children().length ) {
    34694289                                return;
     4290                        }
    34704291
    34714292                        var collection = this.collection,
    34724293                                editing = 'edit-selection' === this.controller.content.mode();
     
    34814302
    34824303                edit: function( event ) {
    34834304                        event.preventDefault();
    3484                         if ( this.options.editable )
     4305                        if ( this.options.editable ) {
    34854306                                this.options.editable.call( this, this.collection );
     4307                        }
    34864308                },
    34874309
    34884310                clear: function( event ) {
     
    34944316
    34954317        /**
    34964318         * wp.media.view.Attachment.Selection
     4319         *
     4320         * @constructor
     4321         * @augments wp.media.view.Attachment
     4322         * @augments wp.media.View
     4323         * @augments wp.Backbone.View
     4324         * @augments Backbone.View
    34974325         */
    34984326        media.view.Attachment.Selection = media.view.Attachment.extend({
    34994327                className: 'attachment selection',
     
    35074335
    35084336        /**
    35094337         * wp.media.view.Attachments.Selection
     4338         *
     4339         * @constructor
     4340         * @augments wp.media.view.Attachments
     4341         * @augments wp.media.View
     4342         * @augments wp.Backbone.View
     4343         * @augments Backbone.View
    35104344         */
    35114345        media.view.Attachments.Selection = media.view.Attachments.extend({
    35124346                events: {},
     
    35184352                                // The single `Attachment` view to be used in the `Attachments` view.
    35194353                                AttachmentView: media.view.Attachment.Selection
    35204354                        });
     4355                        /**
     4356                         * call 'initialize' directly on the parent class
     4357                         */
    35214358                        return media.view.Attachments.prototype.initialize.apply( this, arguments );
    35224359                }
    35234360        });
    35244361
    35254362        /**
    35264363         * wp.media.view.Attachments.EditSelection
     4364         *
     4365         * @constructor
     4366         * @augments wp.media.view.Attachment.Selection
     4367         * @augments wp.media.view.Attachment
     4368         * @augments wp.media.View
     4369         * @augments wp.Backbone.View
     4370         * @augments Backbone.View
    35274371         */
    35284372        media.view.Attachment.EditSelection = media.view.Attachment.Selection.extend({
    35294373                buttons: {
     
    35344378
    35354379        /**
    35364380         * wp.media.view.Settings
     4381         *
     4382         * @constructor
     4383         * @augments wp.media.View
     4384         * @augments wp.Backbone.View
     4385         * @augments Backbone.View
    35374386         */
    35384387        media.view.Settings = media.View.extend({
    35394388                events: {
     
    35534402                                model: this.model.toJSON()
    35544403                        }, this.options );
    35554404                },
    3556 
     4405                /**
     4406                 * @returns {wp.media.view.Setings} Returns itself to allow chaining
     4407                 */
    35574408                render: function() {
    35584409                        media.View.prototype.render.apply( this, arguments );
    35594410                        // Select the correct values.
    35604411                        _( this.model.attributes ).chain().keys().each( this.update, this );
    35614412                        return this;
    35624413                },
    3563 
     4414                /**
     4415                 * @param {string} key
     4416                 */
    35644417                update: function( key ) {
    35654418                        var value = this.model.get( key ),
    35664419                                $setting = this.$('[data-setting="' + key + '"]'),
    35674420                                $buttons, $value;
    35684421
    35694422                        // Bail if we didn't find a matching setting.
    3570                         if ( ! $setting.length )
     4423                        if ( ! $setting.length ) {
    35714424                                return;
     4425                        }
    35724426
    35734427                        // Attempt to determine how the setting is rendered and update
    35744428                        // the selected value.
     
    35854439                                        this.model.set( key, $setting.find(':selected').val() );
    35864440                                }
    35874441
    3588 
    35894442                        // Handle button groups.
    35904443                        } else if ( $setting.hasClass('button-group') ) {
    35914444                                $buttons = $setting.find('button').removeClass('active');
     
    35934446
    35944447                        // Handle text inputs and textareas.
    35954448                        } else if ( $setting.is('input[type="text"], textarea') ) {
    3596                                 if ( ! $setting.is(':focus') )
     4449                                if ( ! $setting.is(':focus') ) {
    35974450                                        $setting.val( value );
    3598 
     4451                                }
    35994452                        // Handle checkboxes.
    36004453                        } else if ( $setting.is('input[type="checkbox"]') ) {
    36014454                                $setting.attr( 'checked', !! value );
    36024455                        }
    36034456                },
    3604 
     4457                /**
     4458                 * @param {Object} event
     4459                 */
    36054460                updateHandler: function( event ) {
    36064461                        var $setting = $( event.target ).closest('[data-setting]'),
    36074462                                value = event.target.value,
     
    36094464
    36104465                        event.preventDefault();
    36114466
    3612                         if ( ! $setting.length )
     4467                        if ( ! $setting.length ) {
    36134468                                return;
     4469                        }
    36144470
    36154471                        // Use the correct value for checkboxes.
    3616                         if ( $setting.is('input[type="checkbox"]') )
     4472                        if ( $setting.is('input[type="checkbox"]') ) {
    36174473                                value = $setting[0].checked;
     4474                        }
    36184475
    36194476                        // Update the corresponding setting.
    36204477                        this.model.set( $setting.data('setting'), value );
    36214478
    36224479                        // If the setting has a corresponding user setting,
    36234480                        // update that as well.
    3624                         if ( userSetting = $setting.data('userSetting') )
     4481                        if ( userSetting = $setting.data('userSetting') ) {
    36254482                                setUserSetting( userSetting, value );
     4483                        }
    36264484                },
    36274485
    36284486                updateChanges: function( model ) {
    3629                         if ( model.hasChanged() )
     4487                        if ( model.hasChanged() ) {
    36304488                                _( model.changed ).chain().keys().each( this.update, this );
     4489                        }
    36314490                }
    36324491        });
    36334492
    36344493        /**
    36354494         * wp.media.view.Settings.AttachmentDisplay
     4495         *
     4496         * @constructor
     4497         * @augments wp.media.view.Settings
     4498         * @augments wp.media.View
     4499         * @augments wp.Backbone.View
     4500         * @augments Backbone.View
    36364501         */
    36374502        media.view.Settings.AttachmentDisplay = media.view.Settings.extend({
    36384503                className: 'attachment-display-settings',
     
    36444509                        _.defaults( this.options, {
    36454510                                userSettings: false
    36464511                        });
    3647 
     4512                        /**
     4513                         * call 'initialize' directly on the parent class
     4514                         */
    36484515                        media.view.Settings.prototype.initialize.apply( this, arguments );
    36494516                        this.model.on( 'change:link', this.updateLinkTo, this );
    36504517
    3651                         if ( attachment )
     4518                        if ( attachment ) {
    36524519                                attachment.on( 'change:uploading', this.render, this );
     4520                        }
    36534521                },
    36544522
    36554523                dispose: function() {
    36564524                        var attachment = this.options.attachment;
    3657                         if ( attachment )
     4525                        if ( attachment ) {
    36584526                                attachment.off( null, null, this );
    3659 
     4527                        }
     4528                        /**
     4529                         * call 'dispose' directly on the parent class
     4530                         */
    36604531                        media.view.Settings.prototype.dispose.apply( this, arguments );
    36614532                },
    3662 
     4533                /**
     4534                 * @returns {wp.media.view.AttachmentDisplay} Returns itself to allow chaining
     4535                 */
    36634536                render: function() {
    36644537                        var attachment = this.options.attachment;
    36654538                        if ( attachment ) {
     
    36684541                                        type:  attachment.get('type')
    36694542                                });
    36704543                        }
    3671 
     4544                        /**
     4545                         * call 'render' directly on the parent class
     4546                         */
    36724547                        media.view.Settings.prototype.render.call( this );
    36734548                        this.updateLinkTo();
    36744549                        return this;
     
    36994574                        $input.show();
    37004575
    37014576                        // If the input is visible, focus and select its contents.
    3702                         if ( $input.is(':visible') )
     4577                        if ( $input.is(':visible') ) {
    37034578                                $input.focus()[0].select();
     4579                        }
    37044580                }
    37054581        });
    37064582
    37074583        /**
    37084584         * wp.media.view.Settings.Gallery
     4585         *
     4586         * @constructor
     4587         * @augments wp.media.view.Settings
     4588         * @augments wp.media.View
     4589         * @augments wp.Backbone.View
     4590         * @augments Backbone.View
    37094591         */
    37104592        media.view.Settings.Gallery = media.view.Settings.extend({
    37114593                className: 'gallery-settings',
     
    37144596
    37154597        /**
    37164598         * wp.media.view.Attachment.Details
     4599         *
     4600         * @constructor
     4601         * @augments wp.media.view.Attachment
     4602         * @augments wp.media.View
     4603         * @augments wp.Backbone.View
     4604         * @augments Backbone.View
    37174605         */
    37184606        media.view.Attachment.Details = media.view.Attachment.extend({
    37194607                tagName:   'div',
     
    37314619                },
    37324620
    37334621                initialize: function() {
     4622                        /**
     4623                         * @member {wp.media.view.FocusManager}
     4624                         */
    37344625                        this.focusManager = new media.view.FocusManager({
    37354626                                el: this.el
    37364627                        });
    3737 
     4628                        /**
     4629                         * call 'initialize' directly on the parent class
     4630                         */
    37384631                        media.view.Attachment.prototype.initialize.apply( this, arguments );
    37394632                },
    3740 
     4633                /**
     4634                 * @returns {wp.media.view..Attachment.Details} Returns itself to allow chaining
     4635                 */
    37414636                render: function() {
     4637                        /**
     4638                         * call 'render' directly on the parent class
     4639                         */
    37424640                        media.view.Attachment.prototype.render.apply( this, arguments );
    37434641                        this.focusManager.focus();
    37444642                        return this;
    37454643                },
    3746 
     4644                /**
     4645                 * @param {Object} event
     4646                 */
    37474647                deleteAttachment: function( event ) {
    37484648                        event.preventDefault();
    37494649
    3750                         if ( confirm( l10n.warnDelete ) )
     4650                        if ( confirm( l10n.warnDelete ) ) {
    37514651                                this.model.destroy();
     4652                        }
    37524653                },
    37534654
    37544655                editAttachment: function() {
    37554656                        this.$el.addClass('needs-refresh');
    37564657                },
    3757 
     4658                /**
     4659                 * @param {Object} event
     4660                 */
    37584661                refreshAttachment: function( event ) {
    37594662                        this.$el.removeClass('needs-refresh');
    37604663                        event.preventDefault();
     
    37644667
    37654668        /**
    37664669         * wp.media.view.AttachmentCompat
     4670         *
     4671         * @constructor
     4672         * @augments wp.media.View
     4673         * @augments wp.Backbone.View
     4674         * @augments Backbone.View
    37674675         */
    37684676        media.view.AttachmentCompat = media.View.extend({
    37694677                tagName:   'form',
     
    37774685                },
    37784686
    37794687                initialize: function() {
     4688                        /**
     4689                         * @member {wp.media.view.FocusManager}
     4690                         */
    37804691                        this.focusManager = new media.view.FocusManager({
    37814692                                el: this.el
    37824693                        });
    37834694
    37844695                        this.model.on( 'change:compat', this.render, this );
    37854696                },
    3786 
     4697                /**
     4698                 * @returns {wp.media.view.AttachmentCompat} Returns itself to allow chaining
     4699                 */
    37874700                dispose: function() {
    3788                         if ( this.$(':focus').length )
     4701                        if ( this.$(':focus').length ) {
    37894702                                this.save();
    3790 
     4703                        }
     4704                        /**
     4705                         * call 'dispose' directly on the parent class
     4706                         */
    37914707                        return media.View.prototype.dispose.apply( this, arguments );
    37924708                },
    3793 
     4709                /**
     4710                 * @returns {wp.media.view.AttachmentCompat} Returns itself to allow chaining
     4711                 */
    37944712                render: function() {
    37954713                        var compat = this.model.get('compat');
    3796                         if ( ! compat || ! compat.item )
     4714                        if ( ! compat || ! compat.item ) {
    37974715                                return;
     4716                        }
    37984717
    37994718                        this.views.detach();
    38004719                        this.$el.html( compat.item );
     
    38034722                        this.focusManager.focus();
    38044723                        return this;
    38054724                },
    3806 
     4725                /**
     4726                 * @param {Object} event
     4727                 */
    38074728                preventDefault: function( event ) {
    38084729                        event.preventDefault();
    38094730                },
    3810 
     4731                /**
     4732                 * @param {Object} event
     4733                 */
    38114734                save: function( event ) {
    38124735                        var data = {};
    38134736
    3814                         if ( event )
     4737                        if ( event ) {
    38154738                                event.preventDefault();
     4739                        }
    38164740
    38174741                        _.each( this.$el.serializeArray(), function( pair ) {
    38184742                                data[ pair.name ] = pair.value;
     
    38244748
    38254749        /**
    38264750         * wp.media.view.Iframe
     4751         *
     4752         * @constructor
     4753         * @augments wp.media.View
     4754         * @augments wp.Backbone.View
     4755         * @augments Backbone.View
    38274756         */
    38284757        media.view.Iframe = media.View.extend({
    38294758                className: 'media-iframe',
    3830 
     4759                /**
     4760                 * @returns {wp.media.view.Iframe} Returns itself to allow chaining
     4761                 */
    38314762                render: function() {
    38324763                        this.views.detach();
    38334764                        this.$el.html( '<iframe src="' + this.controller.state().get('src') + '" />' );
     
    38384769
    38394770        /**
    38404771         * wp.media.view.Embed
     4772         *
     4773         * @constructor
     4774         * @augments wp.media.View
     4775         * @augments wp.Backbone.View
     4776         * @augments Backbone.View
    38414777         */
    38424778        media.view.Embed = media.View.extend({
    38434779                className: 'media-embed',
    38444780
    38454781                initialize: function() {
     4782                        /**
     4783                         * @member {wp.media.view.EmbedUrl}
     4784                         */
    38464785                        this.url = new media.view.EmbedUrl({
    38474786                                controller: this.controller,
    38484787                                model:      this.model.props
     
    38544793                        this.model.on( 'change:loading', this.loading, this );
    38554794                },
    38564795
     4796                /**
     4797                 * @param {Object} view
     4798                 */
    38574799                settings: function( view ) {
    3858                         if ( this._settings )
     4800                        if ( this._settings ) {
    38594801                                this._settings.remove();
     4802                        }
    38604803                        this._settings = view;
    38614804                        this.views.add( view );
    38624805                },
     
    38654808                        var type = this.model.get('type'),
    38664809                                constructor;
    38674810
    3868                         if ( 'image' === type )
     4811                        if ( 'image' === type ) {
    38694812                                constructor = media.view.EmbedImage;
    3870                         else if ( 'link' === type )
     4813                        } else if ( 'link' === type ) {
    38714814                                constructor = media.view.EmbedLink;
    3872                         else
     4815                        } else {
    38734816                                return;
     4817                        }
    38744818
    38754819                        this.settings( new constructor({
    38764820                                controller: this.controller,
     
    38864830
    38874831        /**
    38884832         * wp.media.view.EmbedUrl
     4833         *
     4834         * @constructor
     4835         * @augments wp.media.View
     4836         * @augments wp.Backbone.View
     4837         * @augments Backbone.View
    38894838         */
    38904839        media.view.EmbedUrl = media.View.extend({
    38914840                tagName:   'label',
     
    39064855
    39074856                        this.model.on( 'change:url', this.render, this );
    39084857                },
    3909 
     4858                /**
     4859                 * @returns {wp.media.view.EmbedUrl} Returns itself to allow chaining
     4860                 */
    39104861                render: function() {
    39114862                        var $input = this.$input;
    39124863
    3913                         if ( $input.is(':focus') )
     4864                        if ( $input.is(':focus') ) {
    39144865                                return;
     4866                        }
    39154867
    39164868                        this.input.value = this.model.get('url') || 'http://';
     4869                        /**
     4870                         * Call `render` directly on parent class with passed arguments
     4871                         */
    39174872                        media.View.prototype.render.apply( this, arguments );
    39184873                        return this;
    39194874                },
     
    39264881                        this.model.set( 'url', event.target.value );
    39274882                },
    39284883
     4884                /**
     4885                 * If the input is visible, focus and select its contents.
     4886                 */
    39294887                focus: function() {
    39304888                        var $input = this.$input;
    3931                         // If the input is visible, focus and select its contents.
    3932                         if ( $input.is(':visible') )
     4889                        if ( $input.is(':visible') ) {
    39334890                                $input.focus()[0].select();
     4891                        }
    39344892                }
    39354893        });
    39364894
    39374895        /**
    39384896         * wp.media.view.EmbedLink
     4897         *
     4898         * @constructor
     4899         * @augments wp.media.view.Settings
     4900         * @augments wp.media.View
     4901         * @augments wp.Backbone.View
     4902         * @augments Backbone.View
    39394903         */
    39404904        media.view.EmbedLink = media.view.Settings.extend({
    39414905                className: 'embed-link-settings',
     
    39444908
    39454909        /**
    39464910         * wp.media.view.EmbedImage
     4911         *
     4912         * @contructor
     4913         * @augments wp.media.view.Settings.AttachmentDisplay
     4914         * @augments wp.media.view.Settings
     4915         * @augments wp.media.View
     4916         * @augments wp.Backbone.View
     4917         * @augments Backbone.View
    39474918         */
    39484919        media.view.EmbedImage =  media.view.Settings.AttachmentDisplay.extend({
    39494920                className: 'embed-image-settings',
    39504921                template:  media.template('embed-image-settings'),
    39514922
    39524923                initialize: function() {
     4924                        /**
     4925                         * Call `initialize` directly on parent class with passed arguments
     4926                         */
    39534927                        media.view.Settings.AttachmentDisplay.prototype.initialize.apply( this, arguments );
    39544928                        this.model.on( 'change:url', this.updateImage, this );
    39554929                },