at path:ROOT / wp-admin / js / common.js
run:R W Run
DIR
2026-03-11 16:18:51
R W Run
2.86 KB
2026-03-11 16:18:51
R W Run
758 By
2026-03-11 16:18:51
R W Run
6.24 KB
2026-03-11 16:18:51
R W Run
2.95 KB
2026-03-11 16:18:51
R W Run
5.66 KB
2026-03-11 16:18:51
R W Run
2.04 KB
2026-03-11 16:18:51
R W Run
11.32 KB
2026-03-11 16:18:51
R W Run
3.01 KB
2026-03-11 16:18:51
R W Run
9.54 KB
2026-03-11 16:18:51
R W Run
3.4 KB
2026-03-11 16:18:51
R W Run
2.85 KB
2026-03-11 16:18:51
R W Run
1.28 KB
2026-03-11 16:18:51
R W Run
61.15 KB
2026-03-11 16:18:51
R W Run
23.12 KB
2026-03-11 16:18:51
R W Run
3.35 KB
2026-03-11 16:18:51
R W Run
1.18 KB
2026-03-11 16:18:51
R W Run
1.98 KB
2026-03-11 16:18:51
R W Run
288.41 KB
2026-03-11 16:18:51
R W Run
109.69 KB
2026-03-11 16:18:51
R W Run
111.46 KB
2026-03-11 16:18:51
R W Run
47.14 KB
2026-03-11 16:18:51
R W Run
70.05 KB
2026-03-11 16:18:51
R W Run
27.41 KB
2026-03-11 16:18:51
R W Run
27.02 KB
2026-03-11 16:18:51
R W Run
8.65 KB
2026-03-11 16:18:51
R W Run
37.12 KB
2026-03-11 16:18:51
R W Run
15.13 KB
2026-03-11 16:18:51
R W Run
41.61 KB
2026-03-11 16:18:51
R W Run
13.14 KB
2026-03-11 16:18:51
R W Run
44 KB
2026-03-11 16:18:51
R W Run
12.78 KB
2026-03-11 16:18:51
R W Run
7.67 KB
2026-03-11 16:18:51
R W Run
5.41 KB
2026-03-11 16:18:51
R W Run
3.65 KB
2026-03-11 16:18:51
R W Run
39.98 KB
2026-03-11 16:18:51
R W Run
15.15 KB
2026-03-11 16:18:51
R W Run
20.17 KB
2026-03-11 16:18:51
R W Run
9.41 KB
2026-03-11 16:18:51
R W Run
7.61 KB
2026-03-11 16:18:51
R W Run
2.93 KB
2026-03-11 16:18:51
R W Run
23.09 KB
2026-03-11 16:18:51
R W Run
890 By
2026-03-11 16:18:51
R W Run
423 By
2026-03-11 16:18:51
R W Run
3.89 KB
2026-03-11 16:18:51
R W Run
1.7 KB
2026-03-11 16:18:51
R W Run
1.27 KB
2026-03-11 16:18:51
R W Run
611 By
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
1.13 KB
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
2.38 KB
2026-03-11 16:18:51
R W Run
61.15 KB
2026-03-11 16:18:51
R W Run
30.06 KB
2026-03-11 16:18:51
R W Run
4.14 KB
2026-03-11 16:18:51
R W Run
1.1 KB
2026-03-11 16:18:51
R W Run
1.31 KB
2026-03-11 16:18:51
R W Run
847 By
2026-03-11 16:18:51
R W Run
6.92 KB
2026-03-11 16:18:51
R W Run
2.35 KB
2026-03-11 16:18:51
R W Run
38.68 KB
2026-03-11 16:18:51
R W Run
18.4 KB
2026-03-11 16:18:51
R W Run
18.49 KB
2026-03-11 16:18:51
R W Run
6.6 KB
2026-03-11 16:18:51
R W Run
10.67 KB
2026-03-11 16:18:51
R W Run
5.03 KB
2026-03-11 16:18:51
R W Run
33.92 KB
2026-03-11 16:18:51
R W Run
17.97 KB
2026-03-11 16:18:51
R W Run
876 By
2026-03-11 16:18:51
R W Run
620 By
2026-03-11 16:18:51
R W Run
13.15 KB
2026-03-11 16:18:51
R W Run
6.13 KB
2026-03-11 16:18:51
R W Run
6.1 KB
2026-03-11 16:18:51
R W Run
2.2 KB
2026-03-11 16:18:51
R W Run
3.2 KB
2026-03-11 16:18:51
R W Run
1.53 KB
2026-03-11 16:18:51
R W Run
10.88 KB
2026-03-11 16:18:51
R W Run
3 KB
2026-03-11 16:18:51
R W Run
5.64 KB
2026-03-11 16:18:51
R W Run
2.22 KB
2026-03-11 16:18:51
R W Run
5.96 KB
2026-03-11 16:18:51
R W Run
2.41 KB
2026-03-11 16:18:51
R W Run
24.77 KB
2026-03-11 16:18:51
R W Run
11.43 KB
2026-03-11 16:18:51
R W Run
54.94 KB
2026-03-11 16:18:51
R W Run
26.51 KB
2026-03-11 16:18:51
R W Run
109.37 KB
2026-03-11 16:18:51
R W Run
47.31 KB
2026-03-11 16:18:51
R W Run
17.91 KB
2026-03-11 16:18:51
R W Run
7.81 KB
2026-03-11 16:18:51
R W Run
2.25 KB
2026-03-11 16:18:51
R W Run
676 By
2026-03-11 16:18:51
R W Run
22.56 KB
2026-03-11 16:18:51
R W Run
12.31 KB
2026-03-11 16:18:51
R W Run
7.52 KB
2026-03-11 16:18:51
R W Run
1.49 KB
2026-03-11 16:18:51
R W Run
740 By
2026-03-11 16:18:51
R W Run
458 By
2026-03-11 16:18:51
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})();
2357
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1