diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 329d54622b..54d00a06e6 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -25,7 +25,8 @@ margin-left: 20px; } -.themes-php .wrap .theme-count { +.themes-php .wrap .theme-count, +.theme-navigation .theme-count { color: #fff; -webkit-border-radius: 30px; border-radius: 30px; @@ -1064,157 +1065,210 @@ body.folded .theme-overlay .theme-wrap { 16.2 - Install Themes ------------------------------------------------------------------------------*/ -.theme-install-php h4 { - margin: 2.5em 0 8px; +.theme-install-php h2 .upload { + margin-left: 10px; } - -.theme-install-php .tablenav { - height: auto; -} - -.theme-install-php .spinner { - margin-top: 9px; -} - -.available-theme { +.theme-navigation { + background: #fff; + box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #555; display: inline-block; - margin-right: 10px; - overflow: hidden; - padding: 20px 20px 20px 0; - vertical-align: top; - width: 300px; + font-size: 13px; + margin: 20px 0 30px; + padding: 0 20px; + position: relative; + width: 100%; } - -.available-theme .screenshot { - width: 300px; - height: 225px; +.upload-theme { + -moz-box-sizing: border-box; + box-sizing: border-box; + display: none; + margin: 0px 0 0; + padding: 0; + width: 100%; + overflow: hidden; + position: relative; + top: 10px; +} +.upload-theme.opened { display: block; - border: 1px solid #ccc; - margin-bottom: 10px; - overflow: hidden; - background-color: #fff; } - -.available-theme img { - width: 300px; +.upload-theme .wp-upload-form { + background: #fafafa; + border: 1px solid #e5e5e5; + padding: 30px; + margin: 30px auto; + max-width: 380px; } - -.available-theme h3 { - margin: 15px 0 0; +.upload-theme .install-help { + color: #999; + font-size: 18px; + font-style: normal; + margin: 0; + padding: 40px 0 0; + text-align: center; } - -.available-theme .theme-author { - line-height: 18px; +.upload-theme.opened + .theme-navigation, +.upload-theme.opened + .theme-navigation + .theme-browser { + display: none; } - -.available-theme .action-links { - margin-top: 10px; - overflow: hidden; +.theme-navigation .theme-count { + top: 3px; + margin-left: 0; } - -.available-theme a.screenshot:focus { - border-color: #777; -} - -.available-theme .action-links li { - float: left; - padding-right: 10px; - margin-right: 10px; - border-right: 1px solid #dfdfdf; -} - -.available-theme .action-links li { - padding-right: 8px; - margin-right: 8px; -} - -.ie8 .available-theme .action-links li { - padding-right: 7px; - margin-right: 7px; -} - -.available-theme .action-links li:last-child { - padding-right: 0; - margin-right: 0; - border-right: 0; -} - -.available-theme .action-links .delete-theme { - float: right; - margin-left: 8px; - margin-right: 0; -} - -.available-theme .action-links .delete-theme a { - color: red; - padding: 2px; -} - -.available-theme .action-links .delete-theme a:hover { - background: red; - color: #fff; - text-decoration: none; -} - -.available-theme .action-links p { - float: left; -} - -/* Allow for three-up in small windows when sidebar is collapsed */ -@media only screen and (max-width: 1200px) { - .folded .available-theme, - .folded .available-theme .screenshot { - width: 300px; - } - - .folded .available-theme .screenshot { - height: 225px; - } -} - -/* Adjust three-up display in smaller windows when sidebar is collapsed */ -@media only screen and (max-width: 1079px) { - .folded .available-theme, - .folded .available-theme .screenshot { - width: 270px; - } - - .folded .available-theme .screenshot { - height: 203px; - } -} - -/* Allow for three-up on 1024px wide screens, e.g. tablets */ -@media only screen and (max-width: 1200px) { - .available-theme, - .available-theme .screenshot { - width: 240px; - } - - .available-theme .screenshot { - height: 180px; - } - - .available-theme img { - width: 100%; - } -} - -.feature-filter { - padding: 8px 12px 0; -} - -.feature-filter .feature-group { - float: left; - margin: 5px 10px 10px; -} - -.feature-filter .feature-group li { +.theme-section, +.theme-filter { + border-bottom: 4px solid #fff; + color: #666; + cursor: pointer; display: inline-block; + margin: 0 10px; + padding: 15px 0; + -moz-transition: border-color .1s ease-in; + -webkit-transition: border-color .1s ease-in; +} +.theme-section.current, +.theme-filter.current { + border-bottom: 4px solid #666; + color: #222; +} +.theme-top-filters { + display: inline-block; +} +.theme-navigation .more-filters { + color: #666; + cursor: pointer; + display: inline-block; + margin: 0 10px; + padding: 4px 5px; + -moz-transition: color .1s ease-in, background .1s ease-in; + -webkit-transition: color .1s ease-in, background .1s ease-in; + transition: color .1s ease-in, background .1s ease-in; +} +body.more-filters-opened .more-filters, +.theme-navigation .more-filters.current { + background: rgb(46, 162, 204); + border-radius: 2px; + border: none; + color: #fff; +} +.theme-install-php .theme-search { + position: absolute; + right: 10px; + top: 9px; + font-size: 16px; + font-weight: 300; + line-height: 1.5; + width: 280px; +} +.more-filters:before { + color: #777; + text-align: center; + margin: 0 5px 0 0; + content: "\f111"; + display: inline-block; + width: 16px; + height: 16px; + -webkit-font-smoothing: antialiased; + font-size: 16px; + line-height: 1; + font-family: "dashicons"; + text-decoration: inherit; + font-weight: normal; + font-style: normal; vertical-align: top; - list-style-type: none; - padding-right: 25px; - width: 150px; + -moz-transition: color .1s ease-in 0; + -webkit-transition: color .1s ease-in 0; + transition: color .1s ease-in 0; + text-align: center; +} +.more-filters.current:before { + color: #fff; +} +.more-filters-container { + display: none; + padding: 30px; + border-top: 1px solid #eee; + margin: 0 -20px; + background: #fafafa; +} +body.more-filters-opened .more-filters-container { + display: block; +} +.theme-install-php .add-new-theme { + display: none !important; +} + +.rating { + margin: 30px 0; +} +.rating span:before { + color: #e6b800; + content: "\f154"; + display: inline-block; + -webkit-font-smoothing: antialiased; + font: normal 20px/1 'dashicons'; + vertical-align: top; +} +/* Half stars */ +.rating-10 span.one:before, +.rating-30 span.two:before, +.rating-50 span.three:before, +.rating-70 span.four:before, +.rating-90 span.five:before { + content: "\f459"; +} +/* Full stars */ +.rating-20 span.one:before { + content: "\f155"; +} +.rating-30 span.one:before, +.rating-40 span.one:before, +.rating-40 span.two:before { + content: "\f155"; +} +.rating-50 span.one:before, +.rating-50 span.two:before, +.rating-60 span.one:before, +.rating-60 span.two:before, +.rating-60 span.three:before { + content: "\f155"; +} +.rating-70 span.one:before, +.rating-70 span.two:before, +.rating-70 span.three:before, +.rating-80 span.one:before, +.rating-80 span.two:before, +.rating-80 span.three:before, +.rating-80 span.four:before { + content: "\f155"; +} +.rating-90 span.one:before, +.rating-90 span.two:before, +.rating-90 span.three:before, +.rating-90 span.four:before, +.rating-100 span.one:before, +.rating-100 span.two:before, +.rating-100 span.three:before, +.rating-100 span.four:before, +.rating-100 span.five:before { + content: "\f155"; +} +.rating .votes { + display: inline; + margin-left: 10px; + line-height: 20px; +} +.loading-themes .theme-browser, +.error .theme-browser { + display: none; +} +.loading-themes .spinner { + display: block; + margin: 40px auto 0; + float: none; } /*------------------------------------------------------------------------------ diff --git a/src/wp-admin/includes/theme-install.php b/src/wp-admin/includes/theme-install.php index 63be1d7e01..0a28e0fabd 100644 --- a/src/wp-admin/includes/theme-install.php +++ b/src/wp-admin/includes/theme-install.php @@ -132,11 +132,10 @@ function install_themes_dashboard() { -
prepare_items(); $wp_list_table->single_row( $theme ); } @@ -166,12 +169,17 @@ function display_theme( $theme ) { function display_themes() { global $wp_list_table; + if ( ! isset( $wp_list_table ) ) { + $wp_list_table = _get_list_table('WP_Theme_Install_List_Table'); + } + $wp_list_table->prepare_items(); $wp_list_table->display(); + } -add_action('install_themes_search', 'display_themes'); -add_action('install_themes_featured', 'display_themes'); -add_action('install_themes_new', 'display_themes'); -add_action('install_themes_updated', 'display_themes'); +// add_action('install_themes_search', 'display_themes'); +// add_action('install_themes_featured', 'display_themes'); +// add_action('install_themes_new', 'display_themes'); +// add_action('install_themes_updated', 'display_themes'); /** * Display theme information in dialog box form. @@ -179,7 +187,7 @@ add_action('install_themes_updated', 'display_themes'); * @since 2.8.0 */ function install_theme_information() { - global $tab, $themes_allowedtags, $wp_list_table; + global $wp_list_table; $theme = themes_api( 'theme_information', array( 'slug' => wp_unslash( $_REQUEST['theme'] ) ) ); @@ -187,6 +195,9 @@ function install_theme_information() { wp_die( $theme ); iframe_header( __('Theme Install') ); + if ( ! isset( $wp_list_table ) ) { + $wp_list_table = _get_list_table('WP_Theme_Install_List_Table'); + } $wp_list_table->theme_installer_single( $theme ); iframe_footer(); exit; diff --git a/src/wp-admin/js/theme-install.js b/src/wp-admin/js/theme-install.js deleted file mode 100644 index 41fa244f7b..0000000000 --- a/src/wp-admin/js/theme-install.js +++ /dev/null @@ -1,268 +0,0 @@ -/* global ajaxurl, list_args, theme_list_args */ - -var theme_viewer; - -/** - * Theme Browsing - * - * Controls visibility of theme details on manage and install themes pages. - */ -jQuery( function($) { - $('#availablethemes').on( 'click', '.theme-detail', function (event) { - var theme = $(this).closest('.available-theme'), - details = theme.find('.themedetaildiv'); - - if ( ! details.length ) { - details = theme.find('.install-theme-info .theme-details'); - details = details.clone().addClass('themedetaildiv').appendTo( theme ).hide(); - } - - details.toggle(); - event.preventDefault(); - }); -}); - -/** - * Theme Install - * - * Displays theme previews on theme install pages. - */ -jQuery( function($) { - if ( ! window.postMessage ) { - return; - } - - var preview = $('#theme-installer'), - header = preview.find('.wp-full-overlay-header'), - info = preview.find('.install-theme-info'), - panel = preview.find('.wp-full-overlay-main'), - body = $( document.body ); - - preview.on( 'click', '.close-full-overlay', function( event ) { - preview.fadeOut( 200, function() { - panel.empty(); - body.removeClass('theme-installer-active full-overlay-active'); - }); - event.preventDefault(); - }); - - preview.on( 'click', '.collapse-sidebar', function( event ) { - preview.toggleClass( 'collapsed' ).toggleClass( 'expanded' ); - event.preventDefault(); - }); - - $('#availablethemes').on( 'click', '.install-theme-preview', function( event ) { - var src; - - info.html( $(this).closest('.installable-theme').find('.install-theme-info').html() ); - - header.find( '.theme-install' ).replaceWith( info.find( '.theme-install' ) ); - - src = info.find( '.theme-preview-url' ).val(); - panel.html( ''); - preview.fadeIn( 200, function() { - body.addClass('theme-installer-active full-overlay-active'); - }); - event.preventDefault(); - }); -}); - -var ThemeViewer; - -(function($){ - ThemeViewer = function() { - - function init() { - $( '#filter-click, #mini-filter-click' ).unbind( 'click' ).click( function() { - $( '#filter-click' ).toggleClass( 'current' ); - $( '#filter-box' ).slideToggle(); - $( '#current-theme' ).slideToggle( 300 ); - return false; - }); - - $( '#filter-box :checkbox' ).unbind( 'click' ).click( function() { - var count = $( '#filter-box :checked' ).length, - text = $( '#filter-click' ).text(); - - if ( text.indexOf( '(' ) !== -1 ) { - text = text.substr( 0, text.indexOf( '(' ) ); - } - - if ( count === 0 ) { - $( '#filter-click' ).text( text ); - } else { - $( '#filter-click' ).text( text + ' (' + count + ')' ); - } - }); - - /* $('#filter-box :submit').unbind( 'click' ).click(function() { - var features = []; - $('#filter-box :checked').each(function() { - features.push($(this).val()); - }); - - listTable.update_rows({'features': features}, true, function() { - $( '#filter-click' ).toggleClass( 'current' ); - $( '#filter-box' ).slideToggle(); - $( '#current-theme' ).slideToggle( 300 ); - }); - - return false; - }); */ - } - - // These are the functions we expose - var api = { - init: init - }; - - return api; - }; -})(jQuery); - -jQuery( document ).ready( function() { - theme_viewer = new ThemeViewer(); - theme_viewer.init(); -}); - - -/** - * Class that provides infinite scroll for Themes admin screens - * - * @since 3.4.0 - * - * @uses ajaxurl - * @uses list_args - * @uses theme_list_args - * @uses $('#_ajax_fetch_list_nonce').val() -* */ -var ThemeScroller; -(function($){ - ThemeScroller = { - querying: false, - scrollPollingDelay: 500, - failedRetryDelay: 4000, - outListBottomThreshold: 300, - - /** - * Initializer - * - * @since 3.4.0 - * @access private - */ - init: function() { - var self = this; - - // Get out early if we don't have the required arguments. - if ( typeof ajaxurl === 'undefined' || - typeof list_args === 'undefined' || - typeof theme_list_args === 'undefined' ) { - - $('.pagination-links').show(); - return; - } - - // Handle inputs - this.nonce = $('#_ajax_fetch_list_nonce').val(); - this.nextPage = ( theme_list_args.paged + 1 ); - - // Cache jQuery selectors - this.$outList = $('#availablethemes'); - this.$spinner = $('div.tablenav.bottom').children( '.spinner' ); - this.$window = $(window); - this.$document = $(document); - - /** - * If there are more pages to query, then start polling to track - * when user hits the bottom of the current page - */ - if ( theme_list_args.total_pages >= this.nextPage ) { - this.pollInterval = setInterval( function() { - return self.poll(); - }, this.scrollPollingDelay ); - } - }, - - /** - * Checks to see if user has scrolled to bottom of page. - * If so, requests another page of content from self.ajax(). - * - * @since 3.4.0 - * @access private - */ - poll: function() { - var bottom = this.$document.scrollTop() + this.$window.innerHeight(); - - if ( this.querying || - ( bottom < this.$outList.height() - this.outListBottomThreshold ) ) { - return; - } - - this.ajax(); - }, - - /** - * Applies results passed from this.ajax() to $outList - * - * @since 3.4.0 - * @access private - * - * @param results Array with results from this.ajax() query. - */ - process: function( results ) { - if ( results === undefined ) { - clearInterval( this.pollInterval ); - return; - } - - if ( this.nextPage > theme_list_args.total_pages ) { - clearInterval( this.pollInterval ); - } - - if ( this.nextPage <= ( theme_list_args.total_pages + 1 ) ) { - this.$outList.append( results.rows ); - } - }, - - /** - * Queries next page of themes - * - * @since 3.4.0 - * @access private - */ - ajax: function() { - var self = this, - query = { - action: 'fetch-list', - paged: this.nextPage, - s: theme_list_args.search, - tab: theme_list_args.tab, - type: theme_list_args.type, - _ajax_fetch_list_nonce: this.nonce, - 'features[]': theme_list_args.features, - 'list_args': list_args - }; - - this.querying = true; - - this.$spinner.show(); - $.getJSON( ajaxurl, query ) - .done( function( response ) { - self.nextPage++; - self.process( response ); - self.$spinner.hide(); - self.querying = false; - }) - .fail( function() { - self.$spinner.hide(); - self.querying = false; - setTimeout( function() { self.ajax(); }, self.failedRetryDelay ); - }); - } - }; - - $(document).ready( function() { - ThemeScroller.init(); - }); - -})(jQuery); diff --git a/src/wp-admin/js/theme-preview.js b/src/wp-admin/js/theme-preview.js deleted file mode 100644 index 28d93cfc70..0000000000 --- a/src/wp-admin/js/theme-preview.js +++ /dev/null @@ -1,59 +0,0 @@ -/* global tb_click */ -var thickDims, tbWidth, tbHeight; -jQuery(document).ready(function($) { - - thickDims = function() { - var tbWindow = $('#TB_window'), H = $(window).height(), W = $(window).width(), w, h; - - w = (tbWidth && tbWidth < W - 90) ? tbWidth : W - 90; - h = (tbHeight && tbHeight < H - 60) ? tbHeight : H - 60; - - if ( tbWindow.size() ) { - tbWindow.width(w).height(h); - $('#TB_iframeContent').width(w).height(h - 27); - tbWindow.css({'margin-left': '-' + parseInt((w / 2),10) + 'px'}); - if ( typeof document.body.style.maxWidth !== 'undefined' ) { - tbWindow.css({'top':'30px','margin-top':'0'}); - } - } - }; - - thickDims(); - $(window).resize( function() { thickDims(); } ); - - $('a.thickbox-preview').click( function() { - tb_click.call(this); - - var alink = $(this).parents('.available-theme').find('.activatelink'), link = '', href = $(this).attr('href'), url, text; - - if ( tbWidth = href.match(/&tbWidth=[0-9]+/) ) { - tbWidth = parseInt(tbWidth[0].replace(/[^0-9]+/g, ''), 10); - } else { - tbWidth = $(window).width() - 90; - } - - if ( tbHeight = href.match(/&tbHeight=[0-9]+/) ) { - tbHeight = parseInt(tbHeight[0].replace(/[^0-9]+/g, ''), 10); - } else { - tbHeight = $(window).height() - 60; - } - - if ( alink.length ) { - url = alink.attr('href') || ''; - text = alink.attr('title') || ''; - link = ' ' + text + ''; - } else { - text = $(this).attr('title') || ''; - link = ' ' + text + ''; - } - - $('#TB_title').css({'background-color':'#222','color':'#dfdfdf'}); - $('#TB_closeAjaxWindow').css({'float':'left'}); - $('#TB_ajaxWindowTitle').css({'float':'right'}).html(link); - - $('#TB_iframeContent').width('100%'); - thickDims(); - - return false; - } ); -}); diff --git a/src/wp-admin/js/theme.js b/src/wp-admin/js/theme.js index 7e12958993..ce9a835e22 100644 --- a/src/wp-admin/js/theme.js +++ b/src/wp-admin/js/theme.js @@ -12,10 +12,45 @@ themes = wp.themes = wp.themes || {}; themes.data = _wpThemeSettings; l10n = themes.data.l10n; +// Shortcut for isInstall check +themes.isInstall = !! themes.data.settings.isInstall; + // Setup app structure _.extend( themes, { model: {}, view: {}, routes: {}, router: {}, template: wp.template }); -themes.model = Backbone.Model.extend({}); +themes.Model = Backbone.Model.extend({ + // Adds attributes to the default data coming through the .org themes api + // Map `id` to `slug` for shared code + initialize: function() { + var install, preview; + + // Install url for the theme + // using the install nonce + install = { + action: 'install-theme', + theme: this.get( 'slug' ), + _wpnonce: themes.data.settings._nonceInstall + }; + + // Build the url query + install = themes.data.settings.updateURI + '?' + $.param( install ); + + // Preview url for the theme + preview = { + tab: 'theme-information', + theme: this.get( 'slug' ) + }; + + preview = themes.data.settings.installURI + '?' + $.param( preview ); + + // Set the attributes + this.set({ + installURI: install, + previewURI: preview, + id: this.get( 'slug' ) + }); + } +}); // Main view controller for themes.php // Unifies and renders all available views @@ -28,10 +63,11 @@ themes.view.Appearance = wp.Backbone.View.extend({ page: 0, // Sets up a throttler for binding to 'scroll' - initialize: function() { + initialize: function( options ) { // Scroller checks how far the scroll position is _.bindAll( this, 'scroller' ); + this.SearchView = options.SearchView ? options.SearchView : themes.view.Search; // Bind to the scroll event and throttle // the results from this.scroller this.window.bind( 'scroll', _.throttle( this.scroller, 300 ) ); @@ -55,6 +91,9 @@ themes.view.Appearance = wp.Backbone.View.extend({ this.$el.append( '' + l10n.error + '
' + l10n.error + '
' . sprintf(__('You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the WordPress.org Theme Directory. These themes are designed and developed by third parties, are available free of charge, and are compatible with the license WordPress uses.'), 'https://wordpress.org/themes/') . '
' . @@ -73,14 +99,39 @@ get_current_screen()->set_help_sidebar( ); include(ABSPATH . 'wp-admin/admin-header.php'); + ?> + + + + + $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth. if ( is_wp_error($api) ) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 728f87e683..7849c30a43 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -454,10 +454,6 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), false, 1 ); $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone' ), false, 1 ); - $scripts->add( 'theme-install', "/wp-admin/js/theme-install$suffix.js", array( 'jquery' ), false, 1 ); - - // @todo: Core no longer uses theme-preview.js. Remove? - $scripts->add( 'theme-preview', "/wp-admin/js/theme-preview$suffix.js", array( 'thickbox', 'jquery' ), false, 1 ); $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest', 'heartbeat' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'inline-edit-post', 'inlineEditL10n', array(