Theme Installer: Handle currently installed themes, add search route, let prev/next refresh collections.

props matveb.
see #27055. fixes #27695.

Built from https://develop.svn.wordpress.org/trunk@28025


git-svn-id: http://core.svn.wordpress.org/trunk@27855 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Nacin 2014-04-07 23:04:15 +00:00
parent 5ce9ab1293
commit 56c1deba7c
7 changed files with 109 additions and 22 deletions

View File

@ -216,7 +216,8 @@
* Displays a theme update notice * Displays a theme update notice
* when an update is available. * when an update is available.
*/ */
.theme-browser .theme .theme-update { .theme-browser .theme .theme-update,
.theme-browser .theme .theme-installed {
background: #d54e21; background: #d54e21;
background: rgba(213, 78, 33, 0.95); background: rgba(213, 78, 33, 0.95);
color: #fff; color: #fff;
@ -234,7 +235,8 @@
overflow: hidden; overflow: hidden;
} }
.theme-browser .theme .theme-update:before { .theme-browser .theme .theme-update:before,
.theme-browser .theme .theme-installed:before {
content: '\f463'; content: '\f463';
display: inline-block; display: inline-block;
font: normal 20px/1 'dashicons'; font: normal 20px/1 'dashicons';
@ -1074,6 +1076,25 @@ body.folded .theme-overlay .theme-wrap {
16.2 - Install Themes 16.2 - Install Themes
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
/* Already installed theme */
.theme-browser .theme.is-installed {
cursor: default;
}
.theme-browser .theme .theme-installed {
background: #0074a2;
}
.theme-browser .theme .theme-installed:before {
content: '\f147';
}
.theme-browser .theme.is-installed .theme-actions,
.theme-browser.rendered .theme.is-installed .more-details {
display: none !important;
}
.theme-browser.rendered .theme.is-installed:hover .theme-screenshot img,
.theme-browser.rendered .theme.is-installed:focus .theme-screenshot img {
opacity: 1 !important;
}
.theme-navigation { .theme-navigation {
background: #fff; background: #fff;
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);

View File

@ -216,7 +216,8 @@
* Displays a theme update notice * Displays a theme update notice
* when an update is available. * when an update is available.
*/ */
.theme-browser .theme .theme-update { .theme-browser .theme .theme-update,
.theme-browser .theme .theme-installed {
background: #d54e21; background: #d54e21;
background: rgba(213, 78, 33, 0.95); background: rgba(213, 78, 33, 0.95);
color: #fff; color: #fff;
@ -234,7 +235,8 @@
overflow: hidden; overflow: hidden;
} }
.theme-browser .theme .theme-update:before { .theme-browser .theme .theme-update:before,
.theme-browser .theme .theme-installed:before {
content: '\f463'; content: '\f463';
display: inline-block; display: inline-block;
font: normal 20px/1 'dashicons'; font: normal 20px/1 'dashicons';
@ -1074,6 +1076,25 @@ body.folded .theme-overlay .theme-wrap {
16.2 - Install Themes 16.2 - Install Themes
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
/* Already installed theme */
.theme-browser .theme.is-installed {
cursor: default;
}
.theme-browser .theme .theme-installed {
background: #0074a2;
}
.theme-browser .theme .theme-installed:before {
content: '\f147';
}
.theme-browser .theme.is-installed .theme-actions,
.theme-browser.rendered .theme.is-installed .more-details {
display: none !important;
}
.theme-browser.rendered .theme.is-installed:hover .theme-screenshot img,
.theme-browser.rendered .theme.is-installed:focus .theme-screenshot img {
opacity: 1 !important;
}
.theme-navigation { .theme-navigation {
background: #fff; background: #fff;
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@ themes.Model = Backbone.Model.extend({
// Adds attributes to the default data coming through the .org themes api // Adds attributes to the default data coming through the .org themes api
// Map `id` to `slug` for shared code // Map `id` to `slug` for shared code
initialize: function() { initialize: function() {
var install, preview; var install, installed;
// Install url for the theme // Install url for the theme
// using the install nonce // using the install nonce
@ -35,18 +35,14 @@ themes.Model = Backbone.Model.extend({
// Build the url query // Build the url query
install = themes.data.settings.updateURI + '?' + $.param( install ); install = themes.data.settings.updateURI + '?' + $.param( install );
// Preview url for the theme // If theme is already installed, set an attribute.
preview = { if ( _.indexOf( themes.data.installedThemes, this.get( 'slug' ) ) !== -1 ) {
tab: 'theme-information', this.set({ installed: true });
theme: this.get( 'slug' ) }
};
preview = themes.data.settings.installURI + '?' + $.param( preview );
// Set the attributes // Set the attributes
this.set({ this.set({
installURI: install, installURI: ( this.get( 'slug' ) ) ? install : false,
previewURI: preview,
// slug is for installation, id is for existing. // slug is for installation, id is for existing.
id: this.get( 'slug' ) || this.get( 'id' ) id: this.get( 'slug' ) || this.get( 'id' )
}); });
@ -391,6 +387,11 @@ themes.view.Theme = wp.Backbone.View.extend({
if ( this.model.get( 'displayAuthor' ) ) { if ( this.model.get( 'displayAuthor' ) ) {
this.$el.addClass( 'display-author' ); this.$el.addClass( 'display-author' );
} }
if ( this.model.get( 'installed' ) ) {
this.$el.addClass( 'is-installed' );
this.$el.unbind();
}
}, },
// Adds a class to the currently active theme // Adds a class to the currently active theme
@ -451,6 +452,11 @@ themes.view.Theme = wp.Backbone.View.extend({
return this.touchDrag = false; return this.touchDrag = false;
} }
// Allow direct link path to installing a theme.
if ( $( event.target ).hasClass( 'button-primary' ) ) {
return;
}
// 'enter' and 'space' keys expand the details view when a theme is :focused // 'enter' and 'space' keys expand the details view when a theme is :focused
if ( event.type === 'keydown' && ( event.which !== 13 && event.which !== 32 ) ) { if ( event.type === 'keydown' && ( event.which !== 13 && event.which !== 32 ) ) {
return; return;
@ -494,6 +500,7 @@ themes.view.Theme = wp.Backbone.View.extend({
// If we have no more themes, bail. // If we have no more themes, bail.
if ( _.isUndefined( self.current ) ) { if ( _.isUndefined( self.current ) ) {
self.options.parent.parent.trigger( 'theme:end' );
return self.current = current; return self.current = current;
} }
@ -505,6 +512,7 @@ themes.view.Theme = wp.Backbone.View.extend({
// Render and append. // Render and append.
preview.render(); preview.render();
$( 'div.wrap' ).append( preview.el ); $( 'div.wrap' ).append( preview.el );
$( '.next-theme' ).focus();
}) })
.listenTo( preview, 'theme:previous', function() { .listenTo( preview, 'theme:previous', function() {
@ -532,6 +540,7 @@ themes.view.Theme = wp.Backbone.View.extend({
// Render and append. // Render and append.
preview.render(); preview.render();
$( 'div.wrap' ).append( preview.el ); $( 'div.wrap' ).append( preview.el );
$( '.previous-theme' ).focus();
}); });
} }
}); });
@ -882,7 +891,8 @@ themes.view.Themes = wp.Backbone.View.extend({
// Loop through the themes and setup each theme view // Loop through the themes and setup each theme view
self.instance.each( function( theme ) { self.instance.each( function( theme ) {
self.theme = new themes.view.Theme({ self.theme = new themes.view.Theme({
model: theme model: theme,
parent: self
}); });
// Render the views... // Render the views...
@ -1158,8 +1168,7 @@ themes.Run = {
// Handles search route event // Handles search route event
themes.router.on( 'route:search', function( query ) { themes.router.on( 'route:search', function( query ) {
self.view.trigger( 'theme:close' ); $( '.theme-search' ).trigger( 'keyup' );
self.themes.doSearch( query );
}); });
this.extraRoutes(); this.extraRoutes();
@ -1224,6 +1233,9 @@ themes.view.InstallerSearch = themes.view.Search.extend({
// Get the themes by sending Ajax POST request to api.wordpress.org/themes // Get the themes by sending Ajax POST request to api.wordpress.org/themes
// or searching the local cache // or searching the local cache
this.collection.query( request ); this.collection.query( request );
// Set route
themes.router.navigate( themes.router.baseUrl( '?search=' + value ), { replace: true } );
}, 300 ) }, 300 )
}); });
@ -1329,7 +1341,7 @@ themes.view.Installer = themes.view.Appearance.extend({
}, },
sort: function( sort ) { sort: function( sort ) {
$( '#theme-search-input' ).val( '' ); this.clearSearch();
$( '.theme-section, .theme-filter' ).removeClass( this.activeClass ); $( '.theme-section, .theme-filter' ).removeClass( this.activeClass );
$( '[data-sort="' + sort + '"]' ).addClass( this.activeClass ); $( '[data-sort="' + sort + '"]' ).addClass( this.activeClass );
@ -1450,6 +1462,9 @@ themes.view.Installer = themes.view.Appearance.extend({
return this.addFilter(); return this.addFilter();
} }
this.clearSearch();
themes.router.navigate( themes.router.baseUrl( '' ) );
$( 'body' ).toggleClass( 'more-filters-opened' ); $( 'body' ).toggleClass( 'more-filters-opened' );
}, },
@ -1474,6 +1489,10 @@ themes.view.Installer = themes.view.Appearance.extend({
backToFilters: function() { backToFilters: function() {
$( 'body' ).removeClass( 'filters-applied' ); $( 'body' ).removeClass( 'filters-applied' );
},
clearSearch: function() {
$( '#theme-search-input').val( '' );
} }
}); });
@ -1482,12 +1501,17 @@ themes.InstallerRouter = Backbone.Router.extend({
'theme-install.php?theme=:slug': 'preview', 'theme-install.php?theme=:slug': 'preview',
'theme-install.php?sort=:sort': 'sort', 'theme-install.php?sort=:sort': 'sort',
'theme-install.php?upload': 'upload', 'theme-install.php?upload': 'upload',
'theme-install.php?search=:query': 'search',
'': 'sort' '': 'sort'
}, },
baseUrl: function( url ) { baseUrl: function( url ) {
return 'theme-install.php' + url; return 'theme-install.php' + url;
} },
search: function( query ) {
$( '.theme-search' ).val( query );
},
}); });
@ -1542,6 +1566,11 @@ themes.RunInstaller = {
$( 'a.upload' ).trigger( 'click' ); $( 'a.upload' ).trigger( 'click' );
}); });
// Handles search route event
themes.router.on( 'route:search', function( query ) {
$( '.theme-search' ).focus().trigger( 'keyup' );
});
this.extraRoutes(); this.extraRoutes();
}, },

File diff suppressed because one or more lines are too long

View File

@ -33,6 +33,13 @@ $sections = array(
'new' => __( 'Newest Themes' ), 'new' => __( 'Newest Themes' ),
); );
$installed_themes = search_theme_directories();
foreach ( $installed_themes as $k => $v ) {
if ( false !== strpos( $k, '/' ) ) {
unset( $installed_themes[ $k ] );
}
}
wp_localize_script( 'theme', '_wpThemeSettings', array( wp_localize_script( 'theme', '_wpThemeSettings', array(
'themes' => false, 'themes' => false,
'settings' => array( 'settings' => array(
@ -51,6 +58,7 @@ wp_localize_script( 'theme', '_wpThemeSettings', array(
'back' => __( 'Back' ), 'back' => __( 'Back' ),
'error' => ( 'There was a problem trying to load the themes. Please, try again.' ), // @todo improve 'error' => ( 'There was a problem trying to load the themes. Please, try again.' ), // @todo improve
), ),
'installedThemes' => array_keys( $installed_themes ),
'browse' => array( 'browse' => array(
'sections' => $sections, 'sections' => $sections,
), ),
@ -190,13 +198,21 @@ if ( $tab ) {
<a class="button button-primary" href="{{ data.installURI }}"><?php esc_html_e( 'Install' ); ?></a> <a class="button button-primary" href="{{ data.installURI }}"><?php esc_html_e( 'Install' ); ?></a>
<a class="button button-secondary preview install-theme-preview" href="#"><?php esc_html_e( 'Preview' ); ?></a> <a class="button button-secondary preview install-theme-preview" href="#"><?php esc_html_e( 'Preview' ); ?></a>
</div> </div>
<# if ( data.installed ) { #>
<div class="theme-installed"><?php _e( 'Already Installed' ); ?></div>
<# } #>
</script> </script>
<script id="tmpl-theme-preview" type="text/template"> <script id="tmpl-theme-preview" type="text/template">
<div class="wp-full-overlay-sidebar"> <div class="wp-full-overlay-sidebar">
<div class="wp-full-overlay-header"> <div class="wp-full-overlay-header">
<a href="#" class="close-full-overlay button-secondary"><?php _e( 'Close' ); ?></a> <a href="#" class="close-full-overlay button-secondary"><?php _e( 'Close' ); ?></a>
<# if ( data.installed ) { #>
<a href="#" class="button button-primary theme-install disabled"><?php _e( 'Installed' ); ?></a>
<# } else { #>
<a href="{{ data.installURI }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a> <a href="{{ data.installURI }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a>
<# } #>
</div> </div>
<div class="wp-full-overlay-sidebar-content"> <div class="wp-full-overlay-sidebar-content">
<div class="install-theme-info"> <div class="install-theme-info">