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