Make WordPress Core

Changeset 24360


Ignore:
Timestamp:
05/25/2013 09:03:04 PM (13 years ago)
Author:
koopersmith
Message:

Extract the base views from media.

See #24424.

Location:
trunk/wp-includes/js
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/media-views.js

    r23956 r24360  
    844844     */
    845845
    846     // wp.media.Views
    847     // -------------
    848     //
    849     // A subview manager.
    850 
    851     media.Views = function( view, views ) {
    852         this.view = view;
    853         this._views = _.isArray( views ) ? { '': views } : views || {};
    854     };
    855 
    856     media.Views.extend = Backbone.Model.extend;
    857 
    858     _.extend( media.Views.prototype, {
    859         // ### Fetch all of the subviews
    860         //
    861         // Returns an array of all subviews.
    862         all: function() {
    863             return _.flatten( this._views );
    864         },
    865 
    866         // ### Get a selector's subviews
    867         //
    868         // Fetches all subviews that match a given `selector`.
    869         //
    870         // If no `selector` is provided, it will grab all subviews attached
    871         // to the view's root.
    872         get: function( selector ) {
    873             selector = selector || '';
    874             return this._views[ selector ];
    875         },
    876 
    877         // ### Get a selector's first subview
    878         //
    879         // Fetches the first subview that matches a given `selector`.
    880         //
    881         // If no `selector` is provided, it will grab the first subview
    882         // attached to the view's root.
    883         //
    884         // Useful when a selector only has one subview at a time.
    885         first: function( selector ) {
    886             var views = this.get( selector );
    887             return views && views.length ? views[0] : null;
    888         },
    889 
    890         // ### Register subview(s)
    891         //
    892         // Registers any number of `views` to a `selector`.
    893         //
    894         // When no `selector` is provided, the root selector (the empty string)
    895         // is used. `views` accepts a `Backbone.View` instance or an array of
    896         // `Backbone.View` instances.
    897         //
    898         // ---
    899         //
    900         // Accepts an `options` object, which has a significant effect on the
    901         // resulting behavior.
    902         //
    903         // `options.silent` – *boolean, `false`*
    904         // > If `options.silent` is true, no DOM modifications will be made.
    905         //
    906         // `options.add` – *boolean, `false`*
    907         // > Use `Views.add()` as a shortcut for setting `options.add` to true.
    908         //
    909         // > By default, the provided `views` will replace
    910         // any existing views associated with the selector. If `options.add`
    911         // is true, the provided `views` will be added to the existing views.
    912         //
    913         // `options.at` – *integer, `undefined`*
    914         // > When adding, to insert `views` at a specific index, use
    915         // `options.at`. By default, `views` are added to the end of the array.
    916         set: function( selector, views, options ) {
    917             var existing, next;
    918 
    919             if ( ! _.isString( selector ) ) {
    920                 options  = views;
    921                 views    = selector;
    922                 selector = '';
    923             }
    924 
    925             options  = options || {};
    926             views    = _.isArray( views ) ? views : [ views ];
    927             existing = this.get( selector );
    928             next     = views;
    929 
    930             if ( existing ) {
    931                 if ( options.add ) {
    932                     if ( _.isUndefined( options.at ) ) {
    933                         next = existing.concat( views );
    934                     } else {
    935                         next = existing;
    936                         next.splice.apply( next, [ options.at, 0 ].concat( views ) );
    937                     }
    938                 } else {
    939                     _.each( next, function( view ) {
    940                         view.__detach = true;
    941                     });
    942 
    943                     _.each( existing, function( view ) {
    944                         if ( view.__detach )
    945                             view.$el.detach();
    946                         else
    947                             view.dispose();
    948                     });
    949 
    950                     _.each( next, function( view ) {
    951                         delete view.__detach;
    952                     });
    953                 }
    954             }
    955 
    956             this._views[ selector ] = next;
    957 
    958             _.each( views, function( subview ) {
    959                 var constructor = subview.Views || media.Views,
    960                     subviews = subview.views = subview.views || new constructor( subview );
    961                 subviews.parent   = this.view;
    962                 subviews.selector = selector;
    963             }, this );
    964 
    965             if ( ! options.silent )
    966                 this._attach( selector, views, _.extend({ ready: this._isReady() }, options ) );
    967 
    968             return this;
    969         },
    970 
    971         // ### Add subview(s) to existing subviews
    972         //
    973         // An alias to `Views.set()`, which defaults `options.add` to true.
    974         //
    975         // Adds any number of `views` to a `selector`.
    976         //
    977         // When no `selector` is provided, the root selector (the empty string)
    978         // is used. `views` accepts a `Backbone.View` instance or an array of
    979         // `Backbone.View` instances.
    980         //
    981         // Use `Views.set()` when setting `options.add` to `false`.
    982         //
    983         // Accepts an `options` object. By default, provided `views` will be
    984         // inserted at the end of the array of existing views. To insert
    985         // `views` at a specific index, use `options.at`. If `options.silent`
    986         // is true, no DOM modifications will be made.
    987         //
    988         // For more information on the `options` object, see `Views.set()`.
    989         add: function( selector, views, options ) {
    990             if ( ! _.isString( selector ) ) {
    991                 options  = views;
    992                 views    = selector;
    993                 selector = '';
    994             }
    995 
    996             return this.set( selector, views, _.extend({ add: true }, options ) );
    997         },
    998 
    999         // ### Stop tracking subviews
    1000         //
    1001         // Stops tracking `views` registered to a `selector`. If no `views` are
    1002         // set, then all of the `selector`'s subviews will be unregistered and
    1003         // disposed.
    1004         //
    1005         // Accepts an `options` object. If `options.silent` is set, `dispose`
    1006         // will *not* be triggered on the unregistered views.
    1007         unset: function( selector, views, options ) {
    1008             var existing;
    1009 
    1010             if ( ! _.isString( selector ) ) {
    1011                 options = views;
    1012                 views = selector;
    1013                 selector = '';
    1014             }
    1015 
    1016             views = views || [];
    1017 
    1018             if ( existing = this.get( selector ) ) {
    1019                 views = _.isArray( views ) ? views : [ views ];
    1020                 this._views[ selector ] = views.length ? _.difference( existing, views ) : [];
    1021             }
    1022 
    1023             if ( ! options || ! options.silent )
    1024                 _.invoke( views, 'dispose' );
    1025 
    1026             return this;
    1027         },
    1028 
    1029         // ### Detach all subviews
    1030         //
    1031         // Detaches all subviews from the DOM.
    1032         //
    1033         // Helps to preserve all subview events when re-rendering the master
    1034         // view. Used in conjunction with `Views.render()`.
    1035         detach: function() {
    1036             $( _.pluck( this.all(), 'el' ) ).detach();
    1037             return this;
    1038         },
    1039 
    1040         // ### Render all subviews
    1041         //
    1042         // Renders all subviews. Used in conjunction with `Views.detach()`.
    1043         render: function() {
    1044             var options = {
    1045                     ready: this._isReady()
    1046                 };
    1047 
    1048             _.each( this._views, function( views, selector ) {
    1049                 this._attach( selector, views, options );
    1050             }, this );
    1051 
    1052             this.rendered = true;
    1053             return this;
    1054         },
    1055 
    1056         // ### Dispose all subviews
    1057         //
    1058         // Triggers the `dispose()` method on all subviews. Detaches the master
    1059         // view from its parent. Resets the internals of the views manager.
    1060         //
    1061         // Accepts an `options` object. If `options.silent` is set, `unset`
    1062         // will *not* be triggered on the master view's parent.
    1063         dispose: function( options ) {
    1064             if ( ! options || ! options.silent ) {
    1065                 if ( this.parent && this.parent.views )
    1066                     this.parent.views.unset( this.selector, this.view, { silent: true });
    1067                 delete this.parent;
    1068                 delete this.selector;
    1069             }
    1070 
    1071             _.invoke( this.all(), 'dispose' );
    1072             this._views = [];
    1073             return this;
    1074         },
    1075 
    1076         // ### Replace a selector's subviews
    1077         //
    1078         // By default, sets the `$target` selector's html to the subview `els`.
    1079         //
    1080         // Can be overridden in subclasses.
    1081         replace: function( $target, els ) {
    1082             $target.html( els );
    1083             return this;
    1084         },
    1085 
    1086         // ### Insert subviews into a selector
    1087         //
    1088         // By default, appends the subview `els` to the end of the `$target`
    1089         // selector. If `options.at` is set, inserts the subview `els` at the
    1090         // provided index.
    1091         //
    1092         // Can be overridden in subclasses.
    1093         insert: function( $target, els, options ) {
    1094             var at = options && options.at,
    1095                 $children;
    1096 
    1097             if ( _.isNumber( at ) && ($children = $target.children()).length > at )
    1098                 $children.eq( at ).before( els );
    1099             else
    1100                 $target.append( els );
    1101 
    1102             return this;
    1103         },
    1104 
    1105         // ### Trigger the ready event
    1106         //
    1107         // **Only use this method if you know what you're doing.**
    1108         // For performance reasons, this method does not check if the view is
    1109         // actually attached to the DOM. It's taking your word for it.
    1110         //
    1111         // Fires the ready event on the current view and all attached subviews.
    1112         ready: function() {
    1113             this.view.trigger('ready');
    1114 
    1115             // Find all attached subviews, and call ready on them.
    1116             _.chain( this.all() ).map( function( view ) {
    1117                 return view.views;
    1118             }).flatten().where({ attached: true }).invoke('ready');
    1119         },
    1120 
    1121         // #### Internal. Attaches a series of views to a selector.
    1122         //
    1123         // Checks to see if a matching selector exists, renders the views,
    1124         // performs the proper DOM operation, and then checks if the view is
    1125         // attached to the document.
    1126         _attach: function( selector, views, options ) {
    1127             var $selector = selector ? this.view.$( selector ) : this.view.$el,
    1128                 managers;
    1129 
    1130             // Check if we found a location to attach the views.
    1131             if ( ! $selector.length )
    1132                 return this;
    1133 
    1134             managers = _.chain( views ).pluck('views').flatten().value();
    1135 
    1136             // Render the views if necessary.
    1137             _.each( managers, function( manager ) {
    1138                 if ( manager.rendered )
    1139                     return;
    1140 
    1141                 manager.view.render();
    1142                 manager.rendered = true;
    1143             }, this );
    1144 
    1145             // Insert or replace the views.
    1146             this[ options.add ? 'insert' : 'replace' ]( $selector, _.pluck( views, 'el' ), options );
    1147 
    1148             // Set attached and trigger ready if the current view is already
    1149             // attached to the DOM.
    1150             _.each( managers, function( manager ) {
    1151                 manager.attached = true;
    1152 
    1153                 if ( options.ready )
    1154                     manager.ready();
    1155             }, this );
    1156 
    1157             return this;
    1158         },
    1159 
    1160         // #### Internal. Checks if the current view is in the DOM.
    1161         _isReady: function() {
    1162             var node = this.view.el;
    1163             while ( node ) {
    1164                 if ( node === document.body )
    1165                     return true;
    1166                 node = node.parentNode;
    1167             }
    1168 
    1169             return false;
    1170         }
    1171     });
    1172 
    1173846    // wp.media.View
    1174847    // -------------
    1175848    //
    1176849    // The base view class.
    1177     media.View = Backbone.View.extend({
    1178         // The constructor for the `Views` manager.
    1179         Views: media.Views,
    1180 
    1181         constructor: function( options ) {
    1182             this.views = new this.Views( this, this.views );
    1183             this.on( 'ready', this.ready, this );
    1184 
    1185             if ( options && options.controller )
    1186                 this.controller = options.controller;
    1187 
    1188             Backbone.View.apply( this, arguments );
    1189         },
    1190 
    1191         dispose: function() {
    1192             // Undelegating events, removing events from the model, and
    1193             // removing events from the controller mirror the code for
    1194             // `Backbone.View.dispose` in Backbone master.
    1195             this.undelegateEvents();
    1196 
    1197             if ( this.model && this.model.off )
    1198                 this.model.off( null, null, this );
    1199 
    1200             if ( this.collection && this.collection.off )
    1201                 this.collection.off( null, null, this );
    1202 
    1203             // Unbind controller events.
    1204             if ( this.controller && this.controller.off )
    1205                 this.controller.off( null, null, this );
    1206 
    1207             // Recursively dispose child views.
    1208             if ( this.views )
    1209                 this.views.dispose();
    1210 
    1211             return this;
    1212         },
    1213 
    1214         remove: function() {
    1215             this.dispose();
    1216             return Backbone.View.prototype.remove.apply( this, arguments );
    1217         },
    1218 
    1219         render: function() {
    1220             var options;
    1221 
    1222             if ( this.prepare )
    1223                 options = this.prepare();
    1224 
    1225             this.views.detach();
    1226 
    1227             if ( this.template ) {
    1228                 options = options || {};
    1229                 this.trigger( 'prepare', options );
    1230                 this.$el.html( this.template( options ) );
    1231             }
    1232 
    1233             this.views.render();
    1234             return this;
    1235         },
    1236 
    1237         prepare: function() {
    1238             return this.options;
    1239         },
    1240 
    1241         ready: function() {}
    1242     });
     850    media.View = wp.View;
    1243851
    1244852    /**
  • trunk/wp-includes/js/wp-backbone.js

    r24359 r24360  
    2626    });
    2727
     28
     29    // wp.Subviews
     30    // -----------
     31    //
     32    // A subview manager.
     33    wp.Subviews = function( view, views ) {
     34        this.view = view;
     35        this._views = _.isArray( views ) ? { '': views } : views || {};
     36    };
     37
     38    wp.Subviews.extend = Backbone.Model.extend;
     39
     40    _.extend( wp.Subviews.prototype, {
     41        // ### Fetch all of the subviews
     42        //
     43        // Returns an array of all subviews.
     44        all: function() {
     45            return _.flatten( this._views );
     46        },
     47
     48        // ### Get a selector's subviews
     49        //
     50        // Fetches all subviews that match a given `selector`.
     51        //
     52        // If no `selector` is provided, it will grab all subviews attached
     53        // to the view's root.
     54        get: function( selector ) {
     55            selector = selector || '';
     56            return this._views[ selector ];
     57        },
     58
     59        // ### Get a selector's first subview
     60        //
     61        // Fetches the first subview that matches a given `selector`.
     62        //
     63        // If no `selector` is provided, it will grab the first subview
     64        // attached to the view's root.
     65        //
     66        // Useful when a selector only has one subview at a time.
     67        first: function( selector ) {
     68            var views = this.get( selector );
     69            return views && views.length ? views[0] : null;
     70        },
     71
     72        // ### Register subview(s)
     73        //
     74        // Registers any number of `views` to a `selector`.
     75        //
     76        // When no `selector` is provided, the root selector (the empty string)
     77        // is used. `views` accepts a `Backbone.View` instance or an array of
     78        // `Backbone.View` instances.
     79        //
     80        // ---
     81        //
     82        // Accepts an `options` object, which has a significant effect on the
     83        // resulting behavior.
     84        //
     85        // `options.silent` – *boolean, `false`*
     86        // > If `options.silent` is true, no DOM modifications will be made.
     87        //
     88        // `options.add` – *boolean, `false`*
     89        // > Use `Views.add()` as a shortcut for setting `options.add` to true.
     90        //
     91        // > By default, the provided `views` will replace
     92        // any existing views associated with the selector. If `options.add`
     93        // is true, the provided `views` will be added to the existing views.
     94        //
     95        // `options.at` – *integer, `undefined`*
     96        // > When adding, to insert `views` at a specific index, use
     97        // `options.at`. By default, `views` are added to the end of the array.
     98        set: function( selector, views, options ) {
     99            var existing, next;
     100
     101            if ( ! _.isString( selector ) ) {
     102                options  = views;
     103                views    = selector;
     104                selector = '';
     105            }
     106
     107            options  = options || {};
     108            views    = _.isArray( views ) ? views : [ views ];
     109            existing = this.get( selector );
     110            next     = views;
     111
     112            if ( existing ) {
     113                if ( options.add ) {
     114                    if ( _.isUndefined( options.at ) ) {
     115                        next = existing.concat( views );
     116                    } else {
     117                        next = existing;
     118                        next.splice.apply( next, [ options.at, 0 ].concat( views ) );
     119                    }
     120                } else {
     121                    _.each( next, function( view ) {
     122                        view.__detach = true;
     123                    });
     124
     125                    _.each( existing, function( view ) {
     126                        if ( view.__detach )
     127                            view.$el.detach();
     128                        else
     129                            view.dispose();
     130                    });
     131
     132                    _.each( next, function( view ) {
     133                        delete view.__detach;
     134                    });
     135                }
     136            }
     137
     138            this._views[ selector ] = next;
     139
     140            _.each( views, function( subview ) {
     141                var constructor = subview.Views || wp.Subviews,
     142                    subviews = subview.views = subview.views || new constructor( subview );
     143                subviews.parent   = this.view;
     144                subviews.selector = selector;
     145            }, this );
     146
     147            if ( ! options.silent )
     148                this._attach( selector, views, _.extend({ ready: this._isReady() }, options ) );
     149
     150            return this;
     151        },
     152
     153        // ### Add subview(s) to existing subviews
     154        //
     155        // An alias to `Views.set()`, which defaults `options.add` to true.
     156        //
     157        // Adds any number of `views` to a `selector`.
     158        //
     159        // When no `selector` is provided, the root selector (the empty string)
     160        // is used. `views` accepts a `Backbone.View` instance or an array of
     161        // `Backbone.View` instances.
     162        //
     163        // Use `Views.set()` when setting `options.add` to `false`.
     164        //
     165        // Accepts an `options` object. By default, provided `views` will be
     166        // inserted at the end of the array of existing views. To insert
     167        // `views` at a specific index, use `options.at`. If `options.silent`
     168        // is true, no DOM modifications will be made.
     169        //
     170        // For more information on the `options` object, see `Views.set()`.
     171        add: function( selector, views, options ) {
     172            if ( ! _.isString( selector ) ) {
     173                options  = views;
     174                views    = selector;
     175                selector = '';
     176            }
     177
     178            return this.set( selector, views, _.extend({ add: true }, options ) );
     179        },
     180
     181        // ### Stop tracking subviews
     182        //
     183        // Stops tracking `views` registered to a `selector`. If no `views` are
     184        // set, then all of the `selector`'s subviews will be unregistered and
     185        // disposed.
     186        //
     187        // Accepts an `options` object. If `options.silent` is set, `dispose`
     188        // will *not* be triggered on the unregistered views.
     189        unset: function( selector, views, options ) {
     190            var existing;
     191
     192            if ( ! _.isString( selector ) ) {
     193                options = views;
     194                views = selector;
     195                selector = '';
     196            }
     197
     198            views = views || [];
     199
     200            if ( existing = this.get( selector ) ) {
     201                views = _.isArray( views ) ? views : [ views ];
     202                this._views[ selector ] = views.length ? _.difference( existing, views ) : [];
     203            }
     204
     205            if ( ! options || ! options.silent )
     206                _.invoke( views, 'dispose' );
     207
     208            return this;
     209        },
     210
     211        // ### Detach all subviews
     212        //
     213        // Detaches all subviews from the DOM.
     214        //
     215        // Helps to preserve all subview events when re-rendering the master
     216        // view. Used in conjunction with `Views.render()`.
     217        detach: function() {
     218            $( _.pluck( this.all(), 'el' ) ).detach();
     219            return this;
     220        },
     221
     222        // ### Render all subviews
     223        //
     224        // Renders all subviews. Used in conjunction with `Views.detach()`.
     225        render: function() {
     226            var options = {
     227                    ready: this._isReady()
     228                };
     229
     230            _.each( this._views, function( views, selector ) {
     231                this._attach( selector, views, options );
     232            }, this );
     233
     234            this.rendered = true;
     235            return this;
     236        },
     237
     238        // ### Dispose all subviews
     239        //
     240        // Triggers the `dispose()` method on all subviews. Detaches the master
     241        // view from its parent. Resets the internals of the views manager.
     242        //
     243        // Accepts an `options` object. If `options.silent` is set, `unset`
     244        // will *not* be triggered on the master view's parent.
     245        dispose: function( options ) {
     246            if ( ! options || ! options.silent ) {
     247                if ( this.parent && this.parent.views )
     248                    this.parent.views.unset( this.selector, this.view, { silent: true });
     249                delete this.parent;
     250                delete this.selector;
     251            }
     252
     253            _.invoke( this.all(), 'dispose' );
     254            this._views = [];
     255            return this;
     256        },
     257
     258        // ### Replace a selector's subviews
     259        //
     260        // By default, sets the `$target` selector's html to the subview `els`.
     261        //
     262        // Can be overridden in subclasses.
     263        replace: function( $target, els ) {
     264            $target.html( els );
     265            return this;
     266        },
     267
     268        // ### Insert subviews into a selector
     269        //
     270        // By default, appends the subview `els` to the end of the `$target`
     271        // selector. If `options.at` is set, inserts the subview `els` at the
     272        // provided index.
     273        //
     274        // Can be overridden in subclasses.
     275        insert: function( $target, els, options ) {
     276            var at = options && options.at,
     277                $children;
     278
     279            if ( _.isNumber( at ) && ($children = $target.children()).length > at )
     280                $children.eq( at ).before( els );
     281            else
     282                $target.append( els );
     283
     284            return this;
     285        },
     286
     287        // ### Trigger the ready event
     288        //
     289        // **Only use this method if you know what you're doing.**
     290        // For performance reasons, this method does not check if the view is
     291        // actually attached to the DOM. It's taking your word for it.
     292        //
     293        // Fires the ready event on the current view and all attached subviews.
     294        ready: function() {
     295            this.view.trigger('ready');
     296
     297            // Find all attached subviews, and call ready on them.
     298            _.chain( this.all() ).map( function( view ) {
     299                return view.views;
     300            }).flatten().where({ attached: true }).invoke('ready');
     301        },
     302
     303        // #### Internal. Attaches a series of views to a selector.
     304        //
     305        // Checks to see if a matching selector exists, renders the views,
     306        // performs the proper DOM operation, and then checks if the view is
     307        // attached to the document.
     308        _attach: function( selector, views, options ) {
     309            var $selector = selector ? this.view.$( selector ) : this.view.$el,
     310                managers;
     311
     312            // Check if we found a location to attach the views.
     313            if ( ! $selector.length )
     314                return this;
     315
     316            managers = _.chain( views ).pluck('views').flatten().value();
     317
     318            // Render the views if necessary.
     319            _.each( managers, function( manager ) {
     320                if ( manager.rendered )
     321                    return;
     322
     323                manager.view.render();
     324                manager.rendered = true;
     325            }, this );
     326
     327            // Insert or replace the views.
     328            this[ options.add ? 'insert' : 'replace' ]( $selector, _.pluck( views, 'el' ), options );
     329
     330            // Set attached and trigger ready if the current view is already
     331            // attached to the DOM.
     332            _.each( managers, function( manager ) {
     333                manager.attached = true;
     334
     335                if ( options.ready )
     336                    manager.ready();
     337            }, this );
     338
     339            return this;
     340        },
     341
     342        // #### Internal. Checks if the current view is in the DOM.
     343        _isReady: function() {
     344            var node = this.view.el;
     345            while ( node ) {
     346                if ( node === document.body )
     347                    return true;
     348                node = node.parentNode;
     349            }
     350
     351            return false;
     352        }
     353    });
     354
     355
     356    // wp.View
     357    // -------
     358    //
     359    // The base view class.
     360    wp.View = Backbone.View.extend({
     361        // The constructor for the `Views` manager.
     362        Subviews: wp.Subviews,
     363
     364        constructor: function( options ) {
     365            this.views = new this.Subviews( this, this.views );
     366            this.on( 'ready', this.ready, this );
     367
     368            if ( options && options.controller )
     369                this.controller = options.controller;
     370
     371            Backbone.View.apply( this, arguments );
     372        },
     373
     374        dispose: function() {
     375            // Undelegating events, removing events from the model, and
     376            // removing events from the controller mirror the code for
     377            // `Backbone.View.dispose` in Backbone master.
     378            this.undelegateEvents();
     379
     380            if ( this.model && this.model.off )
     381                this.model.off( null, null, this );
     382
     383            if ( this.collection && this.collection.off )
     384                this.collection.off( null, null, this );
     385
     386            // Unbind controller events.
     387            if ( this.controller && this.controller.off )
     388                this.controller.off( null, null, this );
     389
     390            // Recursively dispose child views.
     391            if ( this.views )
     392                this.views.dispose();
     393
     394            return this;
     395        },
     396
     397        remove: function() {
     398            this.dispose();
     399            return Backbone.View.prototype.remove.apply( this, arguments );
     400        },
     401
     402        render: function() {
     403            var options;
     404
     405            if ( this.prepare )
     406                options = this.prepare();
     407
     408            this.views.detach();
     409
     410            if ( this.template ) {
     411                options = options || {};
     412                this.trigger( 'prepare', options );
     413                this.$el.html( this.template( options ) );
     414            }
     415
     416            this.views.render();
     417            return this;
     418        },
     419
     420        prepare: function() {
     421            return this.options;
     422        },
     423
     424        ready: function() {}
     425    });
    28426}(jQuery));
Note: See TracChangeset for help on using the changeset viewer.