--- a/wp/wp-admin/js/theme.js Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-admin/js/theme.js Tue Dec 15 13:49:49 2020 +0100
@@ -11,36 +11,43 @@
var themes, l10n;
themes = wp.themes = wp.themes || {};
-// Store the theme data and settings for organized and quick access
-// themes.data.settings, themes.data.themes, themes.data.l10n
+// Store the theme data and settings for organized and quick access.
+// themes.data.settings, themes.data.themes, themes.data.l10n.
themes.data = _wpThemeSettings;
l10n = themes.data.l10n;
-// Shortcut for isInstall check
+// Shortcut for isInstall check.
themes.isInstall = !! themes.data.settings.isInstall;
-// Setup app structure
+// Setup app structure.
_.extend( themes, { model: {}, view: {}, routes: {}, router: {}, template: wp.template });
themes.Model = Backbone.Model.extend({
- // Adds attributes to the default data coming through the .org themes api
- // Map `id` to `slug` for shared code
+ // Adds attributes to the default data coming through the .org themes api.
+ // Map `id` to `slug` for shared code.
initialize: function() {
var description;
- // If theme is already installed, set an attribute.
- if ( _.indexOf( themes.data.installedThemes, this.get( 'slug' ) ) !== -1 ) {
- this.set({ installed: true });
+ if ( this.get( 'slug' ) ) {
+ // If the theme is already installed, set an attribute.
+ if ( _.indexOf( themes.data.installedThemes, this.get( 'slug' ) ) !== -1 ) {
+ this.set({ installed: true });
+ }
+
+ // If the theme is active, set an attribute.
+ if ( themes.data.activeTheme === this.get( 'slug' ) ) {
+ this.set({ active: true });
+ }
}
- // Set the attributes
+ // Set the attributes.
this.set({
- // slug is for installation, id is for existing.
+ // `slug` is for installation, `id` is for existing.
id: this.get( 'slug' ) || this.get( 'id' )
});
// Map `section.description` to `description`
- // as the API sometimes returns it differently
+ // as the API sometimes returns it differently.
if ( this.has( 'sections' ) ) {
description = this.get( 'sections' ).description;
this.set({ description: description });
@@ -48,31 +55,31 @@
}
});
-// Main view controller for themes.php
-// Unifies and renders all available views
+// Main view controller for themes.php.
+// Unifies and renders all available views.
themes.view.Appearance = wp.Backbone.View.extend({
el: '#wpbody-content .wrap .theme-browser',
window: $( window ),
- // Pagination instance
+ // Pagination instance.
page: 0,
- // Sets up a throttler for binding to 'scroll'
+ // Sets up a throttler for binding to 'scroll'.
initialize: function( options ) {
- // Scroller checks how far the scroll position is
+ // 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
+ // the results from this.scroller.
this.window.bind( 'scroll', _.throttle( this.scroller, 300 ) );
},
- // Main render control
+ // Main render control.
render: function() {
// Setup the main theme view
- // with the current theme collection
+ // with the current theme collection.
this.view = new themes.view.Themes({
collection: this.collection,
parent: this
@@ -83,21 +90,21 @@
this.$el.removeClass( 'search-loading' );
- // Render and append
+ // Render and append.
this.view.render();
this.$el.empty().append( this.view.el ).addClass( 'rendered' );
},
- // Defines search element container
+ // Defines search element container.
searchContainer: $( '.search-form' ),
// Search input and view
- // for current theme collection
+ // for current theme collection.
search: function() {
var view,
self = this;
- // Don't render the search if there is only one theme
+ // Don't render the search if there is only one theme.
if ( themes.data.themes.length === 1 ) {
return;
}
@@ -108,7 +115,7 @@
});
self.SearchView = view;
- // Render and append after screen title
+ // Render and append after screen title.
view.render();
this.searchContainer
.append( $.parseHTML( '<label class="screen-reader-text" for="wp-filter-search-input">' + l10n.search + '</label>' ) )
@@ -119,7 +126,7 @@
},
// Checks when the user gets close to the bottom
- // of the mage and triggers a theme:scroll event
+ // of the mage and triggers a theme:scroll event.
scroller: function() {
var self = this,
bottom, threshold;
@@ -134,26 +141,26 @@
}
});
-// Set up the Collection for our theme data
+// Set up the Collection for our theme data.
// @has 'id' 'name' 'screenshot' 'author' 'authorURI' 'version' 'active' ...
themes.Collection = Backbone.Collection.extend({
model: themes.Model,
- // Search terms
+ // Search terms.
terms: '',
// Controls searching on the current theme collection
- // and triggers an update event
+ // and triggers an update event.
doSearch: function( value ) {
- // Don't do anything if we've already done this search
- // Useful because the Search handler fires multiple times per keystroke
+ // Don't do anything if we've already done this search.
+ // Useful because the Search handler fires multiple times per keystroke.
if ( this.terms === value ) {
return;
}
- // Updates terms with the value passed
+ // Updates terms with the value passed.
this.terms = value;
// If we have terms, run a search...
@@ -161,35 +168,41 @@
this.search( this.terms );
}
- // If search is blank, show all themes
- // Useful for resetting the views when you clean the input
+ // If search is blank, show all themes.
+ // Useful for resetting the views when you clean the input.
if ( this.terms === '' ) {
this.reset( themes.data.themes );
$( 'body' ).removeClass( 'no-results' );
}
- // Trigger a 'themes:update' event
+ // Trigger a 'themes:update' event.
this.trigger( 'themes:update' );
},
- // Performs a search within the collection
- // @uses RegExp
+ /**
+ * Performs a search within the collection.
+ *
+ * @uses RegExp
+ */
search: function( term ) {
var match, results, haystack, name, description, author;
- // Start with a full collection
+ // Start with a full collection.
this.reset( themes.data.themes, { silent: true } );
- // Escape the term string for RegExp meta characters
+ // Trim the term.
+ term = term.trim();
+
+ // Escape the term string for RegExp meta characters.
term = term.replace( /[-\/\\^$*+?.()|[\]{}]/g, '\\$&' );
// Consider spaces as word delimiters and match the whole string
- // so matching terms can be combined
+ // so matching terms can be combined.
term = term.replace( / /g, ')(?=.*' );
match = new RegExp( '^(?=.*' + term + ').+', 'i' );
- // Find results
- // _.filter and .test
+ // Find results.
+ // _.filter() and .test().
results = this.filter( function( data ) {
name = data.get( 'name' ).replace( /(<([^>]+)>)/ig, '' );
description = data.get( 'description' ).replace( /(<([^>]+)>)/ig, '' );
@@ -214,12 +227,12 @@
},
// Paginates the collection with a helper method
- // that slices the collection
+ // that slices the collection.
paginate: function( instance ) {
var collection = this;
instance = instance || 0;
- // Themes per instance are set at 20
+ // Themes per instance are set at 20.
collection = _( collection.rest( 20 * instance ) );
collection = _( collection.first( 20 ) );
@@ -228,11 +241,13 @@
count: false,
- // Handles requests for more themes
- // and caches results
- //
- // When we are missing a cache object we fire an apiCall()
- // which triggers events of `query:success` or `query:fail`
+ /*
+ * Handles requests for more themes and caches results.
+ *
+ *
+ * When we are missing a cache object we fire an apiCall()
+ * which triggers events of `query:success` or `query:fail`.
+ */
query: function( request ) {
/**
* @static
@@ -243,7 +258,7 @@
query, isPaginated, count;
// Store current query request args
- // for later use with the event `theme:end`
+ // for later use with the event `theme:end`.
this.currentQuery.request = request;
// Search the query cache for matches.
@@ -255,7 +270,7 @@
// it means we have a paginated request.
isPaginated = _.has( request, 'page' );
- // Reset the internal api page counter for non paginated queries.
+ // Reset the internal api page counter for non-paginated queries.
if ( ! isPaginated ) {
this.currentQuery.page = 1;
}
@@ -268,7 +283,7 @@
if ( data.themes ) {
self.reset( data.themes );
count = data.info.results;
- // Store the results and the query request
+ // Store the results and the query request.
queries.push( { themes: data.themes, request: request, total: count } );
}
@@ -288,8 +303,8 @@
// If it's a paginated request we need to fetch more themes...
if ( isPaginated ) {
return this.apiCall( request, isPaginated ).done( function( data ) {
- // Add the new themes to the current collection
- // @todo update counter
+ // Add the new themes to the current collection.
+ // @todo Update counter.
self.add( data.themes );
self.trigger( 'query:success' );
@@ -308,7 +323,7 @@
}
// Only trigger an update event since we already have the themes
- // on our cached object
+ // on our cached object.
if ( _.isNumber( query.total ) ) {
this.count = query.total;
}
@@ -323,20 +338,20 @@
}
},
- // Local cache array for API queries
+ // Local cache array for API queries.
queries: [],
- // Keep track of current query so we can handle pagination
+ // Keep track of current query so we can handle pagination.
currentQuery: {
page: 1,
request: {}
},
- // Send request to api.wordpress.org/themes
+ // Send request to api.wordpress.org/themes.
apiCall: function( request, paginated ) {
return wp.ajax.send( 'query-themes', {
data: {
- // Request data
+ // Request data.
request: _.extend({
per_page: 100
}, request)
@@ -344,7 +359,7 @@
beforeSend: function() {
if ( ! paginated ) {
- // Spin it
+ // Spin it.
$( 'body' ).addClass( 'loading-content' ).removeClass( 'no-results' );
}
}
@@ -356,17 +371,17 @@
});
// This is the view that controls each theme item
-// that will be displayed on the screen
+// that will be displayed on the screen.
themes.view.Theme = wp.Backbone.View.extend({
- // Wrap theme data on a div.theme element
+ // Wrap theme data on a div.theme element.
className: 'theme',
- // Reflects which theme view we have
- // 'grid' (default) or 'detail'
+ // Reflects which theme view we have.
+ // 'grid' (default) or 'detail'.
state: 'grid',
- // The HTML template for each element to be rendered
+ // The HTML template for each element to be rendered.
html: themes.template( 'theme' ),
events: {
@@ -388,14 +403,14 @@
render: function() {
var data = this.model.toJSON();
- // Render themes using the html template
+ // Render themes using the html template.
this.$el.html( this.html( data ) ).attr({
tabindex: 0,
'aria-describedby' : data.id + '-action ' + data.id + '-name',
'data-slug': data.id
});
- // Renders active theme styles
+ // Renders active theme styles.
this.activeTheme();
if ( this.model.get( 'displayAuthor' ) ) {
@@ -404,7 +419,7 @@
},
// Adds a class to the currently active theme
- // and to the overlay in detailed view mode
+ // and to the overlay in detailed view mode.
activeTheme: function() {
if ( this.model.get( 'active' ) ) {
this.$el.addClass( 'active' );
@@ -419,25 +434,25 @@
$themeToFocus.addClass('focus');
},
- // Single theme overlay screen
- // It's shown when clicking a theme
+ // Single theme overlay screen.
+ // It's shown when clicking a theme.
expand: function( event ) {
var self = this;
event = event || window.event;
- // '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 ) ) {
return;
}
- // Bail if the user scrolled on a touch device
+ // Bail if the user scrolled on a touch device.
if ( this.touchDrag === true ) {
return this.touchDrag = false;
}
// Prevent the modal from showing when the user clicks
- // one of the direct action buttons
+ // one of the direct action buttons.
if ( $( event.target ).is( '.theme-actions a' ) ) {
return;
}
@@ -447,7 +462,7 @@
return;
}
- // Set focused theme to current element
+ // Set focused theme to current element.
themes.focusedTheme = this.$el;
this.trigger( 'theme:expand', self.model.cid );
@@ -463,7 +478,7 @@
event = event || window.event;
- // Bail if the user scrolled on a touch device
+ // Bail if the user scrolled on a touch device.
if ( this.touchDrag === true ) {
return this.touchDrag = false;
}
@@ -473,12 +488,12 @@
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 ) ) {
return;
}
- // pressing enter while focused on the buttons shouldn't open the preview
+ // Pressing Enter while focused on the buttons shouldn't open the preview.
if ( event.type === 'keydown' && event.which !== 13 && $( ':focus' ).hasClass( 'button' ) ) {
return;
}
@@ -499,14 +514,14 @@
preview.render();
this.setNavButtonsState();
- // Hide previous/next navigation if there is only one theme
+ // Hide previous/next navigation if there is only one theme.
if ( this.model.collection.length === 1 ) {
preview.$el.addClass( 'no-navigation' );
} else {
preview.$el.removeClass( 'no-navigation' );
}
- // Append preview
+ // Append preview.
$( 'div.wrap' ).append( preview.el );
// Listen to our preview object
@@ -542,7 +557,7 @@
// Keep track of current theme model.
current = self.model;
- // Bail early if we are at the beginning of the collection
+ // Bail early if we are at the beginning of the collection.
if ( self.model.collection.indexOf( self.current ) === 0 ) {
return;
}
@@ -574,14 +589,14 @@
},
- // Handles .disabled classes for previous/next buttons in theme installer preview
+ // Handles .disabled classes for previous/next buttons in theme installer preview.
setNavButtonsState: function() {
var $themeInstaller = $( '.theme-install-overlay' ),
current = _.isUndefined( this.current ) ? this.model : this.current,
previousThemeButton = $themeInstaller.find( '.previous-theme' ),
nextThemeButton = $themeInstaller.find( '.next-theme' );
- // Disable previous at the zero position
+ // Disable previous at the zero position.
if ( 0 === this.model.collection.indexOf( current ) ) {
previousThemeButton
.addClass( 'disabled' )
@@ -590,7 +605,7 @@
nextThemeButton.focus();
}
- // Disable next if the next model is undefined
+ // Disable next if the next model is undefined.
if ( _.isUndefined( this.model.collection.at( this.model.collection.indexOf( current ) + 1 ) ) ) {
nextThemeButton
.addClass( 'disabled' )
@@ -646,11 +661,11 @@
}
});
-// Theme Details view
-// Set ups a modal overlay with the expanded theme data
+// Theme Details view.
+// Sets up a modal overlay with the expanded theme data.
themes.view.Details = wp.Backbone.View.extend({
- // Wrap theme data on a div.theme element
+ // Wrap theme data on a div.theme element.
className: 'theme-overlay',
events: {
@@ -658,29 +673,30 @@
'click .delete-theme': 'deleteTheme',
'click .left': 'previousTheme',
'click .right': 'nextTheme',
- 'click #update-theme': 'updateTheme'
+ 'click #update-theme': 'updateTheme',
+ 'click .toggle-auto-update': 'autoupdateState'
},
- // The HTML template for the theme overlay
+ // The HTML template for the theme overlay.
html: themes.template( 'theme-single' ),
render: function() {
var data = this.model.toJSON();
this.$el.html( this.html( data ) );
- // Renders active theme styles
+ // Renders active theme styles.
this.activeTheme();
- // Set up navigation events
+ // Set up navigation events.
this.navigation();
- // Checks screenshot size
+ // Checks screenshot size.
this.screenshotCheck( this.$el );
- // Contain "tabbing" inside the overlay
+ // Contain "tabbing" inside the overlay.
this.containFocus( this.$el );
},
// Adds a class to the currently active theme
- // and to the overlay in detailed view mode
+ // and to the overlay in detailed view mode.
activeTheme: function() {
- // Check the model has the active property
+ // Check the model has the active property.
this.$el.toggleClass( 'active', this.model.get( 'active' ) );
},
@@ -710,44 +726,43 @@
});
},
- // Single theme overlay screen
- // It's shown when clicking a theme
+ // Single theme overlay screen.
+ // It's shown when clicking a theme.
collapse: function( event ) {
var self = this,
scroll;
event = event || window.event;
- // Prevent collapsing detailed view when there is only one theme available
+ // Prevent collapsing detailed view when there is only one theme available.
if ( themes.data.themes.length === 1 ) {
return;
}
- // Detect if the click is inside the overlay
- // and don't close it unless the target was
- // the div.back button
+ // Detect if the click is inside the overlay and don't close it
+ // unless the target was the div.back button.
if ( $( event.target ).is( '.theme-backdrop' ) || $( event.target ).is( '.close' ) || event.keyCode === 27 ) {
- // Add a temporary closing class while overlay fades out
+ // Add a temporary closing class while overlay fades out.
$( 'body' ).addClass( 'closing-overlay' );
- // With a quick fade out animation
+ // With a quick fade out animation.
this.$el.fadeOut( 130, function() {
- // Clicking outside the modal box closes the overlay
+ // Clicking outside the modal box closes the overlay.
$( 'body' ).removeClass( 'closing-overlay' );
- // Handle event cleanup
+ // Handle event cleanup.
self.closeOverlay();
- // Get scroll position to avoid jumping to the top
+ // Get scroll position to avoid jumping to the top.
scroll = document.body.scrollTop;
- // Clean the url structure
+ // Clean the URL structure.
themes.router.navigate( themes.router.baseUrl( '' ) );
- // Restore scroll position
+ // Restore scroll position.
document.body.scrollTop = scroll;
- // Return focus to the theme div
+ // Return focus to the theme div.
if ( themes.focusedTheme ) {
themes.focusedTheme.focus();
}
@@ -755,10 +770,10 @@
}
},
- // Handles .disabled classes for next/previous buttons
+ // Handles .disabled classes for next/previous buttons.
navigation: function() {
- // Disable Left/Right when at the start or end of the collection
+ // Disable Left/Right when at the start or end of the collection.
if ( this.model.cid === this.model.collection.at(0).cid ) {
this.$el.find( '.left' )
.addClass( 'disabled' )
@@ -772,7 +787,7 @@
},
// Performs the actions to effectively close
- // the theme details overlay
+ // the theme details overlay.
closeOverlay: function() {
$( 'body' ).removeClass( 'modal-open' );
this.remove();
@@ -780,6 +795,26 @@
this.trigger( 'theme:collapse' );
},
+ // Set state of the auto-update settings link after it has been changed and saved.
+ autoupdateState: function() {
+ var callback,
+ _this = this;
+
+ // Support concurrent clicks in different Theme Details overlays.
+ callback = function( event, data ) {
+ var autoupdate;
+ if ( _this.model.get( 'id' ) === data.asset ) {
+ autoupdate = _this.model.get( 'autoupdate' );
+ autoupdate.enabled = 'enable' === data.state;
+ _this.model.set( { autoupdate: autoupdate } );
+ $( document ).off( 'wp-auto-update-setting-changed', callback );
+ }
+ };
+
+ // Triggered in updates.js
+ $( document ).on( 'wp-auto-update-setting-changed', callback );
+ },
+
updateTheme: function( event ) {
var _this = this;
event.preventDefault();
@@ -845,7 +880,7 @@
},
// Checks if the theme screenshot is the old 300px width version
- // and adds a corresponding class if it's true
+ // and adds a corresponding class if it's true.
screenshotCheck: function( el ) {
var screenshot, image;
@@ -853,15 +888,15 @@
image = new Image();
image.src = screenshot.attr( 'src' );
- // Width check
+ // Width check.
if ( image.width && image.width <= 300 ) {
el.addClass( 'small-screenshot' );
}
}
});
-// Theme Preview view
-// Set ups a modal overlay with the expanded theme data
+// Theme Preview view.
+// Sets up a modal overlay with the expanded theme data.
themes.view.Preview = themes.view.Details.extend({
className: 'wp-full-overlay expanded',
@@ -877,7 +912,7 @@
'click .theme-install': 'installTheme'
},
- // The HTML template for the theme preview
+ // The HTML template for the theme preview.
html: themes.template( 'theme-preview' ),
render: function() {
@@ -915,7 +950,7 @@
this.$el.fadeOut( 200, function() {
$( 'body' ).removeClass( 'theme-installer-active full-overlay-active' );
- // Return focus to the theme div
+ // Return focus to the theme div.
if ( themes.focusedTheme ) {
themes.focusedTheme.focus();
}
@@ -970,17 +1005,17 @@
},
keyEvent: function( event ) {
- // The escape key closes the preview
+ // The escape key closes the preview.
if ( event.keyCode === 27 ) {
this.undelegateEvents();
this.close();
}
- // The right arrow key, next theme
+ // The right arrow key, next theme.
if ( event.keyCode === 39 ) {
_.once( this.nextTheme() );
}
- // The left arrow key, previous theme
+ // The left arrow key, previous theme.
if ( event.keyCode === 37 ) {
this.previousTheme();
}
@@ -1008,32 +1043,32 @@
});
// Controls the rendering of div.themes,
-// a wrapper that will hold all the theme elements
+// a wrapper that will hold all the theme elements.
themes.view.Themes = wp.Backbone.View.extend({
className: 'themes wp-clearfix',
$overlay: $( 'div.theme-overlay' ),
// Number to keep track of scroll position
- // while in theme-overlay mode
+ // while in theme-overlay mode.
index: 0,
- // The theme count element
+ // The theme count element.
count: $( '.wrap .theme-count' ),
- // The live themes count
+ // The live themes count.
liveThemeCount: 0,
initialize: function( options ) {
var self = this;
- // Set up parent
+ // Set up parent.
this.parent = options.parent;
- // Set current view to [grid]
+ // Set current view to [grid].
this.setView( 'grid' );
- // Move the active theme to the beginning of the collection
+ // Move the active theme to the beginning of the collection.
self.currentTheme();
// When the collection is updated by user input...
@@ -1079,17 +1114,17 @@
return;
}
- // Pressing the right arrow key fires a theme:next event
+ // Pressing the right arrow key fires a theme:next event.
if ( event.keyCode === 39 ) {
self.overlay.nextTheme();
}
- // Pressing the left arrow key fires a theme:previous event
+ // Pressing the left arrow key fires a theme:previous event.
if ( event.keyCode === 37 ) {
self.overlay.previousTheme();
}
- // Pressing the escape key fires a theme:collapse event
+ // Pressing the escape key fires a theme:collapse event.
if ( event.keyCode === 27 ) {
self.overlay.collapse( event );
}
@@ -1097,35 +1132,33 @@
},
// Manages rendering of theme pages
- // and keeping theme count in sync
+ // and keeping theme count in sync.
render: function() {
- // Clear the DOM, please
+ // Clear the DOM, please.
this.$el.empty();
- // If the user doesn't have switch capabilities
- // or there is only one theme in the collection
- // render the detailed view of the active theme
+ // If the user doesn't have switch capabilities or there is only one theme
+ // in the collection, render the detailed view of the active theme.
if ( themes.data.themes.length === 1 ) {
- // Constructs the view
+ // Constructs the view.
this.singleTheme = new themes.view.Details({
model: this.collection.models[0]
});
- // Render and apply a 'single-theme' class to our container
+ // Render and apply a 'single-theme' class to our container.
this.singleTheme.render();
this.$el.addClass( 'single-theme' );
this.$el.append( this.singleTheme.el );
}
- // Generate the themes
- // Using page instance
- // While checking the collection has items
+ // Generate the themes using page instance
+ // while checking the collection has items.
if ( this.options.collection.size() > 0 ) {
this.renderThemes( this.parent.page );
}
- // Display a live theme count for the collection
+ // Display a live theme count for the collection.
this.liveThemeCount = this.collection.count ? this.collection.count : this.collection.length;
this.count.text( this.liveThemeCount );
@@ -1139,25 +1172,25 @@
},
// Iterates through each instance of the collection
- // and renders each theme module
+ // and renders each theme module.
renderThemes: function( page ) {
var self = this;
self.instance = self.collection.paginate( page );
- // If we have no more themes bail
+ // If we have no more themes, bail.
if ( self.instance.size() === 0 ) {
// Fire a no-more-themes event.
this.parent.trigger( 'theme:end' );
return;
}
- // Make sure the add-new stays at the end
+ // Make sure the add-new stays at the end.
if ( ! themes.isInstall && page >= 1 ) {
$( '.add-new-theme' ).remove();
}
- // Loop through the themes and setup each theme view
+ // Loop through the themes and setup each theme view.
self.instance.each( function( theme ) {
self.theme = new themes.view.Theme({
model: theme,
@@ -1166,15 +1199,15 @@
// Render the views...
self.theme.render();
- // and append them to div.themes
+ // ...and append them to div.themes.
self.$el.append( self.theme.el );
// Binds to theme:expand to show the modal box
- // with the theme details
+ // with the theme details.
self.listenTo( self.theme, 'theme:expand', self.expand, self );
});
- // 'Add new theme' element shown at the end of the grid
+ // 'Add new theme' element shown at the end of the grid.
if ( ! themes.isInstall && themes.data.settings.canInstall ) {
this.$el.append( '<div class="theme add-new-theme"><a href="' + themes.data.settings.installURI + '"><div class="theme-screenshot"><span></span></div><h2 class="theme-name">' + l10n.addNew + '</h2></a></div>' );
}
@@ -1182,41 +1215,41 @@
this.parent.page++;
},
- // Grabs current theme and puts it at the beginning of the collection
+ // Grabs current theme and puts it at the beginning of the collection.
currentTheme: function() {
var self = this,
current;
current = self.collection.findWhere({ active: true });
- // Move the active theme to the beginning of the collection
+ // Move the active theme to the beginning of the collection.
if ( current ) {
self.collection.remove( current );
self.collection.add( current, { at:0 } );
}
},
- // Sets current view
+ // Sets current view.
setView: function( view ) {
return view;
},
- // Renders the overlay with the ThemeDetails view
- // Uses the current model data
+ // Renders the overlay with the ThemeDetails view.
+ // Uses the current model data.
expand: function( id ) {
var self = this, $card, $modal;
- // Set the current theme model
+ // Set the current theme model.
this.model = self.collection.get( id );
- // Trigger a route update for the current model
+ // Trigger a route update for the current model.
themes.router.navigate( themes.router.baseUrl( themes.router.themePath + this.model.id ) );
- // Sets this.view to 'detail'
+ // Sets this.view to 'detail'.
this.setView( 'detail' );
$( 'body' ).addClass( 'modal-open' );
- // Set up the theme details view
+ // Set up the theme details view.
this.overlay = new themes.view.Details({
model: self.model
});
@@ -1240,72 +1273,75 @@
this.$overlay.html( this.overlay.el );
- // Bind to theme:next and theme:previous
- // triggered by the arrow keys
- //
- // Keep track of the current model so we
- // can infer an index position
+ // Bind to theme:next and theme:previous triggered by the arrow keys.
+ // Keep track of the current model so we can infer an index position.
this.listenTo( this.overlay, 'theme:next', function() {
- // Renders the next theme on the overlay
+ // Renders the next theme on the overlay.
self.next( [ self.model.cid ] );
})
.listenTo( this.overlay, 'theme:previous', function() {
- // Renders the previous theme on the overlay
+ // Renders the previous theme on the overlay.
self.previous( [ self.model.cid ] );
});
},
- // This method renders the next theme on the overlay modal
- // based on the current position in the collection
- // @params [model cid]
+ /*
+ * This method renders the next theme on the overlay modal
+ * based on the current position in the collection.
+ *
+ * @params [model cid]
+ */
next: function( args ) {
var self = this,
model, nextModel;
- // Get the current theme
+ // Get the current theme.
model = self.collection.get( args[0] );
- // Find the next model within the collection
+ // Find the next model within the collection.
nextModel = self.collection.at( self.collection.indexOf( model ) + 1 );
- // Sanity check which also serves as a boundary test
+ // Sanity check which also serves as a boundary test.
if ( nextModel !== undefined ) {
// We have a new theme...
- // Close the overlay
+ // Close the overlay.
this.overlay.closeOverlay();
- // Trigger a route update for the current model
+ // Trigger a route update for the current model.
self.theme.trigger( 'theme:expand', nextModel.cid );
}
},
- // This method renders the previous theme on the overlay modal
- // based on the current position in the collection
- // @params [model cid]
+ /*
+ * This method renders the previous theme on the overlay modal
+ * based on the current position in the collection.
+ *
+ * @params [model cid]
+ */
previous: function( args ) {
var self = this,
model, previousModel;
- // Get the current theme
+ // Get the current theme.
model = self.collection.get( args[0] );
- // Find the previous model within the collection
+ // Find the previous model within the collection.
previousModel = self.collection.at( self.collection.indexOf( model ) - 1 );
if ( previousModel !== undefined ) {
// We have a new theme...
- // Close the overlay
+ // Close the overlay.
this.overlay.closeOverlay();
- // Trigger a route update for the current model
+ // Trigger a route update for the current model.
self.theme.trigger( 'theme:expand', previousModel.cid );
}
},
- // Dispatch audible search results feedback message
+ // Dispatch audible search results feedback message.
announceSearchResults: function( count ) {
if ( 0 === count ) {
wp.a11y.speak( l10n.noThemesFound );
@@ -1361,14 +1397,14 @@
this.collection.doSearch( event.target.value.replace( /\+/g, ' ' ) );
- // if search is initiated and key is not return
+ // if search is initiated and key is not return.
if ( this.searching && event.which !== 13 ) {
options.replace = true;
} else {
this.searching = true;
}
- // Update the URL hash
+ // Update the URL hash.
if ( event.target.value ) {
themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + event.target.value ), options );
} else {
@@ -1395,8 +1431,8 @@
* @since 4.9.0
*
* @param {string} url - URL to navigate to.
- * @param {object} state - State.
- * @returns {void}
+ * @param {Object} state - State.
+ * @return {void}
*/
function navigateRouter( url, state ) {
var router = this;
@@ -1405,8 +1441,8 @@
}
}
-// Sets up the routes events for relevant url queries
-// Listens to [theme] and [search] params
+// Sets up the routes events for relevant url queries.
+// Listens to [theme] and [search] params.
themes.Router = Backbone.Router.extend({
routes: {
@@ -1436,14 +1472,14 @@
});
-// Execute and setup the application
+// Execute and setup the application.
themes.Run = {
init: function() {
- // Initializes the blog's theme library view
- // Create a new collection with data
+ // Initializes the blog's theme library view.
+ // Create a new collection with data.
this.themes = new themes.Collection( themes.data.themes );
- // Set up the view
+ // Set up the view.
this.view = new themes.view.Appearance({
collection: this.themes
});
@@ -1456,7 +1492,7 @@
render: function() {
- // Render results
+ // Render results.
this.view.render();
this.routes();
@@ -1473,10 +1509,10 @@
routes: function() {
var self = this;
// Bind to our global thx object
- // so that the object is available to sub-views
+ // so that the object is available to sub-views.
themes.router = new themes.Router();
- // Handles theme details route event
+ // Handles theme details route event.
themes.router.on( 'route:theme', function( slug ) {
self.view.view.expand( slug );
});
@@ -1486,7 +1522,7 @@
self.view.trigger( 'theme:close' );
});
- // Handles search route event
+ // Handles search route event.
themes.router.on( 'route:search', function() {
$( '.wp-filter-search' ).trigger( 'keyup' );
});
@@ -1499,7 +1535,7 @@
}
};
-// Extend the main Search view
+// Extend the main Search view.
themes.view.InstallerSearch = themes.view.Search.extend({
events: {
@@ -1509,10 +1545,10 @@
terms: '',
- // Handles Ajax request for searching through themes in public repo
+ // Handles Ajax request for searching through themes in public repo.
search: function( event ) {
- // Tabbing or reverse tabbing into the search input shouldn't trigger a search
+ // Tabbing or reverse tabbing into the search input shouldn't trigger a search.
if ( event.type === 'keyup' && ( event.which === 9 || event.which === 16 ) ) {
return;
}
@@ -1540,19 +1576,23 @@
request.search = value;
- // Intercept an [author] search.
- //
- // If input value starts with `author:` send a request
- // for `author` instead of a regular `search`
+ /*
+ * Intercept an [author] search.
+ *
+ * If input value starts with `author:` send a request
+ * for `author` instead of a regular `search`.
+ */
if ( value.substring( 0, 7 ) === 'author:' ) {
request.search = '';
request.author = value.slice( 7 );
}
- // Intercept a [tag] search.
- //
- // If input value starts with `tag:` send a request
- // for `tag` instead of a regular `search`
+ /*
+ * Intercept a [tag] search.
+ *
+ * If input value starts with `tag:` send a request
+ * for `tag` instead of a regular `search`.
+ */
if ( value.substring( 0, 4 ) === 'tag:' ) {
request.search = '';
request.tag = [ value.slice( 4 ) ];
@@ -1566,10 +1606,10 @@
$( '.drawer-toggle' ).attr( 'aria-expanded', 'false' );
// 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 );
- // Set route
+ // Set route.
themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + encodeURIComponent( value ) ), { replace: true } );
}
});
@@ -1578,7 +1618,7 @@
el: '#wpbody-content .wrap',
- // Register events for sorting and filters in theme-navigation
+ // Register events for sorting and filters in theme-navigation.
events: {
'click .filter-links li > a': 'onSort',
'click .theme-filter': 'onFilter',
@@ -1591,7 +1631,7 @@
'keyup #wporg-username-input': 'saveUsername'
},
- // Initial render method
+ // Initial render method.
render: function() {
var self = this;
@@ -1603,7 +1643,7 @@
// Bump `collection.currentQuery.page` and request more themes if we hit the end of the page.
this.listenTo( this, 'theme:end', function() {
- // Make sure we are not already loading
+ // Make sure we are not already loading.
if ( self.collection.loadingThemes ) {
return;
}
@@ -1636,29 +1676,29 @@
this.view.remove();
}
- // Set ups the view and passes the section argument
+ // Sets up the view and passes the section argument.
this.view = new themes.view.Themes({
collection: this.collection,
parent: this
});
- // Reset pagination every time the install view handler is run
+ // Reset pagination every time the install view handler is run.
this.page = 0;
- // Render and append
+ // Render and append.
this.$el.find( '.themes' ).remove();
this.view.render();
this.$el.find( '.theme-browser' ).append( this.view.el ).addClass( 'rendered' );
},
- // Handles all the rendering of the public theme directory
+ // Handles all the rendering of the public theme directory.
browse: function( section ) {
// Create a new collection with the proper theme data
- // for each section
+ // for each section.
this.collection.query( { browse: section } );
},
- // Sorting navigation
+ // Sorting navigation.
onSort: function( event ) {
var $el = $( event.target ),
sort = $el.data( 'sort' );
@@ -1668,14 +1708,14 @@
$( 'body' ).removeClass( 'filters-applied show-filters' );
$( '.drawer-toggle' ).attr( 'aria-expanded', 'false' );
- // Bail if this is already active
+ // Bail if this is already active.
if ( $el.hasClass( this.activeClass ) ) {
return;
}
this.sort( sort );
- // Trigger a router.naviagte update
+ // Trigger a router.navigate update.
themes.router.navigate( themes.router.baseUrl( themes.router.browsePath + sort ) );
},
@@ -1702,13 +1742,13 @@
this.browse( sort );
},
- // Filters and Tags
+ // Filters and Tags.
onFilter: function( event ) {
var request,
$el = $( event.target ),
filter = $el.data( 'filter' );
- // Bail if this is already active
+ // Bail if this is already active.
if ( $el.hasClass( this.activeClass ) ) {
return;
}
@@ -1725,21 +1765,21 @@
}
// Construct the filter request
- // using the default values
+ // using the default values.
filter = _.union( [ filter, this.filtersChecked() ] );
request = { tag: [ filter ] };
// 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 );
},
- // Clicking on a checkbox to add another filter to the request
+ // Clicking on a checkbox to add another filter to the request.
addFilter: function() {
this.filtersChecked();
},
- // Applying filters triggers a tag request
+ // Applying filters triggers a tag request.
applyFilters: function( event ) {
var name,
tags = this.filtersChecked(),
@@ -1768,7 +1808,7 @@
});
// 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 );
},
@@ -1783,7 +1823,7 @@
event.preventDefault();
}
- // save username on enter
+ // Save username on enter.
if ( event.type === 'keyup' && event.which !== 13 ) {
return;
}
@@ -1795,14 +1835,17 @@
},
success: function () {
// Get the themes by sending Ajax POST request to api.wordpress.org/themes
- // or searching the local cache
+ // or searching the local cache.
that.collection.query( request );
}
} );
},
- // Get the checked filters
- // @return {array} of tags or false
+ /**
+ * Get the checked filters.
+ *
+ * @return {Array} of tags or false
+ */
filtersChecked: function() {
var items = $( '.filter-group' ).find( ':checkbox' ),
tags = [];
@@ -1811,7 +1854,7 @@
tags.push( $( item ).prop( 'value' ) );
});
- // When no filters are checked, restore initial state and return
+ // When no filters are checked, restore initial state and return.
if ( tags.length === 0 ) {
$( '.filter-drawer .apply-filters' ).find( 'span' ).text( '' );
$( '.filter-drawer .clear-filters' ).hide();
@@ -1827,7 +1870,7 @@
activeClass: 'current',
- /*
+ /**
* When users press the "Upload Theme" button, show the upload form in place.
*/
uploader: function() {
@@ -1842,7 +1885,7 @@
});
},
- // Toggle the full filters navigation
+ // Toggle the full filters navigation.
moreFilters: function( event ) {
var $body = $( 'body' ),
$toggleButton = $( '.drawer-toggle' );
@@ -1862,8 +1905,11 @@
$toggleButton.attr( 'aria-expanded', $body.hasClass( 'show-filters' ) );
},
- // Clears all the checked filters
- // @uses filtersChecked()
+ /**
+ * Clears all the checked filters.
+ *
+ * @uses filtersChecked()
+ */
clearFilters: function( event ) {
var items = $( '.filter-group' ).find( ':checkbox' ),
self = this;
@@ -1916,14 +1962,14 @@
themes.RunInstaller = {
init: function() {
- // Set up the view
- // Passes the default 'section' as an option
+ // Set up the view.
+ // Passes the default 'section' as an option.
this.view = new themes.view.Installer({
section: 'featured',
SearchView: themes.view.InstallerSearch
});
- // Render results
+ // Render results.
this.render();
// Start debouncing user searches after Backbone.history.start().
@@ -1932,7 +1978,7 @@
render: function() {
- // Render results
+ // Render results.
this.view.render();
this.routes();
@@ -1951,11 +1997,11 @@
request = {};
// Bind to our global `wp.themes` object
- // so that the router is available to sub-views
+ // so that the router is available to sub-views.
themes.router = new themes.InstallerRouter();
- // Handles `theme` route event
- // Queries the API for the passed theme slug
+ // Handles `theme` route event.
+ // Queries the API for the passed theme slug.
themes.router.on( 'route:preview', function( slug ) {
// Remove existing handlers.
@@ -1983,9 +2029,11 @@
}
});
- // Handles sorting / browsing routes
- // Also handles the root URL triggering a sort request
- // for `featured`, the default view
+ /*
+ * Handles sorting / browsing routes.
+ * Also handles the root URL triggering a sort request
+ * for `featured`, the default view.
+ */
themes.router.on( 'route:sort', function( sort ) {
if ( ! sort ) {
sort = 'featured';
@@ -2040,7 +2088,7 @@
})( jQuery );
-// Align theme browser thickbox
+// Align theme browser thickbox.
jQuery(document).ready( function($) {
window.tb_position = function() {
var tbWindow = $('#TB_window'),