|
1 /** |
|
2 * @output wp-admin/js/common.js |
|
3 */ |
|
4 |
1 /* global setUserSetting, ajaxurl, commonL10n, alert, confirm, pagenow */ |
5 /* global setUserSetting, ajaxurl, commonL10n, alert, confirm, pagenow */ |
2 var showNotice, adminMenu, columns, validateForm, screenMeta; |
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 */ |
3 ( function( $, window, undefined ) { |
15 ( function( $, window, undefined ) { |
4 var $document = $( document ), |
16 var $document = $( document ), |
5 $window = $( window ), |
17 $window = $( window ), |
6 $body = $( document.body ); |
18 $body = $( document.body ); |
7 |
19 |
8 // Removed in 3.3. |
20 /** |
9 // (perhaps) needed for back-compat |
21 * Removed in 3.3.0, needed for back-compatibility. |
10 adminMenu = { |
22 * |
|
23 * @since 2.7.0 |
|
24 * @deprecated 3.3.0 |
|
25 */ |
|
26 window.adminMenu = { |
11 init : function() {}, |
27 init : function() {}, |
12 fold : function() {}, |
28 fold : function() {}, |
13 restoreMenuState : function() {}, |
29 restoreMenuState : function() {}, |
14 toggle : function() {}, |
30 toggle : function() {}, |
15 favorites : function() {} |
31 favorites : function() {} |
16 }; |
32 }; |
17 |
33 |
18 // show/hide/save table columns |
34 // Show/hide/save table columns. |
19 columns = { |
35 window.columns = { |
|
36 |
|
37 /** |
|
38 * Initializes the column toggles in the screen options. |
|
39 * |
|
40 * Binds an onClick event to the checkboxes to show or hide the table columns |
|
41 * based on their toggled state. And persists the toggled state. |
|
42 * |
|
43 * @since 2.7.0 |
|
44 * |
|
45 * @returns {void} |
|
46 */ |
20 init : function() { |
47 init : function() { |
21 var that = this; |
48 var that = this; |
22 $('.hide-column-tog', '#adv-settings').click( function() { |
49 $('.hide-column-tog', '#adv-settings').click( function() { |
23 var $t = $(this), column = $t.val(); |
50 var $t = $(this), column = $t.val(); |
24 if ( $t.prop('checked') ) |
51 if ( $t.prop('checked') ) |
28 |
55 |
29 columns.saveManageColumnsState(); |
56 columns.saveManageColumnsState(); |
30 }); |
57 }); |
31 }, |
58 }, |
32 |
59 |
|
60 /** |
|
61 * Saves the toggled state for the columns. |
|
62 * |
|
63 * Saves whether the columns should be shown or hidden on a page. |
|
64 * |
|
65 * @since 3.0.0 |
|
66 * |
|
67 * @returns {void} |
|
68 */ |
33 saveManageColumnsState : function() { |
69 saveManageColumnsState : function() { |
34 var hidden = this.hidden(); |
70 var hidden = this.hidden(); |
35 $.post(ajaxurl, { |
71 $.post(ajaxurl, { |
36 action: 'hidden-columns', |
72 action: 'hidden-columns', |
37 hidden: hidden, |
73 hidden: hidden, |
38 screenoptionnonce: $('#screenoptionnonce').val(), |
74 screenoptionnonce: $('#screenoptionnonce').val(), |
39 page: pagenow |
75 page: pagenow |
40 }); |
76 }); |
41 }, |
77 }, |
42 |
78 |
|
79 /** |
|
80 * Makes a column visible and adjusts the column span for the table. |
|
81 * |
|
82 * @since 3.0.0 |
|
83 * @param {string} column The column name. |
|
84 * |
|
85 * @returns {void} |
|
86 */ |
43 checked : function(column) { |
87 checked : function(column) { |
44 $('.column-' + column).removeClass( 'hidden' ); |
88 $('.column-' + column).removeClass( 'hidden' ); |
45 this.colSpanChange(+1); |
89 this.colSpanChange(+1); |
46 }, |
90 }, |
47 |
91 |
|
92 /** |
|
93 * Hides a column and adjusts the column span for the table. |
|
94 * |
|
95 * @since 3.0.0 |
|
96 * @param {string} column The column name. |
|
97 * |
|
98 * @returns {void} |
|
99 */ |
48 unchecked : function(column) { |
100 unchecked : function(column) { |
49 $('.column-' + column).addClass( 'hidden' ); |
101 $('.column-' + column).addClass( 'hidden' ); |
50 this.colSpanChange(-1); |
102 this.colSpanChange(-1); |
51 }, |
103 }, |
52 |
104 |
|
105 /** |
|
106 * Gets all hidden columns. |
|
107 * |
|
108 * @since 3.0.0 |
|
109 * |
|
110 * @returns {string} The hidden column names separated by a comma. |
|
111 */ |
53 hidden : function() { |
112 hidden : function() { |
54 return $( '.manage-column[id]' ).filter( ':hidden' ).map(function() { |
113 return $( '.manage-column[id]' ).filter( '.hidden' ).map(function() { |
55 return this.id; |
114 return this.id; |
56 }).get().join( ',' ); |
115 }).get().join( ',' ); |
57 }, |
116 }, |
58 |
117 |
|
118 /** |
|
119 * Gets the checked column toggles from the screen options. |
|
120 * |
|
121 * @since 3.0.0 |
|
122 * |
|
123 * @returns {string} String containing the checked column names. |
|
124 */ |
59 useCheckboxesForHidden : function() { |
125 useCheckboxesForHidden : function() { |
60 this.hidden = function(){ |
126 this.hidden = function(){ |
61 return $('.hide-column-tog').not(':checked').map(function() { |
127 return $('.hide-column-tog').not(':checked').map(function() { |
62 var id = this.id; |
128 var id = this.id; |
63 return id.substring( id, id.length - 5 ); |
129 return id.substring( id, id.length - 5 ); |
64 }).get().join(','); |
130 }).get().join(','); |
65 }; |
131 }; |
66 }, |
132 }, |
67 |
133 |
|
134 /** |
|
135 * Adjusts the column span for the table. |
|
136 * |
|
137 * @since 3.1.0 |
|
138 * |
|
139 * @param {int} diff The modifier for the column span. |
|
140 */ |
68 colSpanChange : function(diff) { |
141 colSpanChange : function(diff) { |
69 var $t = $('table').find('.colspanchange'), n; |
142 var $t = $('table').find('.colspanchange'), n; |
70 if ( !$t.length ) |
143 if ( !$t.length ) |
71 return; |
144 return; |
72 n = parseInt( $t.attr('colspan'), 10 ) + diff; |
145 n = parseInt( $t.attr('colspan'), 10 ) + diff; |
74 } |
147 } |
75 }; |
148 }; |
76 |
149 |
77 $document.ready(function(){columns.init();}); |
150 $document.ready(function(){columns.init();}); |
78 |
151 |
79 validateForm = function( form ) { |
152 /** |
|
153 * Validates that the required form fields are not empty. |
|
154 * |
|
155 * @since 2.9.0 |
|
156 * |
|
157 * @param {jQuery} form The form to validate. |
|
158 * |
|
159 * @returns {boolean} Returns true if all required fields are not an empty string. |
|
160 */ |
|
161 window.validateForm = function( form ) { |
80 return !$( form ) |
162 return !$( form ) |
81 .find( '.form-required' ) |
163 .find( '.form-required' ) |
82 .filter( function() { return $( ':input:visible', this ).val() === ''; } ) |
164 .filter( function() { return $( ':input:visible', this ).val() === ''; } ) |
83 .addClass( 'form-invalid' ) |
165 .addClass( 'form-invalid' ) |
84 .find( ':input:visible' ) |
166 .find( ':input:visible' ) |
85 .change( function() { $( this ).closest( '.form-invalid' ).removeClass( 'form-invalid' ); } ) |
167 .change( function() { $( this ).closest( '.form-invalid' ).removeClass( 'form-invalid' ); } ) |
86 .length; |
168 .length; |
87 }; |
169 }; |
88 |
170 |
89 // stub for doing better warnings |
171 // stub for doing better warnings |
90 showNotice = { |
172 /** |
|
173 * Shows message pop-up notice or confirmation message. |
|
174 * |
|
175 * @since 2.7.0 |
|
176 * |
|
177 * @type {{warn: showNotice.warn, note: showNotice.note}} |
|
178 * |
|
179 * @returns {void} |
|
180 */ |
|
181 window.showNotice = { |
|
182 |
|
183 /** |
|
184 * Shows a delete confirmation pop-up message. |
|
185 * |
|
186 * @since 2.7.0 |
|
187 * |
|
188 * @returns {boolean} Returns true if the message is confirmed. |
|
189 */ |
91 warn : function() { |
190 warn : function() { |
92 var msg = commonL10n.warnDelete || ''; |
191 var msg = commonL10n.warnDelete || ''; |
93 if ( confirm(msg) ) { |
192 if ( confirm(msg) ) { |
94 return true; |
193 return true; |
95 } |
194 } |
96 |
195 |
97 return false; |
196 return false; |
98 }, |
197 }, |
99 |
198 |
|
199 /** |
|
200 * Shows an alert message. |
|
201 * |
|
202 * @since 2.7.0 |
|
203 * |
|
204 * @param text The text to display in the message. |
|
205 */ |
100 note : function(text) { |
206 note : function(text) { |
101 alert(text); |
207 alert(text); |
102 } |
208 } |
103 }; |
209 }; |
104 |
210 |
105 screenMeta = { |
211 /** |
|
212 * Represents the functions for the meta screen options panel. |
|
213 * |
|
214 * @since 3.2.0 |
|
215 * |
|
216 * @type {{element: null, toggles: null, page: null, init: screenMeta.init, |
|
217 * toggleEvent: screenMeta.toggleEvent, open: screenMeta.open, |
|
218 * close: screenMeta.close}} |
|
219 * |
|
220 * @returns {void} |
|
221 */ |
|
222 window.screenMeta = { |
106 element: null, // #screen-meta |
223 element: null, // #screen-meta |
107 toggles: null, // .screen-meta-toggle |
224 toggles: null, // .screen-meta-toggle |
108 page: null, // #wpcontent |
225 page: null, // #wpcontent |
109 |
226 |
|
227 /** |
|
228 * Initializes the screen meta options panel. |
|
229 * |
|
230 * @since 3.2.0 |
|
231 * |
|
232 * @returns {void} |
|
233 */ |
110 init: function() { |
234 init: function() { |
111 this.element = $('#screen-meta'); |
235 this.element = $('#screen-meta'); |
112 this.toggles = $( '#screen-meta-links' ).find( '.show-settings' ); |
236 this.toggles = $( '#screen-meta-links' ).find( '.show-settings' ); |
113 this.page = $('#wpcontent'); |
237 this.page = $('#wpcontent'); |
114 |
238 |
115 this.toggles.click( this.toggleEvent ); |
239 this.toggles.click( this.toggleEvent ); |
116 }, |
240 }, |
117 |
241 |
|
242 /** |
|
243 * Toggles the screen meta options panel. |
|
244 * |
|
245 * @since 3.2.0 |
|
246 * |
|
247 * @returns {void} |
|
248 */ |
118 toggleEvent: function() { |
249 toggleEvent: function() { |
119 var panel = $( '#' + $( this ).attr( 'aria-controls' ) ); |
250 var panel = $( '#' + $( this ).attr( 'aria-controls' ) ); |
120 |
251 |
121 if ( !panel.length ) |
252 if ( !panel.length ) |
122 return; |
253 return; |
125 screenMeta.close( panel, $(this) ); |
256 screenMeta.close( panel, $(this) ); |
126 else |
257 else |
127 screenMeta.open( panel, $(this) ); |
258 screenMeta.open( panel, $(this) ); |
128 }, |
259 }, |
129 |
260 |
|
261 /** |
|
262 * Opens the screen meta options panel. |
|
263 * |
|
264 * @since 3.2.0 |
|
265 * |
|
266 * @param {jQuery} panel The screen meta options panel div. |
|
267 * @param {jQuery} button The toggle button. |
|
268 * |
|
269 * @returns {void} |
|
270 */ |
130 open: function( panel, button ) { |
271 open: function( panel, button ) { |
131 |
272 |
132 $( '#screen-meta-links' ).find( '.screen-meta-toggle' ).not( button.parent() ).css( 'visibility', 'hidden' ); |
273 $( '#screen-meta-links' ).find( '.screen-meta-toggle' ).not( button.parent() ).css( 'visibility', 'hidden' ); |
133 |
274 |
134 panel.parent().show(); |
275 panel.parent().show(); |
|
276 |
|
277 /** |
|
278 * Sets the focus to the meta options panel and adds the necessary CSS classes. |
|
279 * |
|
280 * @since 3.2.0 |
|
281 * |
|
282 * @returns {void} |
|
283 */ |
135 panel.slideDown( 'fast', function() { |
284 panel.slideDown( 'fast', function() { |
136 panel.focus(); |
285 panel.focus(); |
137 button.addClass( 'screen-meta-active' ).attr( 'aria-expanded', true ); |
286 button.addClass( 'screen-meta-active' ).attr( 'aria-expanded', true ); |
138 }); |
287 }); |
139 |
288 |
140 $document.trigger( 'screen:options:open' ); |
289 $document.trigger( 'screen:options:open' ); |
141 }, |
290 }, |
142 |
291 |
|
292 /** |
|
293 * Closes the screen meta options panel. |
|
294 * |
|
295 * @since 3.2.0 |
|
296 * |
|
297 * @param {jQuery} panel The screen meta options panel div. |
|
298 * @param {jQuery} button The toggle button. |
|
299 * |
|
300 * @returns {void} |
|
301 */ |
143 close: function( panel, button ) { |
302 close: function( panel, button ) { |
|
303 /** |
|
304 * Hides the screen meta options panel. |
|
305 * |
|
306 * @since 3.2.0 |
|
307 * |
|
308 * @returns {void} |
|
309 */ |
144 panel.slideUp( 'fast', function() { |
310 panel.slideUp( 'fast', function() { |
145 button.removeClass( 'screen-meta-active' ).attr( 'aria-expanded', false ); |
311 button.removeClass( 'screen-meta-active' ).attr( 'aria-expanded', false ); |
146 $('.screen-meta-toggle').css('visibility', ''); |
312 $('.screen-meta-toggle').css('visibility', ''); |
147 panel.parent().hide(); |
313 panel.parent().hide(); |
148 }); |
314 }); |
327 adminbar: $adminbar.height(), |
496 adminbar: $adminbar.height(), |
328 menu: $adminMenuWrap.height() |
497 menu: $adminMenuWrap.height() |
329 }, |
498 }, |
330 $headerEnd = $( '.wp-header-end' ); |
499 $headerEnd = $( '.wp-header-end' ); |
331 |
500 |
332 |
501 /** |
333 // when the menu is folded, make the fly-out submenu header clickable |
502 * Makes the fly-out submenu header clickable, when the menu is folded. |
|
503 * |
|
504 * @param {Event} e The event object. |
|
505 * |
|
506 * @returns {void} |
|
507 */ |
334 $adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){ |
508 $adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){ |
335 $(e.target).parent().siblings('a').get(0).click(); |
509 $(e.target).parent().siblings('a').get(0).click(); |
336 }); |
510 }); |
337 |
511 |
|
512 /** |
|
513 * Collapses the admin menu. |
|
514 * |
|
515 * @returns {void} |
|
516 */ |
338 $( '#collapse-button' ).on( 'click.collapse-menu', function() { |
517 $( '#collapse-button' ).on( 'click.collapse-menu', function() { |
339 var viewportWidth = getViewportWidth() || 961; |
518 var viewportWidth = getViewportWidth() || 961; |
340 |
519 |
341 // reset any compensation for submenus near the bottom of the screen |
520 // reset any compensation for submenus near the bottom of the screen |
342 $('#adminmenu div.wp-submenu').css('margin-top', ''); |
521 $('#adminmenu div.wp-submenu').css('margin-top', ''); |
419 |
606 |
420 if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // touch screen device |
607 if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // touch screen device |
421 // iOS Safari works with touchstart, the rest work with click |
608 // iOS Safari works with touchstart, the rest work with click |
422 mobileEvent = isIOS ? 'touchstart' : 'click'; |
609 mobileEvent = isIOS ? 'touchstart' : 'click'; |
423 |
610 |
424 // close any open submenus when touch/click is not on the menu |
611 /** |
|
612 * Closes any open submenus when touch/click is not on the menu. |
|
613 * |
|
614 * @param {Event} e The event object. |
|
615 * |
|
616 * @returns {void} |
|
617 */ |
425 $body.on( mobileEvent+'.wp-mobile-hover', function(e) { |
618 $body.on( mobileEvent+'.wp-mobile-hover', function(e) { |
426 if ( $adminmenu.data('wp-responsive') ) { |
619 if ( $adminmenu.data('wp-responsive') ) { |
427 return; |
620 return; |
428 } |
621 } |
429 |
622 |
430 if ( ! $( e.target ).closest( '#adminmenu' ).length ) { |
623 if ( ! $( e.target ).closest( '#adminmenu' ).length ) { |
431 $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' ); |
624 $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' ); |
432 } |
625 } |
433 }); |
626 }); |
434 |
627 |
|
628 /** |
|
629 * Handles the opening or closing the submenu based on the mobile click|touch event. |
|
630 * |
|
631 * @param {Event} event The event object. |
|
632 * |
|
633 * @returns {void} |
|
634 */ |
435 $adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) { |
635 $adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) { |
436 var $menuItem = $(this).parent(); |
636 var $menuItem = $(this).parent(); |
437 |
637 |
438 if ( $adminmenu.data( 'wp-responsive' ) ) { |
638 if ( $adminmenu.data( 'wp-responsive' ) ) { |
439 return; |
639 return; |
482 timeout: 200, |
694 timeout: 200, |
483 sensitivity: 7, |
695 sensitivity: 7, |
484 interval: 90 |
696 interval: 90 |
485 }); |
697 }); |
486 |
698 |
|
699 /** |
|
700 * Opens the submenu on when focused on the menu item. |
|
701 * |
|
702 * @param {Event} event The event object. |
|
703 * |
|
704 * @returns {void} |
|
705 */ |
487 $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) { |
706 $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) { |
488 if ( $adminmenu.data( 'wp-responsive' ) ) { |
707 if ( $adminmenu.data( 'wp-responsive' ) ) { |
489 // The menu is in responsive mode, bail |
708 // The menu is in responsive mode, bail |
490 return; |
709 return; |
491 } |
710 } |
492 |
711 |
493 $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' ); |
712 $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' ); |
|
713 |
|
714 /** |
|
715 * Closes the submenu on blur from the menu item. |
|
716 * |
|
717 * @param {Event} event The event object. |
|
718 * |
|
719 * @returns {void} |
|
720 */ |
494 }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) { |
721 }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) { |
495 if ( $adminmenu.data( 'wp-responsive' ) ) { |
722 if ( $adminmenu.data( 'wp-responsive' ) ) { |
496 return; |
723 return; |
497 } |
724 } |
498 |
725 |
499 $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' ); |
726 $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' ); |
|
727 |
|
728 /** |
|
729 * Adjusts the size for the submenu. |
|
730 * |
|
731 * @returns {void} |
|
732 */ |
500 }).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() { |
733 }).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() { |
501 adjustSubmenu( $( this ) ); |
734 adjustSubmenu( $( this ) ); |
502 }); |
735 }); |
503 } |
736 } |
504 |
737 |
562 } |
807 } |
563 lastClicked = this; |
808 lastClicked = this; |
564 |
809 |
565 // Toggle the "Select all" checkboxes depending if the other ones are all checked or not. |
810 // Toggle the "Select all" checkboxes depending if the other ones are all checked or not. |
566 var unchecked = $(this).closest('tbody').find(':checkbox').filter(':visible:enabled').not(':checked'); |
811 var unchecked = $(this).closest('tbody').find(':checkbox').filter(':visible:enabled').not(':checked'); |
|
812 |
|
813 /** |
|
814 * Determines if all checkboxes are checked. |
|
815 * |
|
816 * @returns {boolean} Returns true if there are no unchecked checkboxes. |
|
817 */ |
567 $(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() { |
818 $(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() { |
568 return ( 0 === unchecked.length ); |
819 return ( 0 === unchecked.length ); |
569 }); |
820 }); |
570 |
821 |
571 return true; |
822 return true; |
572 }); |
823 }); |
573 |
824 |
574 // This event needs to be delegated. Ticket #37973. |
825 /** |
|
826 * Controls all the toggles on bulk toggle change. |
|
827 * |
|
828 * When the bulk checkbox is changed, all the checkboxes in the tables are changed accordingly. |
|
829 * When the shift-button is pressed while changing the bulk checkbox the checkboxes in the table are inverted. |
|
830 * |
|
831 * This event needs to be delegated. Ticket #37973. |
|
832 * |
|
833 * @param {Event} event The event object. |
|
834 * |
|
835 * @returns {boolean} |
|
836 */ |
575 $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) { |
837 $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) { |
576 var $this = $(this), |
838 var $this = $(this), |
577 $table = $this.closest( 'table' ), |
839 $table = $this.closest( 'table' ), |
578 controlChecked = $this.prop('checked'), |
840 controlChecked = $this.prop('checked'), |
579 toggle = event.shiftKey || $this.data('wp-toggle'); |
841 toggle = event.shiftKey || $this.data('wp-toggle'); |
580 |
842 |
581 $table.children( 'tbody' ).filter(':visible') |
843 $table.children( 'tbody' ).filter(':visible') |
582 .children().children('.check-column').find(':checkbox') |
844 .children().children('.check-column').find(':checkbox') |
|
845 /** |
|
846 * Updates the checked state on the checkbox in the table. |
|
847 * |
|
848 * @returns {boolean} True checks the checkbox, False unchecks the checkbox. |
|
849 */ |
583 .prop('checked', function() { |
850 .prop('checked', function() { |
584 if ( $(this).is(':hidden,:disabled') ) { |
851 if ( $(this).is(':hidden,:disabled') ) { |
585 return false; |
852 return false; |
586 } |
853 } |
587 |
854 |
634 setUserSetting('default_password_nag', 'hide'); |
911 setUserSetting('default_password_nag', 'hide'); |
635 $('div.default-password-nag').hide(); |
912 $('div.default-password-nag').hide(); |
636 return false; |
913 return false; |
637 }); |
914 }); |
638 |
915 |
639 // tab in textareas |
916 /** |
|
917 * Handles tab keypresses in theme and plugin editor textareas. |
|
918 * |
|
919 * @param {Event} e The event object. |
|
920 * |
|
921 * @returns {void} |
|
922 */ |
640 $('#newcontent').bind('keydown.wpevent_InsertTab', function(e) { |
923 $('#newcontent').bind('keydown.wpevent_InsertTab', function(e) { |
641 var el = e.target, selStart, selEnd, val, scroll, sel; |
924 var el = e.target, selStart, selEnd, val, scroll, sel; |
642 |
925 |
643 if ( e.keyCode == 27 ) { // escape key |
926 // After pressing escape key (keyCode: 27), the tab key should tab out of the textarea. |
|
927 if ( e.keyCode == 27 ) { |
644 // when pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them |
928 // when pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them |
645 e.preventDefault(); |
929 e.preventDefault(); |
646 $(el).data('tab-out', true); |
930 $(el).data('tab-out', true); |
647 return; |
931 return; |
648 } |
932 } |
649 |
933 |
650 if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey ) // tab key |
934 // Only listen for plain tab key (keyCode: 9) without any modifiers. |
|
935 if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey ) |
651 return; |
936 return; |
652 |
937 |
|
938 // After tabbing out, reset it so next time the tab key can be used again. |
653 if ( $(el).data('tab-out') ) { |
939 if ( $(el).data('tab-out') ) { |
654 $(el).data('tab-out', false); |
940 $(el).data('tab-out', false); |
655 return; |
941 return; |
656 } |
942 } |
657 |
943 |
658 selStart = el.selectionStart; |
944 selStart = el.selectionStart; |
659 selEnd = el.selectionEnd; |
945 selEnd = el.selectionEnd; |
660 val = el.value; |
946 val = el.value; |
661 |
947 |
|
948 // If any text is selected, replace the selection with a tab character. |
662 if ( document.selection ) { |
949 if ( document.selection ) { |
663 el.focus(); |
950 el.focus(); |
664 sel = document.selection.createRange(); |
951 sel = document.selection.createRange(); |
665 sel.text = '\t'; |
952 sel.text = '\t'; |
666 } else if ( selStart >= 0 ) { |
953 } else if ( selStart >= 0 ) { |
668 el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) ); |
955 el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) ); |
669 el.selectionStart = el.selectionEnd = selStart + 1; |
956 el.selectionStart = el.selectionEnd = selStart + 1; |
670 this.scrollTop = scroll; |
957 this.scrollTop = scroll; |
671 } |
958 } |
672 |
959 |
|
960 // Cancel the regular tab functionality, to prevent losing focus of the textarea. |
673 if ( e.stopPropagation ) |
961 if ( e.stopPropagation ) |
674 e.stopPropagation(); |
962 e.stopPropagation(); |
675 if ( e.preventDefault ) |
963 if ( e.preventDefault ) |
676 e.preventDefault(); |
964 e.preventDefault(); |
677 }); |
965 }); |
678 |
966 |
|
967 // Reset page number variable for new filters/searches but not for bulk actions. See #17685. |
679 if ( pageInput.length ) { |
968 if ( pageInput.length ) { |
|
969 |
|
970 /** |
|
971 * Handles pagination variable when filtering the list table. |
|
972 * |
|
973 * Set the pagination argument to the first page when the post-filter form is submitted. |
|
974 * This happens when pressing the 'filter' button on the list table page. |
|
975 * |
|
976 * The pagination argument should not be touched when the bulk action dropdowns are set to do anything. |
|
977 * |
|
978 * The form closest to the pageInput is the post-filter form. |
|
979 * |
|
980 * @returns {void} |
|
981 */ |
680 pageInput.closest('form').submit( function() { |
982 pageInput.closest('form').submit( function() { |
681 |
983 /* |
682 // Reset paging var for new filters/searches but not for bulk actions. See #17685. |
984 * action = bulk action dropdown at the top of the table |
|
985 * action2 = bulk action dropdow at the bottom of the table |
|
986 */ |
683 if ( $('select[name="action"]').val() == -1 && $('select[name="action2"]').val() == -1 && pageInput.val() == currentPage ) |
987 if ( $('select[name="action"]').val() == -1 && $('select[name="action2"]').val() == -1 && pageInput.val() == currentPage ) |
684 pageInput.val('1'); |
988 pageInput.val('1'); |
685 }); |
989 }); |
686 } |
990 } |
687 |
991 |
|
992 /** |
|
993 * Resets the bulk actions when the search button is clicked. |
|
994 * |
|
995 * @returns {void} |
|
996 */ |
688 $('.search-box input[type="search"], .search-box input[type="submit"]').mousedown(function () { |
997 $('.search-box input[type="search"], .search-box input[type="submit"]').mousedown(function () { |
689 $('select[name^="action"]').val('-1'); |
998 $('select[name^="action"]').val('-1'); |
690 }); |
999 }); |
691 |
1000 |
692 // Scroll into view when focused |
1001 /** |
|
1002 * Scrolls into view when focus.scroll-into-view is triggered. |
|
1003 * |
|
1004 * @param {Event} e The event object. |
|
1005 * |
|
1006 * @returns {void} |
|
1007 */ |
693 $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){ |
1008 $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){ |
694 if ( e.target.scrollIntoView ) |
1009 if ( e.target.scrollIntoView ) |
695 e.target.scrollIntoView(false); |
1010 e.target.scrollIntoView(false); |
696 }); |
1011 }); |
697 |
1012 |
698 // Disable upload buttons until files are selected |
1013 /** |
|
1014 * Disables the submit upload buttons when no data is entered. |
|
1015 * |
|
1016 * @returns {void} |
|
1017 */ |
699 (function(){ |
1018 (function(){ |
700 var button, input, form = $('form.wp-upload-form'); |
1019 var button, input, form = $('form.wp-upload-form'); |
|
1020 |
|
1021 // Exit when no upload form is found. |
701 if ( ! form.length ) |
1022 if ( ! form.length ) |
702 return; |
1023 return; |
|
1024 |
703 button = form.find('input[type="submit"]'); |
1025 button = form.find('input[type="submit"]'); |
704 input = form.find('input[type="file"]'); |
1026 input = form.find('input[type="file"]'); |
705 |
1027 |
|
1028 /** |
|
1029 * Determines if any data is entered in any file upload input. |
|
1030 * |
|
1031 * @since 3.5.0 |
|
1032 * |
|
1033 * @returns {void} |
|
1034 */ |
706 function toggleUploadButton() { |
1035 function toggleUploadButton() { |
|
1036 // When no inputs have a value, disable the upload buttons. |
707 button.prop('disabled', '' === input.map( function() { |
1037 button.prop('disabled', '' === input.map( function() { |
708 return $(this).val(); |
1038 return $(this).val(); |
709 }).get().join('')); |
1039 }).get().join('')); |
710 } |
1040 } |
|
1041 |
|
1042 // Update the status initially. |
711 toggleUploadButton(); |
1043 toggleUploadButton(); |
|
1044 // Update the status when any file input changes. |
712 input.on('change', toggleUploadButton); |
1045 input.on('change', toggleUploadButton); |
713 })(); |
1046 })(); |
714 |
1047 |
|
1048 /** |
|
1049 * Pins the menu while distraction-free writing is enabled. |
|
1050 * |
|
1051 * @param {Event} event Event data. |
|
1052 * |
|
1053 * @since 4.1.0 |
|
1054 * |
|
1055 * @returns {void} |
|
1056 */ |
715 function pinMenu( event ) { |
1057 function pinMenu( event ) { |
716 var windowPos = $window.scrollTop(), |
1058 var windowPos = $window.scrollTop(), |
717 resizing = ! event || event.type !== 'scroll'; |
1059 resizing = ! event || event.type !== 'scroll'; |
718 |
1060 |
719 if ( isIOS || isIE8 || $adminmenu.data( 'wp-responsive' ) ) { |
1061 if ( isIOS || isIE8 || $adminmenu.data( 'wp-responsive' ) ) { |
720 return; |
1062 return; |
721 } |
1063 } |
722 |
1064 |
|
1065 /* |
|
1066 * When the menu is higher than the window and smaller than the entire page. |
|
1067 * It should be adjusted to be able to see the entire menu. |
|
1068 * |
|
1069 * Otherwise it can be accessed normally. |
|
1070 */ |
723 if ( height.menu + height.adminbar < height.window || |
1071 if ( height.menu + height.adminbar < height.window || |
724 height.menu + height.adminbar + 20 > height.wpwrap ) { |
1072 height.menu + height.adminbar + 20 > height.wpwrap ) { |
725 unpinMenu(); |
1073 unpinMenu(); |
726 return; |
1074 return; |
727 } |
1075 } |
728 |
1076 |
729 menuIsPinned = true; |
1077 menuIsPinned = true; |
730 |
1078 |
|
1079 // If the menu is higher than the window, compensate on scroll. |
731 if ( height.menu + height.adminbar > height.window ) { |
1080 if ( height.menu + height.adminbar > height.window ) { |
732 // Check for overscrolling |
1081 // Check for overscrolling, this happens when swiping up at the top of the document in modern browsers. |
733 if ( windowPos < 0 ) { |
1082 if ( windowPos < 0 ) { |
|
1083 // Stick the menu to the top. |
734 if ( ! pinnedMenuTop ) { |
1084 if ( ! pinnedMenuTop ) { |
735 pinnedMenuTop = true; |
1085 pinnedMenuTop = true; |
736 pinnedMenuBottom = false; |
1086 pinnedMenuBottom = false; |
737 |
1087 |
738 $adminMenuWrap.css({ |
1088 $adminMenuWrap.css({ |
773 position: 'absolute', |
1126 position: 'absolute', |
774 top: menuTop, |
1127 top: menuTop, |
775 bottom: '' |
1128 bottom: '' |
776 }); |
1129 }); |
777 } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) { |
1130 } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) { |
778 // pin the bottom |
1131 // Pin it to the bottom. |
779 pinnedMenuBottom = true; |
1132 pinnedMenuBottom = true; |
780 |
1133 |
781 $adminMenuWrap.css({ |
1134 $adminMenuWrap.css({ |
782 position: 'fixed', |
1135 position: 'fixed', |
783 top: '', |
1136 top: '', |
784 bottom: 0 |
1137 bottom: 0 |
785 }); |
1138 }); |
786 } |
1139 } |
787 } else if ( windowPos < lastScrollPosition ) { |
1140 } else if ( windowPos < lastScrollPosition ) { |
788 // Scrolling up |
1141 // When a scroll up is detected. |
|
1142 |
|
1143 // If it was pinned to the bottom, unpin and calculate relative scroll. |
789 if ( pinnedMenuBottom ) { |
1144 if ( pinnedMenuBottom ) { |
790 // let it scroll |
|
791 pinnedMenuBottom = false; |
1145 pinnedMenuBottom = false; |
|
1146 |
|
1147 // Calculate new offset position. |
792 menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos ); |
1148 menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos ); |
793 |
1149 |
794 if ( menuTop + height.menu > windowPos + height.window ) { |
1150 if ( menuTop + height.menu > windowPos + height.window ) { |
795 menuTop = windowPos; |
1151 menuTop = windowPos; |
796 } |
1152 } |
914 }); |
1310 }); |
915 |
1311 |
916 self.trigger(); |
1312 self.trigger(); |
917 $document.on( 'wp-window-resized.wp-responsive', $.proxy( this.trigger, this ) ); |
1313 $document.on( 'wp-window-resized.wp-responsive', $.proxy( this.trigger, this ) ); |
918 |
1314 |
919 // This needs to run later as UI Sortable may be initialized later on $(document).ready() |
1315 // This needs to run later as UI Sortable may be initialized later on $(document).ready(). |
920 $window.on( 'load.wp-responsive', function() { |
1316 $window.on( 'load.wp-responsive', function() { |
921 var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth; |
1317 var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth; |
922 |
1318 |
923 if ( width <= 782 ) { |
1319 if ( width <= 782 ) { |
924 self.disableSortables(); |
1320 self.disableSortables(); |
925 } |
1321 } |
926 }); |
1322 }); |
927 }, |
1323 }, |
928 |
1324 |
|
1325 /** |
|
1326 * Changes properties of body and admin menu. |
|
1327 * |
|
1328 * Pins and unpins the menu and adds the auto-fold class to the body. |
|
1329 * Makes the admin menu responsive and disables the metabox sortables. |
|
1330 * |
|
1331 * @since 3.8.0 |
|
1332 * |
|
1333 * @returns {void} |
|
1334 */ |
929 activate: function() { |
1335 activate: function() { |
930 setPinMenu(); |
1336 setPinMenu(); |
931 |
1337 |
932 if ( ! $body.hasClass( 'auto-fold' ) ) { |
1338 if ( ! $body.hasClass( 'auto-fold' ) ) { |
933 $body.addClass( 'auto-fold' ); |
1339 $body.addClass( 'auto-fold' ); |
935 |
1341 |
936 $adminmenu.data( 'wp-responsive', 1 ); |
1342 $adminmenu.data( 'wp-responsive', 1 ); |
937 this.disableSortables(); |
1343 this.disableSortables(); |
938 }, |
1344 }, |
939 |
1345 |
|
1346 /** |
|
1347 * Changes properties of admin menu and enables metabox sortables. |
|
1348 * |
|
1349 * Pin and unpin the menu. |
|
1350 * Removes the responsiveness of the admin menu and enables the metabox sortables. |
|
1351 * |
|
1352 * @since 3.8.0 |
|
1353 * |
|
1354 * @returns {void} |
|
1355 */ |
940 deactivate: function() { |
1356 deactivate: function() { |
941 setPinMenu(); |
1357 setPinMenu(); |
942 $adminmenu.removeData('wp-responsive'); |
1358 $adminmenu.removeData('wp-responsive'); |
943 this.enableSortables(); |
1359 this.enableSortables(); |
944 }, |
1360 }, |
945 |
1361 |
|
1362 /** |
|
1363 * Sets the responsiveness and enables the overlay based on the viewport width. |
|
1364 * |
|
1365 * @since 3.8.0 |
|
1366 * |
|
1367 * @returns {void} |
|
1368 */ |
946 trigger: function() { |
1369 trigger: function() { |
947 var viewportWidth = getViewportWidth(); |
1370 var viewportWidth = getViewportWidth(); |
948 |
1371 |
949 // Exclude IE < 9, it doesn't support @media CSS rules. |
1372 // Exclude IE < 9, it doesn't support @media CSS rules. |
950 if ( ! viewportWidth ) { |
1373 if ( ! viewportWidth ) { |
984 $toolbarPopups.on( 'click.wp-responsive', function() { |
1414 $toolbarPopups.on( 'click.wp-responsive', function() { |
985 $overlay.show(); |
1415 $overlay.show(); |
986 }); |
1416 }); |
987 }, |
1417 }, |
988 |
1418 |
|
1419 /** |
|
1420 * Disables the responsive overlay and removes the overlay. |
|
1421 * |
|
1422 * @since 3.8.0 |
|
1423 * |
|
1424 * @returns {void} |
|
1425 */ |
989 disableOverlay: function() { |
1426 disableOverlay: function() { |
990 $toolbarPopups.off( 'click.wp-responsive' ); |
1427 $toolbarPopups.off( 'click.wp-responsive' ); |
991 $overlay.hide(); |
1428 $overlay.hide(); |
992 }, |
1429 }, |
993 |
1430 |
|
1431 /** |
|
1432 * Disables sortables. |
|
1433 * |
|
1434 * @since 3.8.0 |
|
1435 * |
|
1436 * @returns {void} |
|
1437 */ |
994 disableSortables: function() { |
1438 disableSortables: function() { |
995 if ( $sortables.length ) { |
1439 if ( $sortables.length ) { |
996 try { |
1440 try { |
997 $sortables.sortable('disable'); |
1441 $sortables.sortable( 'disable' ); |
998 } catch(e) {} |
1442 } catch ( e ) {} |
999 } |
1443 } |
1000 }, |
1444 }, |
1001 |
1445 |
|
1446 /** |
|
1447 * Enables sortables. |
|
1448 * |
|
1449 * @since 3.8.0 |
|
1450 * |
|
1451 * @returns {void} |
|
1452 */ |
1002 enableSortables: function() { |
1453 enableSortables: function() { |
1003 if ( $sortables.length ) { |
1454 if ( $sortables.length ) { |
1004 try { |
1455 try { |
1005 $sortables.sortable('enable'); |
1456 $sortables.sortable( 'enable' ); |
1006 } catch(e) {} |
1457 } catch ( e ) {} |
1007 } |
1458 } |
1008 } |
1459 } |
1009 }; |
1460 }; |
1010 |
1461 |
1011 // Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on. |
1462 /** |
|
1463 * Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on. |
|
1464 * |
|
1465 * @since 4.5.0 |
|
1466 * |
|
1467 * @returns {void} |
|
1468 */ |
1012 function aria_button_if_js() { |
1469 function aria_button_if_js() { |
1013 $( '.aria-button-if-js' ).attr( 'role', 'button' ); |
1470 $( '.aria-button-if-js' ).attr( 'role', 'button' ); |
1014 } |
1471 } |
1015 |
1472 |
1016 $( document ).ajaxComplete( function() { |
1473 $( document ).ajaxComplete( function() { |
1017 aria_button_if_js(); |
1474 aria_button_if_js(); |
1018 }); |
1475 }); |
1019 |
1476 |
1020 /** |
1477 /** |
1021 * @summary Get the viewport width. |
1478 * Get the viewport width. |
1022 * |
1479 * |
1023 * @since 4.7.0 |
1480 * @since 4.7.0 |
1024 * |
1481 * |
1025 * @returns {number|boolean} The current viewport width or false if the |
1482 * @returns {number|boolean} The current viewport width or false if the |
1026 * browser doesn't support innerWidth (IE < 9). |
1483 * browser doesn't support innerWidth (IE < 9). |