PluginProbe
WebberZone Top 10 — Popular Posts / 4.5.2
WebberZone Top 10 — Popular Posts v4.5.2
4.5.2 4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 All 118 releases
← All changes | includes/admin/settings/js/settings-admin-scripts.js +277 -16 4.3.2 → 4.5.2 View file →
@@ -1,7 +1,7 @@
1 1 jQuery(document).ready(function ($) {
2 2
3 - const prefix = WZSettingsAdmin.prefix || 'wz';
3 + const prefix = WebberSettingsAdmin.prefix || 'wz';
4 4
5 5 // File browser.
6 6 $('.file-browser').on('click', function (event) {
7 7 event.preventDefault();
@@ -33,12 +33,264 @@
33 33 },
34 34 activate: function (event, ui) {
35 35 $(ui.oldTab.find("a")).removeClass("nav-tab-active");
36 36 $(ui.newTab.find("a")).addClass("nav-tab-active");
37 + window.scrollTo({ top: 0, behavior: 'smooth' });
37 38 }
38 39 });
39 40 });
40 41
42 + // Settings search: live-filters setting rows across all tabs.
43 + (function () {
44 + var $container = $('#post-body-content');
45 + var $searchInput = $('#' + prefix + '-settings-search');
46 + var $form = $('#' + prefix + '-settings-form');
47 +
48 + if (!$searchInput.length || !$form.length || !$container.length) {
49 + return;
50 + }
51 +
52 + var $panels = $form.children('div[id]');
53 + var $navLinks = $container.find('> ul.nav-tab-wrapper a.nav-tab');
54 + var $clearButton = $container.find('.wz-settings-search-clear');
55 + var $status = $container.find('.wz-settings-search-status');
56 + var strings = (typeof WebberSettingsAdmin !== 'undefined' && WebberSettingsAdmin.strings) || {};
57 + var $noResults = null;
58 + var $actionsBar = null;
59 + var indexBuilt = false;
60 + var debounceTimer = null;
61 +
62 + function getRows($panel) {
63 + return $panel.children('table.form-table').find('> tbody > tr, > tr');
64 + }
65 +
66 + // Build a searchable text string per row once, on first search.
67 + // Strips noise (select options, dropdown widgets, code editors) and adds input ids/names.
68 + function buildIndex() {
69 + $panels.each(function () {
70 + getRows($(this)).each(function () {
71 + var $row = $(this);
72 + var $clone = $row.clone();
73 + $clone.find('option, script, style, template, .ts-dropdown, .CodeMirror').remove();
74 + var text = $clone.text() + ' ';
75 + $row.find(':input[id], :input[name]').each(function () {
76 + text += ' ' + (this.id || '') + ' ' + (this.name || '');
77 + });
78 + $row.data('wzSearchText', text.toLowerCase());
79 + });
80 + });
81 + indexBuilt = true;
82 + }
83 +
84 + function clearHighlights() {
85 + $form.find('mark.wz-search-mark').each(function () {
86 + var parent = this.parentNode;
87 + $(this).replaceWith(document.createTextNode($(this).text()));
88 + parent.normalize();
89 + });
90 + }
91 +
92 + // Elements the highlighter must never descend into.
93 + var highlightSkip = 'input, textarea, select, button, script, style, template, mark, .CodeMirror, .ts-wrapper, .wp-picker-container, .wz-repeater-wrapper';
94 +
95 + // Wrap the first occurrence of query in each matching text node with <mark>.
96 + function highlightTerm($el, query) {
97 + $el.contents().each(function () {
98 + if (3 === this.nodeType) {
99 + var text = this.nodeValue;
100 + var idx = text.toLowerCase().indexOf(query);
101 + if (-1 !== idx) {
102 + var matched = text.slice(idx, idx + query.length);
103 + var afterNode = document.createTextNode(text.slice(idx + query.length));
104 + var mark = $('<mark class="wz-search-mark"></mark>').text(matched);
105 + this.nodeValue = text.slice(0, idx);
106 + $(this).after(afterNode).after(mark);
107 + }
108 + } else if (1 === this.nodeType && !$(this).is(highlightSkip)) {
109 + highlightTerm($(this), query);
110 + }
111 + });
112 + }
113 +
114 + function updateTabBadge(panelId, count) {
115 + var $link = $navLinks.filter('[href="#' + panelId + '"]');
116 + if (!$link.length) {
117 + return;
118 + }
119 + var $badge = $link.find('.wz-tab-count');
120 + if (0 === count) {
121 + $badge.remove();
122 + } else {
123 + if (!$badge.length) {
124 + $badge = $('<span class="wz-tab-count"><span class="wz-tab-count-number"></span><span class="screen-reader-text"></span></span>').appendTo($link);
125 + $badge.find('.screen-reader-text').text(' ' + (strings.search_matches_label || 'matching settings'));
126 + }
127 + $badge.find('.wz-tab-count-number').text(count);
128 + }
129 + $link.toggleClass('wz-tab-no-matches', 0 === count);
130 + }
131 +
132 + // Announce the result count to screen readers via the polite live region.
133 + function announceResults(total) {
134 + var template;
135 + if (0 === total) {
136 + template = strings.search_no_results || 'No settings found.';
137 + } else if (1 === total) {
138 + template = strings.search_results_single || '%d setting found.';
139 + } else {
140 + template = strings.search_results_plural || '%d settings found.';
141 + }
142 + $status.text(template.replace('%d', total));
143 + }
144 +
145 + // Single Save Changes bar shown while searching, replacing the hidden per-tab button rows.
146 + function toggleActionsBar(show) {
147 + if (show && !$actionsBar) {
148 + var $save = $form.find('input[type="submit"][name="submit"]').first().clone().removeAttr('id');
149 + if (!$save.length) {
150 + return;
151 + }
152 + $actionsBar = $('<p class="wz-search-actions"></p>').append($save).appendTo($form);
153 + }
154 + if ($actionsBar) {
155 + $actionsBar.toggle(show);
156 + }
157 + }
158 +
159 + function toggleNoResults(show) {
160 + if (show && !$noResults) {
161 + $noResults = $('<p class="wz-search-no-results"></p>')
162 + .text(strings.search_no_results || 'No settings found.')
163 + .appendTo($form);
164 + }
165 + if ($noResults) {
166 + $noResults.toggle(show);
167 + }
168 + }
169 +
170 + function resetSearch() {
171 + $container.removeClass('wz-searching');
172 + clearHighlights();
173 + $form.find('.wz-search-hidden').removeClass('wz-search-hidden');
174 + $form.find('.wz-search-match').removeClass('wz-search-match');
175 + $panels.removeClass('wz-has-matches');
176 + $navLinks.removeClass('wz-tab-no-matches').find('.wz-tab-count').remove();
177 + toggleNoResults(false);
178 + toggleActionsBar(false);
179 + $clearButton.prop('hidden', true);
180 + $status.text('');
181 + }
182 +
183 + function applySearch() {
184 + var query = $.trim($searchInput.val()).toLowerCase();
185 +
186 + if (!query) {
187 + resetSearch();
188 + return;
189 + }
190 +
191 + if (!indexBuilt) {
192 + buildIndex();
193 + }
194 +
195 + clearHighlights();
196 + $container.addClass('wz-searching');
197 +
198 + var total = 0;
199 +
200 + $panels.each(function () {
201 + var $panel = $(this);
202 + var $rows = getRows($panel);
203 + var count = 0;
204 +
205 + $rows.each(function () {
206 + var $row = $(this);
207 + var matched = -1 !== ($row.data('wzSearchText') || '').indexOf(query);
208 + $row.toggleClass('wz-search-match', matched).toggleClass('wz-search-hidden', !matched);
209 + if (matched) {
210 + count++;
211 + }
212 + });
213 +
214 + // Keep a section header visible when any row in its group matched.
215 + $rows.filter('.wz-settings-header-row').each(function () {
216 + var $header = $(this);
217 + if ($header.hasClass('wz-search-match')) {
218 + return;
219 + }
220 + var groupHasMatch = $header.nextUntil('.wz-settings-header-row').filter('.wz-search-match').length > 0;
221 + if (groupHasMatch) {
222 + $header.removeClass('wz-search-hidden');
223 + }
224 + });
225 +
226 + $panel.toggleClass('wz-has-matches', count > 0);
227 + updateTabBadge($panel.attr('id'), count);
228 + total += count;
229 + });
230 +
231 + // Highlight the matched term in the visible rows (labels and descriptions).
232 + $form.find('tr.wz-search-match').children('th, td').each(function () {
233 + highlightTerm($(this), query);
234 + });
235 +
236 + toggleNoResults(0 === total);
237 + toggleActionsBar(total > 0);
238 + $clearButton.prop('hidden', false);
239 + announceResults(total);
240 + }
241 +
242 + // 'search' also fires when the native clear (x) button is used.
243 + $searchInput.on('input search', function () {
244 + clearTimeout(debounceTimer);
245 + debounceTimer = setTimeout(applySearch, 200);
246 + });
247 +
248 + $searchInput.on('keydown', function (e) {
249 + if ('Escape' === e.key) {
250 + $(this).val('');
251 + applySearch();
252 + }
253 + });
254 +
255 + // Clear button: reset the search and return focus to the input.
256 + $clearButton.on('click', function () {
257 + $searchInput.val('');
258 + applySearch();
259 + $searchInput.trigger('focus');
260 + });
261 +
262 + // While searching, tab clicks scroll to that tab's results instead of switching tabs.
263 + // Capture-phase listener so it runs before, and blocks, the jQuery UI Tabs handlers.
264 + var navWrapper = $container.find('> ul.nav-tab-wrapper').get(0);
265 + if (navWrapper) {
266 + navWrapper.addEventListener(
267 + 'click',
268 + function (e) {
269 + if (!$container.hasClass('wz-searching')) {
270 + return;
271 + }
272 + var link = e.target.closest ? e.target.closest('a.nav-tab') : null;
273 + if (!link) {
274 + return;
275 + }
276 + e.preventDefault();
277 + e.stopPropagation();
278 + var $panel = $(link.getAttribute('href'));
279 + if ($panel.hasClass('wz-has-matches')) {
280 + // Move focus to the section heading for keyboard/screen-reader users.
281 + var title = $panel.find('.wz-section-title').get(0);
282 + if (title) {
283 + title.focus({ preventScroll: true });
284 + }
285 + window.scrollTo({ top: $panel.offset().top - 80, behavior: 'smooth' });
286 + }
287 + },
288 + true
289 + );
290 + }
291 + })();
292 +
41 293 // Initialize ColorPicker.
42 294 $('.color-field').each(function (i, element) {
43 295 $(element).wpColorPicker();
44 296 });
@@ -44,13 +296,13 @@
44 296 });
45 297
46 298 // Reset default thumbnail - uses plugin-specific localized data.
47 299 $('.reset-default-thumb').on('click', function () {
48 - var settingsKey = WZSettingsAdmin.settings_key || '';
49 - var thumbDefault = (typeof window[WZSettingsAdmin.prefix + '_admin'] !== 'undefined')
50 - ? window[WZSettingsAdmin.prefix + '_admin'].thumb_default
300 + var settingsKey = WebberSettingsAdmin.settings_key || '';
301 + var thumbDefault = (typeof window[WebberSettingsAdmin.prefix + '_admin'] !== 'undefined')
302 + ? window[WebberSettingsAdmin.prefix + '_admin'].thumb_default
51 303 : '';
52 - $('#' + settingsKey + '\\[thumb_default\\]').val(thumbDefault);
304 + $('#' + settingsKey + '-thumb_default').val(thumbDefault);
53 305 });
54 306
55 307 // Reset formmodified on submit.
56 308 $('#' + prefix + '-settings-form').on('submit', function () {
@@ -90,12 +342,16 @@
90 342 template = template.replace(/{{ROW_ID}}/g, uniqueId);
91 343 itemsContainer.append(template);
92 344 index++;
93 345 var newItem = itemsContainer.find('.wz-repeater-item:last');
94 - itemsContainer.find('.repeater-item-header:last .toggle-icon').text('\u25b2');
95 - itemsContainer.find('.repeater-item-content:last').css('display', 'block');
96 - if (window.WZInitTomSelect) {
97 - window.WZInitTomSelect(newItem.get(0));
346 + itemsContainer.find('.repeater-item-header:last')
347 + .attr('aria-expanded', 'true')
348 + .find('.toggle-icon').text('\u25b2');
349 + itemsContainer.find('.repeater-item-content:last')
350 + .attr('aria-hidden', 'false')
351 + .css('display', 'block');
352 + if (window.WebberInitTomSelect) {
353 + window.WebberInitTomSelect(newItem.get(0));
98 354 }
99 355 document.dispatchEvent(new CustomEvent('wz:repeater-item-added', { detail: { container: newItem.get(0) } }));
100 356 });
101 357
@@ -125,17 +381,22 @@
125 381 }
126 382 });
127 383
128 384 // Toggle Accordion.
129 - wrapper.on('click', '.repeater-item-header', function () {
130 - var $this = $(this);
131 - var $toggleIcon = $this.find('.toggle-icon');
132 - var $content = $this.next('.repeater-item-content');
133 - if ($content.is(':visible')) {
134 - $content.slideUp();
385 + wrapper.on('click', '.repeater-item-header', function (e) {
386 + e.preventDefault();
387 + e.stopImmediatePropagation();
388 + var $button = $(this);
389 + var $toggleIcon = $button.find('.toggle-icon');
390 + var $content = $button.next('.repeater-item-content');
391 + var isExpanded = 'true' === $button.attr('aria-expanded');
392 + if (isExpanded) {
393 + $button.attr('aria-expanded', 'false');
394 + $content.attr('aria-hidden', 'true').stop(true, true).hide();
135 395 $toggleIcon.text('\u25bc');
136 396 } else {
137 - $content.slideDown();
397 + $button.attr('aria-expanded', 'true');
398 + $content.attr('aria-hidden', 'false').stop(true, true).show();
138 399 $toggleIcon.text('\u25b2');
139 400 }
140 401 });
141 402