PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | assets/js/mainwp-theme.js +190 -210 5.2.1 → 6.2.2 View file →
@@ -1,9 +1,9 @@
1 1 /* eslint complexity: ["error", 100] */
2 2 // current complexity is the only way to achieve desired results, pull request solutions appreciated.
3 3
4 4 /* global _mainwpThemeSettings, confirm */
5 -window.wp = window.wp || {};
5 +globalThis.wp = globalThis.wp || {};
6 6
7 7 (function ($) {
8 8
9 9 // Set up our namespace...
@@ -52,9 +52,9 @@
52 52 themes.view.Appearance = wp.Backbone.View.extend({
53 53
54 54 el: '#wpbody-content .mainwp-browse-themes',
55 55
56 - window: $(window),
56 + window: $(globalThis.window),
57 57 // Pagination instance
58 58 page: 0,
59 59
60 60 // Sets up a throttler for binding to 'scroll'
@@ -91,18 +91,15 @@
91 91
92 92 // Search input and view
93 93 // for current theme collection
94 94 search: function () {
95 - let view,
96 - self = this;
97 -
98 95 // Don't render the search if there is only one theme
99 96 if (themes.data.themes.length === 1) {
100 97 return;
101 98 }
102 99
103 - view = new this.SearchView({
104 - collection: self.collection,
100 + const view = new this.SearchView({
101 + collection: this.collection,
105 102 parent: this
106 103 });
107 104
108 105 // Render and append after screen title
@@ -114,13 +111,10 @@
114 111
115 112 // Checks when the user gets close to the bottom
116 113 // of the mage and triggers a theme:scroll event
117 114 scroller: function () {
118 - let self = this,
119 - bottom, threshold;
120 -
121 - bottom = this.window.scrollTop() + self.window.height();
122 - threshold = self.$el.offset().top + self.$el.outerHeight(false) - self.window.height();
115 + const bottom = this.window.scrollTop() + this.window.height();
116 + let threshold = this.$el.offset().top + this.$el.outerHeight(false) - this.window.height();
123 117 threshold = Math.round(threshold * 0.9);
124 118
125 119 if (bottom > threshold) {
126 120 this.trigger('theme:scroll');
@@ -174,13 +168,13 @@
174 168 // Start with a full collection
175 169 this.reset(themes.data.themes, { silent: true });
176 170
177 171 // Escape the term string for RegExp meta characters
178 - term = term.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
172 + term = term.replaceAll(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); // NOSONAR - safe pattern.
179 173
180 174 // Consider spaces as word delimiters and match the whole string
181 175 // so matching terms can be combined
182 - term = term.replace(/ /g, ')(?=.*');
176 + term = term.replaceAll(' ', ')(?=.*');
183 177 match = new RegExp('^(?=.*' + term + ').+', 'i');
184 178
185 179 // Find results
186 180 // _.filter and .test
@@ -208,17 +202,15 @@
208 202 },
209 203
210 204 // Paginates the collection with a helper method
211 205 // that slices the collection
212 - paginate: function (instance) {
213 - let collection = this;
214 - instance = instance || 0;
215 -
216 - // Themes per instance are set at 20
217 - collection = _(collection.rest(20 * instance));
206 + paginate: function (instance = 0) {
207 + // Themes per instance are set at 20
208 + let collection = _(this.rest(20 * instance));
218 209 collection = _(collection.first(20));
219 210
220 211 return collection;
212 +
221 213 },
222 214
223 215 count: false,
224 216
@@ -227,88 +219,83 @@
227 219 //
228 220 // When we are missing a cache object we fire an apiCall()
229 221 // which triggers events of `query:success` or `query:fail`
230 222 query: function (request) {
231 - /**
232 - * @static
233 - * @type Array
234 - */
235 - let queries = this.queries,
236 - self = this,
237 - query, isPaginated, count;
238 223
224 + let queries = this.queries;
225 + let query, isPaginated, count;
226 +
239 227 // Store current query request args
240 - // for later use with the event `theme:end`
241 228 this.currentQuery.request = request;
242 229
243 230 // Search the query cache for matches.
244 - query = _.find(queries, function (query) {
231 + query = _.find(queries, (query) => {
245 232 return _.isEqual(query.request, request);
246 233 });
247 234
248 - // If the request matches the stored currentQuery.request
249 - // it means we have a paginated request.
250 235 isPaginated = _.has(request, 'page');
251 236
252 - // Reset the internal api page counter for non paginated queries.
253 237 if (!isPaginated) {
254 238 this.currentQuery.page = 1;
255 239 }
256 240
257 - // Otherwise, send a new API call and add it to the cache.
258 241 if (!query && !isPaginated) {
259 - this.apiCall(request).done(function (data) {
260 242
261 - // Update the collection with the queried data.
262 - if (data.themes) {
263 - self.reset(data.themes);
264 - count = data.info.results;
265 - // Store the results and the query request
266 - queries.push({ themes: data.themes, request: request, total: count });
267 - }
243 + this.apiCall(request)
244 + .done((data) => {
268 245
269 - // Trigger a collection refresh event
270 - // and a `query:success` event with a `count` argument.
271 - self.trigger('update');
272 - self.trigger('query:success', count);
246 + if (data.themes) {
247 + this.reset(data.themes);
248 + count = data.info.results;
273 249
274 - if (data.themes && data.themes.length === 0) {
275 - self.trigger('query:empty');
276 - }
250 + queries.push({
251 + themes: data.themes,
252 + request: request,
253 + total: count
254 + });
255 + }
277 256
278 - }).fail(function () {
279 - self.trigger('query:fail');
280 - });
257 + this.trigger('update');
258 + this.trigger('query:success', count);
259 +
260 + if (data?.themes?.length === 0) {
261 + this.trigger('query:empty');
262 + }
263 +
264 + })
265 + .fail(() => {
266 + this.trigger('query:fail');
267 + });
268 +
281 269 } else {
282 - // If it's a paginated request we need to fetch more themes...
270 +
283 271 if (isPaginated) {
284 - return this.apiCall(request, isPaginated).done(function (data) {
285 - // Add the new themes to the current collection
286 - // @devtodo update counter
287 - self.add(data.themes);
288 - self.trigger('query:success');
272 + return this.apiCall(request, isPaginated)
273 + .done((data) => {
289 274
290 - // We are done loading themes for now.
291 - self.loadingThemes = false;
275 + this.add(data.themes);
276 + this.trigger('query:success');
292 277
293 - }).fail(function () {
294 - self.trigger('query:fail');
295 - });
278 + this.loadingThemes = false;
279 +
280 + })
281 + .fail(() => {
282 + this.trigger('query:fail');
283 + });
296 284 }
297 285
298 286 if (query.themes.length === 0) {
299 - self.trigger('query:empty');
287 + this.trigger('query:empty');
300 288 } else {
301 289 $('body').removeClass('no-results');
302 290 }
303 291
304 - // Only trigger an update event since we already have the themes
305 - // on our cached object
306 292 if (_.isNumber(query.total)) {
307 293 this.count = query.total;
308 294 }
309 295
310 296 this.reset(query.themes);
297 +
311 298 if (!query.total) {
312 299 this.count = this.length;
313 300 }
314 301
@@ -365,9 +352,9 @@
365 352 } else {
366 353 this[index].added_fav = 0;
367 354 }
368 355 }, response.themes); // use second param as this.
369 - } catch (e) {
356 + } catch {
370 357 console.log('Invalid favorites themes data.');
371 358 }
372 359 }
373 360 }
@@ -440,9 +427,8 @@
440 427
441 428 // Single theme overlay screen
442 429 // It's shown when clicking a theme
443 430 expand: function (event) {
444 - let self = this;
445 431
446 432 event = event || window.event; // NOSONAR - compatible.
447 433
448 434 // 'enter' and 'space' keys expand the details view when a theme is :focused
@@ -464,9 +450,9 @@
464 450
465 451 // Set focused theme to current element
466 452 themes.focusedTheme = this.$el;
467 453
468 - this.trigger('theme:expand', self.model.cid);
454 + this.trigger('theme:expand', this.model.cid);
469 455 },
470 456
471 457 preventExpand: function () {
472 458 this.touchDrag = true;
@@ -472,10 +458,9 @@
472 458 this.touchDrag = true;
473 459 },
474 460
475 461 preview: function (event) {
476 - let self = this,
477 - current, preview;
462 + let current, preview;
478 463
479 464 // Bail if the user scrolled on a touch device
480 465 if (this.touchDrag === true) {
481 466 this.touchDrag = false;
@@ -531,29 +516,29 @@
531 516 $('div.mainwp-content-wrap').append(preview.el);
532 517
533 518 // Listen to our preview object
534 519 // for `theme:next` and `theme:previous` events.
535 - this.listenTo(preview, 'theme:next', function () {
520 + this.listenTo(preview, 'theme:next', () => {
536 521
537 522 // Keep local track of current theme model.
538 - current = self.model;
523 + current = this.model;
539 524
540 525 // If we have ventured away from current model update the current model position.
541 - if (!_.isUndefined(self.current)) {
542 - current = self.current;
526 + if (!_.isUndefined(this.current)) {
527 + current = this.current;
543 528 }
544 529
545 530 // Get next theme model.
546 - self.current = self.model.collection.at(self.model.collection.indexOf(current) + 1);
531 + this.current = this.model.collection.at(this.model.collection.indexOf(current) + 1);
547 532
548 533 // If we have no more themes, bail.
549 - if (_.isUndefined(self.current)) {
550 - self.options.parent.parent.trigger('theme:end');
551 - self.current = current;
552 - return self.current;
534 + if (_.isUndefined(this.current)) {
535 + this.options.parent.parent.trigger('theme:end');
536 + this.current = current;
537 + return this.current;
553 538 }
554 539
555 - preview.model = self.current;
540 + preview.model = this.current;
556 541
557 542 // Render and append.
558 543 preview.render();
559 544 this.setNavButtonsState();
@@ -558,32 +543,32 @@
558 543 preview.render();
559 544 this.setNavButtonsState();
560 545 $('.next-theme').trigger('focus');
561 546 })
562 - .listenTo(preview, 'theme:previous', function () {
547 + .listenTo(preview, 'theme:previous', () => {
563 548
564 549 // Keep track of current theme model.
565 - current = self.model;
550 + current = this.model;
566 551
567 552 // Bail early if we are at the beginning of the collection
568 - if (self.model.collection.indexOf(self.current) === 0) {
553 + if (this.model.collection.indexOf(this.current) === 0) {
569 554 return;
570 555 }
571 556
572 557 // If we have ventured away from current model update the current model position.
573 - if (!_.isUndefined(self.current)) {
574 - current = self.current;
558 + if (!_.isUndefined(this.current)) {
559 + current = this.current;
575 560 }
576 561
577 562 // Get previous theme model.
578 - self.current = self.model.collection.at(self.model.collection.indexOf(current) - 1);
563 + this.current = this.model.collection.at(this.model.collection.indexOf(current) - 1);
579 564
580 565 // If we have no more themes, bail.
581 - if (_.isUndefined(self.current)) {
566 + if (_.isUndefined(this.current)) {
582 567 return;
583 568 }
584 569
585 - preview.model = self.current;
570 + preview.model = this.current;
586 571
587 572 // Render and append.
588 573 preview.render();
589 574 this.setNavButtonsState();
@@ -589,10 +574,10 @@
589 574 this.setNavButtonsState();
590 575 $('.previous-theme').trigger('focus');
591 576 });
592 577
593 - this.listenTo(preview, 'preview:close', function () {
594 - self.current = self.model;
578 + this.listenTo(preview, 'preview:close', () => {
579 + this.current = this.model;
595 580 });
596 581 },
597 582
598 583 // Handles .disabled classes for previous/next buttons in theme installer preview
@@ -679,11 +664,9 @@
679 664
680 665 // Single theme overlay screen
681 666 // It's shown when clicking a theme
682 667 collapse: function (event) {
683 - let self = this,
684 - scroll;
685 -
668 + let scroll;
686 669 event = event || window.event; // NOSONAR - compatible.
687 670
688 671 // Prevent collapsing detailed view when there is only one theme available
689 672 if (themes.data.themes.length === 1) {
@@ -698,13 +681,13 @@
698 681 // Add a temporary closing class while overlay fades out
699 682 $('body').addClass('closing-overlay');
700 683
701 684 // With a quick fade out animation
702 - this.$el.fadeOut(130, function () {
685 + this.$el.fadeOut(130, () => {
703 686 // Clicking outside the modal box closes the overlay
704 687 $('body').removeClass('closing-overlay');
705 688 // Handle event cleanup
706 - self.closeOverlay();
689 + this.closeOverlay();
707 690
708 691 // Get scroll position to avoid jumping to the top
709 692 scroll = document.body.scrollTop;
710 693
@@ -728,9 +711,9 @@
728 711 // Disable Left/Right when at the start or end of the collection
729 712 if (this.model.cid === this.model.collection.at(0).cid) {
730 713 this.$el.find('.left').addClass('disabled');
731 714 }
732 - if (this.model.cid === this.model.collection.at(this.model.collection.length - 1).cid) {
715 + if (this.model.cid === this.model.collection.at(-1).cid) {
733 716 this.$el.find('.right').addClass('disabled');
734 717 }
735 718 },
736 719
@@ -748,16 +731,14 @@
748 731 return confirm(themes.data.settings.confirmDelete);
749 732 },
750 733
751 734 nextTheme: function () {
752 - let self = this;
753 - self.trigger('theme:next', self.model.cid);
735 + this.trigger('theme:next', this.model.cid);
754 736 return false;
755 737 },
756 738
757 739 previousTheme: function () {
758 - let self = this;
759 - self.trigger('theme:previous', self.model.cid);
740 + this.trigger('theme:previous', this.model.cid);
760 741 return false;
761 742 },
762 743
763 744 // Checks if the theme screenshot is the old 300px width version
@@ -857,9 +838,9 @@
857 838 // Controls the rendering of div.themes,
858 839 // a wrapper that will hold all the theme elements
859 840 themes.view.Themes = wp.Backbone.View.extend({
860 841
861 - className: 'themes ui four cards',
842 + className: 'themes ui three cards',
862 843 $overlay: $('div.theme-overlay'),
863 844
864 845 // Number to keep track of scroll position
865 846 // while in theme-overlay mode
@@ -871,9 +852,8 @@
871 852 // The live themes count
872 853 liveThemeCount: 0,
873 854
874 855 initialize: function (options) {
875 - let self = this;
876 856
877 857 // Set up parent
878 858 this.parent = options.parent;
879 859
@@ -880,61 +860,61 @@
880 860 // Set current view to [grid]
881 861 this.setView('grid');
882 862
883 863 // Move the active theme to the beginning of the collection
884 - self.currentTheme();
864 + this.currentTheme();
885 865
886 866 // When the collection is updated by user input...
887 - this.listenTo(self.collection, 'update', function () {
888 - self.parent.page = 0;
889 - self.currentTheme();
890 - self.render(this);
867 + this.listenTo(this.collection, 'update', () => {
868 + this.parent.page = 0;
869 + this.currentTheme();
870 + this.render(this);
891 871 });
892 872
893 873 // Update theme count to full result set when available.
894 - this.listenTo(self.collection, 'query:success', function (count) {
874 + this.listenTo(this.collection, 'query:success', (count) => {
895 875 if (_.isNumber(count)) {
896 - self.count.text(count);
897 - self.announceSearchResults(count);
876 + this.count.text(count);
877 + this.announceSearchResults(count);
898 878 } else {
899 - self.count.text(self.collection.length);
900 - self.announceSearchResults(self.collection.length);
879 + this.count.text(this.collection.length);
880 + this.announceSearchResults(this.collection.length);
901 881 }
902 882 });
903 883
904 - this.listenTo(self.collection, 'query:empty', function () {
884 + this.listenTo(this.collection, 'query:empty', () => {
905 885 $('body').addClass('no-results');
906 886 });
907 887
908 - this.listenTo(this.parent, 'theme:scroll', function () {
909 - self.renderThemes(self.parent.page);
888 + this.listenTo(this.parent, 'theme:scroll', () => {
889 + this.renderThemes(this.parent.page);
910 890 });
911 891
912 - this.listenTo(this.parent, 'theme:close', function () {
913 - if (self.overlay) {
914 - self.overlay.closeOverlay();
892 + this.listenTo(this.parent, 'theme:close', () => {
893 + if (this.overlay) {
894 + this.overlay.closeOverlay();
915 895 }
916 896 });
917 897
918 898 // Bind keyboard events.
919 - $('body').on('keyup', function (event) {
920 - if (!self.overlay) {
899 + $('body').on('keyup', (event) => {
900 + if (!this.overlay) {
921 901 return;
922 902 }
923 903
924 904 // Pressing the right arrow key fires a theme:next event
925 905 if (event.keyCode === 39) {
926 - self.overlay.nextTheme();
906 + this.overlay.nextTheme();
927 907 }
928 908
929 909 // Pressing the left arrow key fires a theme:previous event
930 910 if (event.keyCode === 37) {
931 - self.overlay.previousTheme();
911 + this.overlay.previousTheme();
932 912 }
933 913
934 914 // Pressing the escape key fires a theme:collapse event
935 915 if (event.keyCode === 27) {
936 - self.overlay.collapse(event);
916 + this.overlay.collapse(event);
937 917 }
938 918 });
939 919 },
940 920
@@ -976,15 +956,13 @@
976 956
977 957 // Iterates through each instance of the collection
978 958 // and renders each theme module
979 959 renderThemes: function (page) {
980 - let self = this;
981 960
982 - self.instance = self.collection.paginate(page);
961 + this.instance = this.collection.paginate(page);
983 962
984 963 // If we have no more themes bail
985 - if (self.instance.length === 0) {
986 - // Fire a no-more-themes event.
964 + if (this.instance.length === 0) {
987 965 this.parent.trigger('theme:end');
988 966 return;
989 967 }
990 968
@@ -993,27 +971,35 @@
993 971 $('.add-new-theme').remove();
994 972 }
995 973
996 974 // Loop through the themes and setup each theme view
997 - self.instance.each(function (theme) {
998 - self.theme = new themes.view.Theme({
975 + this.instance.each((theme) => {
976 +
977 + this.theme = new themes.view.Theme({
999 978 model: theme,
1000 - parent: self
979 + parent: this
1001 980 });
1002 981
1003 - // Render the views...
1004 - self.theme.render();
1005 - // and append them to div.themes
1006 - self.$el.append(self.theme.el);
982 + // Render the view
983 + this.theme.render();
1007 984
1008 - // Binds to theme:expand to show the modal box
1009 - // with the theme details
1010 - self.listenTo(self.theme, 'theme:expand', self.expand, self);
985 + // Append to container
986 + this.$el.append(this.theme.el);
987 +
988 + // Bind expand event
989 + this.listenTo(this.theme, 'theme:expand', this.expand);
1011 990 });
1012 991
1013 992 // 'Add new theme' element shown at the end of the grid
1014 993 if (themes.data.settings.canInstall) {
1015 - this.$el.append('<div class="theme add-new-theme"><a href="' + themes.data.settings.installURI + '"><div class="theme-screenshot"><span></span></div><h3 class="theme-name">' + l10n.addNew + '</h3></a></div>');
994 + this.$el.append(
995 + '<div class="theme add-new-theme">' +
996 + '<a href="' + themes.data.settings.installURI + '">' +
997 + '<div class="theme-screenshot"><span></span></div>' +
998 + '<h3 class="theme-name">' + l10n.addNew + '</h3>' +
999 + '</a>' +
1000 + '</div>'
1001 + );
1016 1002 }
1017 1003
1018 1004 this.parent.page++;
1019 1005 },
@@ -1019,17 +1005,14 @@
1019 1005 },
1020 1006
1021 1007 // Grabs current theme and puts it at the beginning of the collection
1022 1008 currentTheme: function () {
1023 - let self = this,
1024 - current;
1009 + const current = this.collection.findWhere({ active: true });
1025 1010
1026 - current = self.collection.findWhere({ active: true });
1027 -
1028 1011 // Move the active theme to the beginning of the collection
1029 1012 if (current) {
1030 - self.collection.remove(current);
1031 - self.collection.add(current, { at: 0 });
1013 + this.collection.remove(current);
1014 + this.collection.add(current, { at: 0 });
1032 1015 }
1033 1016 },
1034 1017
1035 1018 // Sets current view
@@ -1039,12 +1022,10 @@
1039 1022
1040 1023 // Renders the overlay with the ThemeDetails view
1041 1024 // Uses the current model data
1042 1025 expand: function (id) {
1043 - let self = this;
1044 -
1045 1026 // Set the current theme model
1046 - this.model = self.collection.get(id);
1027 + this.model = this.collection.get(id);
1047 1028
1048 1029 // Trigger a route update for the current model
1049 1030 themes.router.navigate(themes.router.baseUrl(themes.router.themePath + this.model.id));
1050 1031
@@ -1053,9 +1034,9 @@
1053 1034 $('body').addClass('modal-open');
1054 1035
1055 1036 // Set up the theme details view
1056 1037 this.overlay = new themes.view.Details({
1057 - model: self.model
1038 + model: this.model
1058 1039 });
1059 1040
1060 1041 this.overlay.render();
1061 1042 this.$overlay.html(this.overlay.el);
@@ -1064,16 +1045,15 @@
1064 1045 // triggered by the arrow keys
1065 1046 //
1066 1047 // Keep track of the current model so we
1067 1048 // can infer an index position
1068 - this.listenTo(this.overlay, 'theme:next', function () {
1049 + this.listenTo(this.overlay, 'theme:next', () => {
1069 1050 // Renders the next theme on the overlay
1070 - self.next([self.model.cid]);
1071 -
1051 + this.next([this.model.cid]);
1072 1052 })
1073 - .listenTo(this.overlay, 'theme:previous', function () {
1053 + .listenTo(this.overlay, 'theme:previous', () => {
1074 1054 // Renders the previous theme on the overlay
1075 - self.previous([self.model.cid]);
1055 + this.previous([this.model.cid]);
1076 1056 });
1077 1057 },
1078 1058
1079 1059 // This method renders the next theme on the overlay modal
@@ -1079,15 +1059,14 @@
1079 1059 // This method renders the next theme on the overlay modal
1080 1060 // based on the current position in the collection
1081 1061 // @params [model cid]
1082 1062 next: function (args) {
1083 - let self = this,
1084 - model, nextModel;
1063 + let model, nextModel;
1085 1064
1086 1065 // Get the current theme
1087 - model = self.collection.get(args[0]);
1066 + model = this.collection.get(args[0]);
1088 1067 // Find the next model within the collection
1089 - nextModel = self.collection.at(self.collection.indexOf(model) + 1);
1068 + nextModel = this.collection.at(this.collection.indexOf(model) + 1);
1090 1069
1091 1070 // Sanity check which also serves as a boundary test
1092 1071 if (nextModel !== undefined) {
1093 1072
@@ -1095,9 +1074,9 @@
1095 1074 // Close the overlay
1096 1075 this.overlay.closeOverlay();
1097 1076
1098 1077 // Trigger a route update for the current model
1099 - self.theme.trigger('theme:expand', nextModel.cid);
1078 + this.theme.trigger('theme:expand', nextModel.cid);
1100 1079
1101 1080 }
1102 1081 },
1103 1082
@@ -1104,15 +1083,14 @@
1104 1083 // This method renders the previous theme on the overlay modal
1105 1084 // based on the current position in the collection
1106 1085 // @params [model cid]
1107 1086 previous: function (args) {
1108 - let self = this,
1109 - model, previousModel;
1087 + let model, previousModel;
1110 1088
1111 1089 // Get the current theme
1112 - model = self.collection.get(args[0]);
1090 + model = this.collection.get(args[0]);
1113 1091 // Find the previous model within the collection
1114 - previousModel = self.collection.at(self.collection.indexOf(model) - 1);
1092 + previousModel = this.collection.at(this.collection.indexOf(model) - 1);
1115 1093
1116 1094 if (previousModel !== undefined) {
1117 1095
1118 1096 // We have a new theme...
@@ -1119,9 +1097,9 @@
1119 1097 // Close the overlay
1120 1098 this.overlay.closeOverlay();
1121 1099
1122 1100 // Trigger a route update for the current model
1123 - self.theme.trigger('theme:expand', previousModel.cid);
1101 + this.theme.trigger('theme:expand', previousModel.cid);
1124 1102
1125 1103 }
1126 1104 },
1127 1105
@@ -1136,9 +1114,8 @@
1136 1114 });
1137 1115
1138 1116 // Search input view controller.
1139 1117 themes.view.Search = wp.Backbone.View.extend({
1140 -
1141 1118 tagName: 'input',
1142 1119 className: 'wp-filter-search fluid prompt',
1143 1120 id: 'wp-filter-search-input',
1144 1121 searching: false,
@@ -1144,9 +1121,9 @@
1144 1121 searching: false,
1145 1122
1146 1123
1147 1124 attributes: {
1148 - placeholder: __('Search themes...'),
1125 + placeholder: 'Search themes...',
1149 1126 type: 'text',
1150 1127 'aria-describedby': 'live-search-desc'
1151 1128 },
1152 1129
@@ -1273,27 +1250,25 @@
1273 1250 pushState: true,
1274 1251 hashChange: false
1275 1252 });
1276 1253 },
1254 + routes: function () {
1277 1255
1278 - routes: function () {
1279 - let self = this;
1280 - // Bind to our global thx object
1281 - // so that the object is available to sub-views
1256 + // Bind to our global themes object
1282 1257 themes.router = new themes.Router();
1283 1258
1284 1259 // Handles theme details route event
1285 - themes.router.on('route:theme', function (slug) {
1286 - self.view.view.expand(slug);
1260 + themes.router.on('route:theme', (slug) => {
1261 + this.view.view.expand(slug);
1287 1262 });
1288 1263
1289 - themes.router.on('route:themes', function () {
1290 - self.themes.doSearch('');
1291 - self.view.trigger('theme:close');
1264 + themes.router.on('route:themes', () => {
1265 + this.themes.doSearch('');
1266 + this.view.trigger('theme:close');
1292 1267 });
1293 1268
1294 1269 // Handles search route event
1295 - themes.router.on('route:search', function () {
1270 + themes.router.on('route:search', () => {
1296 1271 $('.wp-filter-search').trigger('keyup');
1297 1272 });
1298 1273
1299 1274 this.extraRoutes();
@@ -1298,8 +1273,9 @@
1298 1273
1299 1274 this.extraRoutes();
1300 1275 },
1301 1276
1277 +
1302 1278 extraRoutes: function () {
1303 1279 return false;
1304 1280 }
1305 1281 };
@@ -1381,9 +1357,8 @@
1381 1357 },
1382 1358
1383 1359 // Initial render method
1384 1360 render: function () {
1385 - let self = this;
1386 1361
1387 1362 this.search();
1388 1363 this.uploader();
1389 1364
@@ -1389,22 +1364,22 @@
1389 1364
1390 1365 this.collection = new themes.Collection();
1391 1366
1392 1367 // Bump `collection.currentQuery.page` and request more themes if we hit the end of the page.
1393 - this.listenTo(this, 'theme:end', function () {
1368 + this.listenTo(this, 'theme:end', () => {
1394 1369
1395 1370 // Make sure we are not already loading
1396 - if (self.collection.loadingThemes) {
1371 + if (this.collection.loadingThemes) {
1397 1372 return;
1398 1373 }
1399 1374
1400 1375 // Set loadingThemes to true and bump page instance of currentQuery.
1401 - self.collection.loadingThemes = true;
1402 - self.collection.currentQuery.page++;
1376 + this.collection.loadingThemes = true;
1377 + this.collection.currentQuery.page++;
1403 1378
1404 1379 // Use currentQuery.page to build the themes request.
1405 - _.extend(self.collection.currentQuery.request, { page: self.collection.currentQuery.page });
1406 - self.collection.query(self.collection.currentQuery.request);
1380 + _.extend(this.collection.currentQuery.request, { page: this.collection.currentQuery.page });
1381 + this.collection.query(this.collection.currentQuery.request);
1407 1382 });
1408 1383
1409 1384 this.listenTo(this.collection, 'query:success', function () {
1410 1385 $('body').removeClass('loading-content');
@@ -1563,20 +1538,23 @@
1563 1538
1564 1539 uploader: function () {
1565 1540 $('a.upload').on('click', function (event) {
1566 1541 event.preventDefault();
1567 - $('body').addClass('show-upload-theme');
1542 + $('.mainwp-bulk-install-showhide-content').hide();
1543 + $('.mainwp-upload-theme').show();
1568 1544 themes.router.navigate(themes.router.baseUrl('&upload'), { replace: true });
1569 - $(this).addClass('mainwp_action_down');
1570 - $('a.browse-themes').removeClass('mainwp_action_down');
1545 + $('a.mainwp-bulk-install-tabs-header-btn').removeClass('green');
1546 + $(this).addClass('green');
1571 1547 $('#mainwp_theme_bulk_install_btn').attr('bulk-action', 'upload');
1572 1548 });
1573 1549 $('a.browse-themes').on('click', function (event) {
1574 1550 event.preventDefault();
1575 - $('body').removeClass('show-upload-theme');
1551 + $('.mainwp-bulk-install-showhide-content').hide();
1552 + $('#mainwp-search-themes-input-container').show();
1553 + $('#theme-filter').show();
1576 1554 themes.router.navigate(themes.router.baseUrl(''), { replace: true });
1577 - $(this).addClass('mainwp_action_down');
1578 - $('a.upload').removeClass('mainwp_action_down');
1555 + $('a.mainwp-bulk-install-tabs-header-btn').removeClass('green');
1556 + $(this).addClass('green');
1579 1557 $('#mainwp_theme_bulk_install_btn').attr('bulk-action', 'install');
1580 1558 });
1581 1559 },
1582 1560
@@ -1602,16 +1580,14 @@
1602 1580
1603 1581 // Clears all the checked filters
1604 1582 // @uses filtersChecked()
1605 1583 clearFilters: function (event) {
1606 - let items = $('.filter-group').find(':checkbox'),
1607 - self = this;
1608 -
1584 + let items = $('.filter-group').find(':checkbox')
1609 1585 event.preventDefault();
1610 1586
1611 - _.each(items.filter(':checked'), function (item) {
1587 + _.each(items.filter(':checked'), (item) => {
1612 1588 $(item).prop('checked', false);
1613 - return self.filtersChecked();
1589 + return this.filtersChecked();
1614 1590 });
1615 1591 },
1616 1592
1617 1593 backToFilters: function (event) {
@@ -1684,10 +1660,9 @@
1684 1660 });
1685 1661 },
1686 1662
1687 1663 routes: function () {
1688 - let self = this,
1689 - request = {};
1664 + let request = {};
1690 1665
1691 1666 // Bind to our global `wp.themes` object
1692 1667 // so that the router is available to sub-views
1693 1668 themes.router = new themes.InstallerRouter();
@@ -1693,22 +1668,23 @@
1693 1668 themes.router = new themes.InstallerRouter();
1694 1669
1695 1670 // Handles `theme` route event
1696 1671 // Queries the API for the passed theme slug
1697 - themes.router.on('route:preview', function (slug) {
1672 + themes.router.on('route:preview', (slug) => {
1698 1673 request.theme = slug;
1699 - self.view.collection.query(request);
1674 + this.view.collection.query(request);
1700 1675 });
1701 1676
1702 1677 // Handles sorting / browsing routes
1703 1678 // Also handles the root URL triggering a sort request
1704 1679 // for `featured`, the default view
1705 - themes.router.on('route:sort', function (sort) {
1680 + themes.router.on('route:sort', (sort) => {
1706 1681 if (!sort) {
1707 1682 sort = 'featured';
1708 1683 }
1709 - self.view.sort(sort);
1710 - self.view.trigger('theme:close');
1684 +
1685 + this.view.sort(sort);
1686 + this.view.trigger('theme:close');
1711 1687 });
1712 1688
1713 1689 // Support the `upload` route by going straight to upload section
1714 1690 themes.router.on('route:upload', function () {
@@ -1744,29 +1720,33 @@
1744 1720 })(jQuery);
1745 1721
1746 1722 // Align theme browser thickbox
1747 1723 jQuery(function($) {
1748 - window.tb_position = function () {
1724 +
1725 + globalThis.tb_position = function () {
1749 1726 let tbWindow = $('#TB_window'),
1750 - width = $(window).width(),
1751 - H = $(window).height(),
1752 - W = (1040 < width) ? 1040 : width,
1727 + width = $(globalThis).width(),
1728 + H = $(globalThis).height(),
1729 + W = Math.min(1040, width),
1753 1730 adminbar_height = 0;
1754 1731
1755 1732 if ($('#wpadminbar').length) {
1756 - adminbar_height = parseInt($('#wpadminbar').css('height'), 10);
1733 + adminbar_height = Number.parseInt($('#wpadminbar').css('height'), 10);
1757 1734 }
1758 1735
1759 1736 if (tbWindow.length) {
1760 1737 tbWindow.width(W - 50).height(H - 45 - adminbar_height);
1761 1738 $('#TB_iframeContent').width(W - 50).height(H - 75 - adminbar_height);
1762 - tbWindow.css({ 'margin-left': '-' + parseInt(((W - 50) / 2), 10) + 'px' });
1763 - if (typeof document.body.style.maxWidth !== 'undefined') {
1764 - tbWindow.css({ 'top': 20 + adminbar_height + 'px', 'margin-top': '0' });
1739 + tbWindow.css({ 'margin-left': '-' + Number.parseInt(((W - 50) / 2), 10) + 'px' });
1740 + if ('maxWidth' in document.body.style) {
1741 + tbWindow.css({
1742 + top: `${20 + adminbar_height}px`,
1743 + marginTop: 0
1744 + });
1765 1745 }
1766 1746 }
1767 1747 };
1768 1748
1769 - $(window).on('resize', function () {
1770 - window.tb_position();
1749 + $(globalThis).on('resize', function () {
1750 + globalThis.tb_position();
1771 1751 });
1772 1752 });