]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/js/postbox.js
WordPress 4.7.1-scripts
[autoinstalls/wordpress.git] / wp-admin / js / postbox.js
1 /**
2  * Contains the postboxes logic, opening and closing postboxes, reordering and saving
3  * the state and ordering to the database.
4  *
5  * @summary Contains postboxes logic
6  *
7  * @since 2.5.0
8  * @requires jQuery
9  */
10
11 /* global ajaxurl, postBoxL10n */
12
13 /**
14  * This object contains all function to handle the behaviour of the post boxes. The post boxes are the boxes you see
15  * around the content on the edit page.
16  *
17  * @since 2.7.0
18  *
19  * @namespace postboxes
20  *
21  * @type {Object}
22  */
23 var postboxes;
24
25 (function($) {
26         var $document = $( document );
27
28         postboxes = {
29
30                 /**
31                  * @summary Handles a click on either the postbox heading or the postbox open/close icon.
32                  *
33                  * Opens or closes the postbox. Expects `this` to equal the clicked element.
34                  * Calls postboxes.pbshow if the postbox has been opened, calls postboxes.pbhide
35                  * if the postbox has been closed.
36                  *
37                  * @since 4.4.0
38                  * @memberof postboxes
39                  * @fires postboxes#postbox-toggled
40                  *
41                  * @returns {void}
42                  */
43                 handle_click : function () {
44                         var $el = $( this ),
45                                 p = $el.parent( '.postbox' ),
46                                 id = p.attr( 'id' ),
47                                 ariaExpandedValue;
48
49                         if ( 'dashboard_browser_nag' === id ) {
50                                 return;
51                         }
52
53                         p.toggleClass( 'closed' );
54
55                         ariaExpandedValue = ! p.hasClass( 'closed' );
56
57                         if ( $el.hasClass( 'handlediv' ) ) {
58                                 // The handle button was clicked.
59                                 $el.attr( 'aria-expanded', ariaExpandedValue );
60                         } else {
61                                 // The handle heading was clicked.
62                                 $el.closest( '.postbox' ).find( 'button.handlediv' )
63                                         .attr( 'aria-expanded', ariaExpandedValue );
64                         }
65
66                         if ( postboxes.page !== 'press-this' ) {
67                                 postboxes.save_state( postboxes.page );
68                         }
69
70                         if ( id ) {
71                                 if ( !p.hasClass('closed') && $.isFunction( postboxes.pbshow ) ) {
72                                         postboxes.pbshow( id );
73                                 } else if ( p.hasClass('closed') && $.isFunction( postboxes.pbhide ) ) {
74                                         postboxes.pbhide( id );
75                                 }
76                         }
77
78                         /**
79                          * @summary Fires when a postbox has been opened or closed.
80                          *
81                          * Contains a jQuery object with the relevant postbox element.
82                          *
83                          * @since 4.0.0
84                          * @event postboxes#postbox-toggled
85                          * @type {Object}
86                          */
87                         $document.trigger( 'postbox-toggled', p );
88                 },
89
90                 /**
91                  * Adds event handlers to all postboxes and screen option on the current page.
92                  *
93                  * @since 2.7.0
94                  * @memberof postboxes
95                  *
96                  * @param {string} page The page we are currently on.
97                  * @param {Object} [args]
98                  * @param {Function} args.pbshow A callback that is called when a postbox opens.
99                  * @param {Function} args.pbhide A callback that is called when a postbox closes.
100                  * @returns {void}
101                  */
102                 add_postbox_toggles : function (page, args) {
103                         var $handles = $( '.postbox .hndle, .postbox .handlediv' );
104
105                         this.page = page;
106                         this.init( page, args );
107
108                         $handles.on( 'click.postboxes', this.handle_click );
109
110                         /**
111                          * @since 2.7.0
112                          */
113                         $('.postbox .hndle a').click( function(e) {
114                                 e.stopPropagation();
115                         });
116
117                         /**
118                          * @summary Hides a postbox.
119                          *
120                          * Event handler for the postbox dismiss button. After clicking the button
121                          * the postbox will be hidden.
122                          *
123                          * @since 3.2.0
124                          *
125                          * @returns {void}
126                          */
127                         $( '.postbox a.dismiss' ).on( 'click.postboxes', function( e ) {
128                                 var hide_id = $(this).parents('.postbox').attr('id') + '-hide';
129                                 e.preventDefault();
130                                 $( '#' + hide_id ).prop('checked', false).triggerHandler('click');
131                         });
132
133                         /**
134                          * @summary Hides the postbox element
135                          *
136                          * Event handler for the screen options checkboxes. When a checkbox is
137                          * clicked this function will hide or show the relevant postboxes.
138                          *
139                          * @since 2.7.0
140                          * @fires postboxes#postbox-toggled
141                          *
142                          * @returns {void}
143                          */
144                         $('.hide-postbox-tog').bind('click.postboxes', function() {
145                                 var $el = $(this),
146                                         boxId = $el.val(),
147                                         $postbox = $( '#' + boxId );
148
149                                 if ( $el.prop( 'checked' ) ) {
150                                         $postbox.show();
151                                         if ( $.isFunction( postboxes.pbshow ) ) {
152                                                 postboxes.pbshow( boxId );
153                                         }
154                                 } else {
155                                         $postbox.hide();
156                                         if ( $.isFunction( postboxes.pbhide ) ) {
157                                                 postboxes.pbhide( boxId );
158                                         }
159                                 }
160
161                                 postboxes.save_state( page );
162                                 postboxes._mark_area();
163
164                                 /**
165                                  * @since 4.0.0
166                                  * @see postboxes.handle_click
167                                  */
168                                 $document.trigger( 'postbox-toggled', $postbox );
169                         });
170
171                         /**
172                          * @summary Changes the amount of columns based on the layout preferences.
173                          *
174                          * @since 2.8.0
175                          *
176                          * @returns {void}
177                          */
178                         $('.columns-prefs input[type="radio"]').bind('click.postboxes', function(){
179                                 var n = parseInt($(this).val(), 10);
180
181                                 if ( n ) {
182                                         postboxes._pb_edit(n);
183                                         postboxes.save_order( page );
184                                 }
185                         });
186                 },
187
188                 /**
189                  * @summary Initializes all the postboxes, mainly their sortable behaviour.
190                  *
191                  * @since 2.7.0
192                  * @memberof postboxes
193                  *
194                  * @param {string} page The page we are currently on.
195                  * @param {Object} [args={}] The arguments for the postbox initializer.
196                  * @param {Function} args.pbshow A callback that is called when a postbox opens.
197                  * @param {Function} args.pbhide A callback that is called when a postbox
198                  *                               closes.
199                  *
200                  * @returns {void}
201                  */
202                 init : function(page, args) {
203                         var isMobile = $( document.body ).hasClass( 'mobile' ),
204                                 $handleButtons = $( '.postbox .handlediv' );
205
206                         $.extend( this, args || {} );
207                         $('#wpbody-content').css('overflow','hidden');
208                         $('.meta-box-sortables').sortable({
209                                 placeholder: 'sortable-placeholder',
210                                 connectWith: '.meta-box-sortables',
211                                 items: '.postbox',
212                                 handle: '.hndle',
213                                 cursor: 'move',
214                                 delay: ( isMobile ? 200 : 0 ),
215                                 distance: 2,
216                                 tolerance: 'pointer',
217                                 forcePlaceholderSize: true,
218                                 helper: function( event, element ) {
219                                         /* `helper: 'clone'` is equivalent to `return element.clone();`
220                                          * Cloning a checked radio and then inserting that clone next to the original
221                                          * radio unchecks the original radio (since only one of the two can be checked).
222                                          * We get around this by renaming the helper's inputs' name attributes so that,
223                                          * when the helper is inserted into the DOM for the sortable, no radios are
224                                          * duplicated, and no original radio gets unchecked.
225                                          */
226                                         return element.clone()
227                                                 .find( ':input' )
228                                                         .attr( 'name', function( i, currentName ) {
229                                                                 return 'sort_' + parseInt( Math.random() * 100000, 10 ).toString() + '_' + currentName;
230                                                         } )
231                                                 .end();
232                                 },
233                                 opacity: 0.65,
234                                 stop: function() {
235                                         var $el = $( this );
236
237                                         if ( $el.find( '#dashboard_browser_nag' ).is( ':visible' ) && 'dashboard_browser_nag' != this.firstChild.id ) {
238                                                 $el.sortable('cancel');
239                                                 return;
240                                         }
241
242                                         postboxes.save_order(page);
243                                 },
244                                 receive: function(e,ui) {
245                                         if ( 'dashboard_browser_nag' == ui.item[0].id )
246                                                 $(ui.sender).sortable('cancel');
247
248                                         postboxes._mark_area();
249                                         $document.trigger( 'postbox-moved', ui.item );
250                                 }
251                         });
252
253                         if ( isMobile ) {
254                                 $(document.body).bind('orientationchange.postboxes', function(){ postboxes._pb_change(); });
255                                 this._pb_change();
256                         }
257
258                         this._mark_area();
259
260                         // Set the handle buttons `aria-expanded` attribute initial value on page load.
261                         $handleButtons.each( function () {
262                                 var $el = $( this );
263                                 $el.attr( 'aria-expanded', ! $el.parent( '.postbox' ).hasClass( 'closed' ) );
264                         });
265                 },
266
267                 /**
268                  * @summary Saves the state of the postboxes to the server.
269                  *
270                  * Saves the state of the postboxes to the server. It sends two lists, one with
271                  * all the closed postboxes, one with all the hidden postboxes.
272                  *
273                  * @since 2.7.0
274                  * @memberof postboxes
275                  *
276                  * @param {string} page The page we are currently on.
277                  * @returns {void}
278                  */
279                 save_state : function(page) {
280                         var closed, hidden;
281
282                         // Return on the nav-menus.php screen, see #35112.
283                         if ( 'nav-menus' === page ) {
284                                 return;
285                         }
286
287                         closed = $( '.postbox' ).filter( '.closed' ).map( function() { return this.id; } ).get().join( ',' );
288                         hidden = $( '.postbox' ).filter( ':hidden' ).map( function() { return this.id; } ).get().join( ',' );
289
290                         $.post(ajaxurl, {
291                                 action: 'closed-postboxes',
292                                 closed: closed,
293                                 hidden: hidden,
294                                 closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(),
295                                 page: page
296                         });
297                 },
298
299                 /**
300                  * @summary Saves the order of the postboxes to the server.
301                  *
302                  * Saves the order of the postboxes to the server. Sends a list of all postboxes
303                  * inside a sortable area to the server.
304                  *
305                  * @since 2.8.0
306                  * @memberof postboxes
307                  *
308                  * @param {string} page The page we are currently on.
309                  * @returns {void}
310                  */
311                 save_order : function(page) {
312                         var postVars, page_columns = $('.columns-prefs input:checked').val() || 0;
313
314                         postVars = {
315                                 action: 'meta-box-order',
316                                 _ajax_nonce: $('#meta-box-order-nonce').val(),
317                                 page_columns: page_columns,
318                                 page: page
319                         };
320
321                         $('.meta-box-sortables').each( function() {
322                                 postVars[ 'order[' + this.id.split( '-' )[0] + ']' ] = $( this ).sortable( 'toArray' ).join( ',' );
323                         } );
324
325                         $.post( ajaxurl, postVars );
326                 },
327
328                 /**
329                  * @summary Marks empty postbox areas.
330                  *
331                  * Adds a message to empty sortable areas on the dashboard page. Also adds a
332                  * border around the side area on the post edit screen if there are no postboxes
333                  * present.
334                  *
335                  * @since 3.3.0
336                  * @memberof postboxes
337                  * @access private
338                  *
339                  * @returns {void}
340                  */
341                 _mark_area : function() {
342                         var visible = $('div.postbox:visible').length, side = $('#post-body #side-sortables');
343
344                         $( '#dashboard-widgets .meta-box-sortables:visible' ).each( function() {
345                                 var t = $(this);
346
347                                 if ( visible == 1 || t.children('.postbox:visible').length ) {
348                                         t.removeClass('empty-container');
349                                 }
350                                 else {
351                                         t.addClass('empty-container');
352                                         t.attr('data-emptyString', postBoxL10n.postBoxEmptyString);
353                                 }
354                         });
355
356                         if ( side.length ) {
357                                 if ( side.children('.postbox:visible').length )
358                                         side.removeClass('empty-container');
359                                 else if ( $('#postbox-container-1').css('width') == '280px' )
360                                         side.addClass('empty-container');
361                         }
362                 },
363
364                 /**
365                  * @summary Changes the amount of columns on the post edit page.
366                  *
367                  * @since 3.3.0
368                  * @memberof postboxes
369                  * @fires postboxes#postboxes-columnchange
370                  * @access private
371                  *
372                  * @param {number} n The amount of columns to divide the post edit page in.
373                  * @returns {void}
374                  */
375                 _pb_edit : function(n) {
376                         var el = $('.metabox-holder').get(0);
377
378                         if ( el ) {
379                                 el.className = el.className.replace(/columns-\d+/, 'columns-' + n);
380                         }
381
382                         /**
383                          * Fires when the amount of columns on the post edit page has been changed.
384                          *
385                          * @since 4.0.0
386                          * @event postboxes#postboxes-columnchange
387                          */
388                         $( document ).trigger( 'postboxes-columnchange' );
389                 },
390
391                 /**
392                  * @summary Changes the amount of columns the postboxes are in based on the
393                  *          current orientation of the browser.
394                  *
395                  * @since 3.3.0
396                  * @memberof postboxes
397                  * @access private
398                  *
399                  * @returns {void}
400                  */
401                 _pb_change : function() {
402                         var check = $( 'label.columns-prefs-1 input[type="radio"]' );
403
404                         switch ( window.orientation ) {
405                                 case 90:
406                                 case -90:
407                                         if ( !check.length || !check.is(':checked') )
408                                                 this._pb_edit(2);
409                                         break;
410                                 case 0:
411                                 case 180:
412                                         if ( $('#poststuff').length ) {
413                                                 this._pb_edit(1);
414                                         } else {
415                                                 if ( !check.length || !check.is(':checked') )
416                                                         this._pb_edit(2);
417                                         }
418                                         break;
419                         }
420                 },
421
422                 /* Callbacks */
423
424                 /**
425                  * @since 2.7.0
426                  * @memberof postboxes
427                  * @access public
428                  * @property {Function|boolean} pbshow A callback that is called when a postbox
429                  *                                     is opened.
430                  */
431                 pbshow : false,
432
433                 /**
434                  * @since 2.7.0
435                  * @memberof postboxes
436                  * @access public
437                  * @property {Function|boolean} pbhide A callback that is called when a postbox
438                  *                                     is closed.
439                  */
440                 pbhide : false
441         };
442
443 }(jQuery));