diff --git a/wp-includes/css/media-views.css b/wp-includes/css/media-views.css index 1e0b40656f..bd96ec2c5a 100644 --- a/wp-includes/css/media-views.css +++ b/wp-includes/css/media-views.css @@ -1249,6 +1249,18 @@ /** * Spinner */ + +.media-frame .spinner { + background: url(../images/wpspin.gif) no-repeat; + background-size: 16px 16px; + display: none; + opacity: 0.7; + filter: alpha(opacity=70); + width: 16px; + height: 16px; + margin: 0; +} + .media-sidebar .settings-save-status { background: #f5f5f5; float: right; @@ -1257,14 +1269,6 @@ } .media-sidebar .settings-save-status .spinner { - background: url(../images/wpspin.gif) no-repeat; - background-size: 16px 16px; - display: none; - float: right; - opacity: 0.7; - filter: alpha(opacity=70); - width: 16px; - height: 16px; margin: 0 5px 0; } @@ -1397,8 +1401,7 @@ .embed-url { display: block; position: relative; - height: 40px; - padding: 0 16px 16px; + padding: 0 16px 7px; margin: 0; z-index: 250; background: #fff; @@ -1416,6 +1419,16 @@ box-shadow: inset 2px 2px 4px -2px rgba( 0, 0, 0, 0.1 ); } +.media-frame .embed-url .spinner { + position: absolute; + top: 16px; + right: 26px; +} + +.media-frame .embed-loading .embed-url .spinner { + display: block; +} + .embed-link-settings, .embed-image-settings { position: absolute; @@ -1437,6 +1450,7 @@ .media-embed .thumbnail img { max-height: 200px; + display: block; } .media-embed .thumbnail:after { @@ -1652,7 +1666,7 @@ background-size: 134px 15px; } - .media-sidebar .settings-save-status .spinner { + .media-frame .spinner { background-image: url(../images/wpspin-2x.gif); } } \ No newline at end of file diff --git a/wp-includes/js/autosave.js b/wp-includes/js/autosave.js index 6e91d47bc3..3920d36061 100644 --- a/wp-includes/js/autosave.js +++ b/wp-includes/js/autosave.js @@ -230,7 +230,7 @@ function autosave_enable_buttons() { // delay that a bit to avoid some rare collisions while the DOM is being updated. setTimeout(function(){ jQuery(':button, :submit', '#submitpost').removeAttr('disabled'); - jQuery('.spinner').hide(); + jQuery('.spinner', '#submitpost').hide(); }, 500); } diff --git a/wp-includes/js/media-views.js b/wp-includes/js/media-views.js index 7054e09cc6..afbc3cef8b 100644 --- a/wp-includes/js/media-views.js +++ b/wp-includes/js/media-views.js @@ -778,9 +778,30 @@ }, scan: function() { - var attributes = { type: 'link' }; + var scanners, + embed = this, + attributes = { + type: 'link', + scanners: [] + }; - this.trigger( 'scan', attributes ); + // Scan is triggered with the list of `attributes` to set on the + // state, useful for the 'type' attribute and 'scanners' attribute, + // an array of promise objects for asynchronous scan operations. + if ( this.props.get('url') ) + this.trigger( 'scan', attributes ); + + if ( attributes.scanners.length ) { + scanners = attributes.scanners = $.when.apply( $, attributes.scanners ); + scanners.always( function() { + if ( embed.get('scanners') === scanners ) + embed.set( 'loading', false ); + }); + } else { + attributes.scanners = null; + } + + attributes.loading = !! attributes.scanners; this.set( attributes ); }, @@ -788,26 +809,30 @@ var frame = this.frame, state = this, url = this.props.get('url'), - image = new Image(); + image = new Image(), + deferred = $.Deferred(); + + attributes.scanners.push( deferred.promise() ); // Try to load the image and find its width/height. image.onload = function() { + deferred.resolve(); + if ( state !== frame.state() || url !== state.props.get('url') ) return; state.set({ - type: 'image', + type: 'image' + }); + + state.props.set({ width: image.width, height: image.height }); }; + image.onerror = deferred.reject; image.src = url; - - // Check if the URL looks like an image; skew toward success. - url = url.replace( /([?|#].*)$/, '' ); - if ( /\.(png|jpe?g|gif)$/i.test( url ) ) - attributes.type = 'image'; }, refresh: function() { @@ -4147,6 +4172,7 @@ this.views.set([ this.url ]); this.refresh(); this.model.on( 'change:type', this.refresh, this ); + this.model.on( 'change:loading', this.loading, this ); }, settings: function( view ) { @@ -4172,6 +4198,10 @@ model: this.model.props, priority: 40 }) ); + }, + + loading: function() { + this.$el.toggleClass( 'embed-loading', this.model.get('loading') ); } }); @@ -4194,8 +4224,12 @@ value: this.model.get('url') || '' }); + this.spinner = this.make( 'span', { + 'class': 'spinner' + }); + this.$input = $( this.input ); - this.$el.append( this.input ); + this.$el.append([ this.input, this.spinner ]); this.model.on( 'change:url', this.render, this ); },