mirror of
https://github.com/WordPress/WordPress.git
synced 2024-10-05 19:18:15 +02:00
Media: Detect when views are added to the DOM and fire a ready event. see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22692 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
48293c9384
commit
05db7000c4
@ -632,7 +632,7 @@
|
|||||||
// > When adding, to insert `views` at a specific index, use
|
// > When adding, to insert `views` at a specific index, use
|
||||||
// `options.at`. By default, `views` are added to the end of the array.
|
// `options.at`. By default, `views` are added to the end of the array.
|
||||||
set: function( selector, views, options ) {
|
set: function( selector, views, options ) {
|
||||||
var $selector, els, existing, method;
|
var existing, next;
|
||||||
|
|
||||||
if ( ! _.isString( selector ) ) {
|
if ( ! _.isString( selector ) ) {
|
||||||
options = views;
|
options = views;
|
||||||
@ -644,7 +644,6 @@
|
|||||||
views = _.isArray( views ) ? views : [ views ];
|
views = _.isArray( views ) ? views : [ views ];
|
||||||
existing = this.get( selector );
|
existing = this.get( selector );
|
||||||
next = views;
|
next = views;
|
||||||
method = options.add ? 'insert' : 'replace';
|
|
||||||
|
|
||||||
if ( existing ) {
|
if ( existing ) {
|
||||||
if ( options.add ) {
|
if ( options.add ) {
|
||||||
@ -672,9 +671,6 @@
|
|||||||
|
|
||||||
this._views[ selector ] = next;
|
this._views[ selector ] = next;
|
||||||
|
|
||||||
$selector = selector ? this.view.$( selector ) : this.view.$el;
|
|
||||||
els = _.pluck( views, 'el' );
|
|
||||||
|
|
||||||
_.each( views, function( subview ) {
|
_.each( views, function( subview ) {
|
||||||
var constructor = subview.Views || media.Views,
|
var constructor = subview.Views || media.Views,
|
||||||
subviews = subview.views = subview.views || new constructor( subview );
|
subviews = subview.views = subview.views || new constructor( subview );
|
||||||
@ -682,10 +678,8 @@
|
|||||||
subviews.selector = selector;
|
subviews.selector = selector;
|
||||||
}, this );
|
}, this );
|
||||||
|
|
||||||
if ( ! options.silent ) {
|
if ( ! options.silent )
|
||||||
_.each( views, this._maybeRender, this );
|
this._attach( selector, views, _.extend({ ready: this._isReady() }, options ) );
|
||||||
this[ method ]( $selector, els, options );
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -755,16 +749,12 @@
|
|||||||
//
|
//
|
||||||
// Renders all subviews. Used in conjunction with `Views.detach()`.
|
// Renders all subviews. Used in conjunction with `Views.detach()`.
|
||||||
render: function() {
|
render: function() {
|
||||||
var root = this._views[''];
|
var options = {
|
||||||
|
ready: this._isReady()
|
||||||
_.each( this.all(), this._maybeRender, this );
|
};
|
||||||
|
|
||||||
if ( root )
|
|
||||||
this.replace( this.view.$el, _.pluck( root, 'el' ) );
|
|
||||||
|
|
||||||
_.each( this._views, function( views, selector ) {
|
_.each( this._views, function( views, selector ) {
|
||||||
if ( selector )
|
this._attach( selector, views, options );
|
||||||
this.replace( this.view.$( selector ), _.pluck( views, 'el' ) );
|
|
||||||
}, this );
|
}, this );
|
||||||
|
|
||||||
this.rendered = true;
|
this.rendered = true;
|
||||||
@ -820,14 +810,71 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ### Trigger the ready event
|
||||||
|
//
|
||||||
|
// **Only use this method if you know what you're doing.**
|
||||||
|
// For performance reasons, this method does not check if the view is
|
||||||
|
// actually attached to the DOM. It's taking your word for it.
|
||||||
|
//
|
||||||
|
// Fires the ready event on the current view and all attached subviews.
|
||||||
|
ready: function() {
|
||||||
|
this.view.trigger('ready');
|
||||||
|
|
||||||
// #### Internal. Maybe render a view.
|
// Find all attached subviews, and call ready on them.
|
||||||
_maybeRender: function( view ) {
|
_.chain( this.all() ).map( function( view ) {
|
||||||
if ( ! view.views || view.views.rendered )
|
return view.views;
|
||||||
|
}).flatten().where({ attached: true }).invoke('ready');
|
||||||
|
},
|
||||||
|
|
||||||
|
// #### Internal. Attaches a series of views to a selector.
|
||||||
|
//
|
||||||
|
// Checks to see if a matching selector exists, renders the views,
|
||||||
|
// performs the proper DOM operation, and then checks if the view is
|
||||||
|
// attached to the document.
|
||||||
|
_attach: function( selector, views, options ) {
|
||||||
|
var $selector = selector ? this.view.$( selector ) : this.view.$el,
|
||||||
|
managers;
|
||||||
|
|
||||||
|
// Check if we found a location to attach the views.
|
||||||
|
if ( ! $selector.length )
|
||||||
|
return this;
|
||||||
|
|
||||||
|
managers = _.chain( views ).pluck('views').flatten().value();
|
||||||
|
|
||||||
|
// Render the views if necessary.
|
||||||
|
_.each( managers, function( manager ) {
|
||||||
|
if ( manager.rendered )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
view.render();
|
manager.view.render();
|
||||||
view.views.rendered = true;
|
manager.rendered = true;
|
||||||
|
}, this );
|
||||||
|
|
||||||
|
// Insert or replace the views.
|
||||||
|
this[ options.add ? 'insert' : 'replace' ]( $selector, _.pluck( views, 'el' ), options );
|
||||||
|
|
||||||
|
// Set attached and trigger ready if the current view is already
|
||||||
|
// attached to the DOM.
|
||||||
|
_.each( managers, function( manager ) {
|
||||||
|
manager.attached = true;
|
||||||
|
|
||||||
|
if ( options.ready )
|
||||||
|
manager.ready();
|
||||||
|
}, this );
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
// #### Internal. Checks if the current view is in the DOM.
|
||||||
|
_isReady: function() {
|
||||||
|
var node = this.view.el;
|
||||||
|
while ( node ) {
|
||||||
|
if ( node === document.body )
|
||||||
|
return true;
|
||||||
|
node = node.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -841,6 +888,7 @@
|
|||||||
|
|
||||||
constructor: function() {
|
constructor: function() {
|
||||||
this.views = new this.Views( this, this.views );
|
this.views = new this.Views( this, this.views );
|
||||||
|
this.on( 'ready', this.ready, this );
|
||||||
Backbone.View.apply( this, arguments );
|
Backbone.View.apply( this, arguments );
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -885,7 +933,9 @@
|
|||||||
|
|
||||||
prepare: function() {
|
prepare: function() {
|
||||||
return this.options;
|
return this.options;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
ready: function() {}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -967,6 +1017,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.on( 'attach', _.bind( this.views.ready, this.views ), this );
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
@ -1060,9 +1112,9 @@
|
|||||||
// Map some of the modal's methods to the frame.
|
// Map some of the modal's methods to the frame.
|
||||||
_.each(['open','close','attach','detach'], function( method ) {
|
_.each(['open','close','attach','detach'], function( method ) {
|
||||||
media.view.MediaFrame.prototype[ method ] = function( view ) {
|
media.view.MediaFrame.prototype[ method ] = function( view ) {
|
||||||
this.trigger( method );
|
|
||||||
if ( this.modal )
|
if ( this.modal )
|
||||||
this.modal[ method ].apply( this.modal, arguments );
|
this.modal[ method ].apply( this.modal, arguments );
|
||||||
|
this.trigger( method );
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -1592,25 +1644,25 @@
|
|||||||
|
|
||||||
attach: function() {
|
attach: function() {
|
||||||
this.$el.appendTo( this.options.container );
|
this.$el.appendTo( this.options.container );
|
||||||
this.controller.trigger( 'attach', this.controller );
|
this.trigger('attach');
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
detach: function() {
|
detach: function() {
|
||||||
this.$el.detach();
|
this.$el.detach();
|
||||||
this.controller.trigger( 'detach', this.controller );
|
this.trigger('detach');
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
this.$el.show();
|
this.$el.show();
|
||||||
this.controller.trigger( 'open', this.controller );
|
this.trigger('open');
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function() {
|
close: function() {
|
||||||
this.$el.hide();
|
this.$el.hide();
|
||||||
this.controller.trigger( 'close', this.controller );
|
this.trigger('close');
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user