Diff: STRATO-apps/wordpress_03/app/wp-admin/js/postbox.js
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
/**
2
+
* Contains the postboxes logic, opening and closing postboxes, reordering and saving
3
+
* the state and ordering to the database.
4
+
*
5
+
* @since 2.5.0
6
+
* @requires jQuery
7
+
* @output wp-admin/js/postbox.js
8
+
*/
9
+
10
+
/* global ajaxurl, postboxes */
11
+
12
+
(function($) {
13
+
var $document = $( document ),
14
+
__ = wp.i18n.__;
15
+
16
+
/**
17
+
* This object contains all function to handle the behavior of the post boxes. The post boxes are the boxes you see
18
+
* around the content on the edit page.
19
+
*
20
+
* @since 2.7.0
21
+
*
22
+
* @namespace postboxes
23
+
*
24
+
* @type {Object}
25
+
*/
26
+
window.postboxes = {
27
+
28
+
/**
29
+
* Handles a click on either the postbox heading or the postbox open/close icon.
30
+
*
31
+
* Opens or closes the postbox. Expects `this` to equal the clicked element.
32
+
* Calls postboxes.pbshow if the postbox has been opened, calls postboxes.pbhide
33
+
* if the postbox has been closed.
34
+
*
35
+
* @since 4.4.0
36
+
*
37
+
* @memberof postboxes
38
+
*
39
+
* @fires postboxes#postbox-toggled
40
+
*
41
+
* @return {void}
42
+
*/
43
+
handle_click : function () {
44
+
var $el = $( this ),
45
+
p = $el.closest( '.postbox' ),
46
+
id = p.attr( 'id' ),
47
+
ariaExpandedValue;
48
+
49
+
if ( 'dashboard_browser_nag' === id ) {
50
+
return;
51
+
}
52
+
53
+
p.toggleClass( 'closed' );
54
+
ariaExpandedValue = ! p.hasClass( 'closed' );
55
+
56
+
if ( $el.hasClass( 'handlediv' ) ) {
57
+
// The handle button was clicked.
58
+
$el.attr( 'aria-expanded', ariaExpandedValue );
59
+
} else {
60
+
// The handle heading was clicked.
61
+
$el.closest( '.postbox' ).find( 'button.handlediv' )
62
+
.attr( 'aria-expanded', ariaExpandedValue );
63
+
}
64
+
65
+
if ( postboxes.page !== 'press-this' ) {
66
+
postboxes.save_state( postboxes.page );
67
+
}
68
+
69
+
if ( id ) {
70
+
if ( !p.hasClass('closed') && typeof postboxes.pbshow === 'function' ) {
71
+
postboxes.pbshow( id );
72
+
} else if ( p.hasClass('closed') && typeof postboxes.pbhide === 'function' ) {
73
+
postboxes.pbhide( id );
74
+
}
75
+
}
76
+
77
+
/**
78
+
* Fires when a postbox has been opened or closed.
79
+
*
80
+
* Contains a jQuery object with the relevant postbox element.
81
+
*
82
+
* @since 4.0.0
83
+
* @ignore
84
+
*
85
+
* @event postboxes#postbox-toggled
86
+
* @type {Object}
87
+
*/
88
+
$document.trigger( 'postbox-toggled', p );
89
+
},
90
+
91
+
/**
92
+
* Handles clicks on the move up/down buttons.
93
+
*
94
+
* @since 5.5.0
95
+
*
96
+
* @return {void}
97
+
*/
98
+
handleOrder: function() {
99
+
var button = $( this ),
100
+
postbox = button.closest( '.postbox' ),
101
+
postboxId = postbox.attr( 'id' ),
102
+
postboxesWithinSortables = postbox.closest( '.meta-box-sortables' ).find( '.postbox:visible' ),
103
+
postboxesWithinSortablesCount = postboxesWithinSortables.length,
104
+
postboxWithinSortablesIndex = postboxesWithinSortables.index( postbox ),
105
+
firstOrLastPositionMessage;
106
+
107
+
if ( 'dashboard_browser_nag' === postboxId ) {
108
+
return;
109
+
}
110
+
111
+
// If on the first or last position, do nothing and send an audible message to screen reader users.
112
+
if ( 'true' === button.attr( 'aria-disabled' ) ) {
113
+
firstOrLastPositionMessage = button.hasClass( 'handle-order-higher' ) ?
114
+
__( 'The box is on the first position' ) :
115
+
__( 'The box is on the last position' );
116
+
117
+
wp.a11y.speak( firstOrLastPositionMessage );
118
+
return;
119
+
}
120
+
121
+
// Move a postbox up.
122
+
if ( button.hasClass( 'handle-order-higher' ) ) {
123
+
// If the box is first within a sortable area, move it to the previous sortable area.
124
+
if ( 0 === postboxWithinSortablesIndex ) {
125
+
postboxes.handleOrderBetweenSortables( 'previous', button, postbox );
126
+
return;
127
+
}
128
+
129
+
postbox.prevAll( '.postbox:visible' ).eq( 0 ).before( postbox );
130
+
button.trigger( 'focus' );
131
+
postboxes.updateOrderButtonsProperties();
132
+
postboxes.save_order( postboxes.page );
133
+
}
134
+
135
+
// Move a postbox down.
136
+
if ( button.hasClass( 'handle-order-lower' ) ) {
137
+
// If the box is last within a sortable area, move it to the next sortable area.
138
+
if ( postboxWithinSortablesIndex + 1 === postboxesWithinSortablesCount ) {
139
+
postboxes.handleOrderBetweenSortables( 'next', button, postbox );
140
+
return;
141
+
}
142
+
143
+
postbox.nextAll( '.postbox:visible' ).eq( 0 ).after( postbox );
144
+
button.trigger( 'focus' );
145
+
postboxes.updateOrderButtonsProperties();
146
+
postboxes.save_order( postboxes.page );
147
+
}
148
+
149
+
},
150
+
151
+
/**
152
+
* Moves postboxes between the sortables areas.
153
+
*
154
+
* @since 5.5.0
155
+
*
156
+
* @param {string} position The "previous" or "next" sortables area.
157
+
* @param {Object} button The jQuery object representing the button that was clicked.
158
+
* @param {Object} postbox The jQuery object representing the postbox to be moved.
159
+
*
160
+
* @return {void}
161
+
*/
162
+
handleOrderBetweenSortables: function( position, button, postbox ) {
163
+
var closestSortablesId = button.closest( '.meta-box-sortables' ).attr( 'id' ),
164
+
sortablesIds = [],
165
+
sortablesIndex,
166
+
detachedPostbox;
167
+
168
+
// Get the list of sortables within the page.
169
+
$( '.meta-box-sortables:visible' ).each( function() {
170
+
sortablesIds.push( $( this ).attr( 'id' ) );
171
+
});
172
+
173
+
// Return if there's only one visible sortables area, e.g. in the block editor page.
174
+
if ( 1 === sortablesIds.length ) {
175
+
return;
176
+
}
177
+
178
+
// Find the index of the current sortables area within all the sortable areas.
179
+
sortablesIndex = $.inArray( closestSortablesId, sortablesIds );
180
+
// Detach the postbox to be moved.
181
+
detachedPostbox = postbox.detach();
182
+
183
+
// Move the detached postbox to its new position.
184
+
if ( 'previous' === position ) {
185
+
$( detachedPostbox ).appendTo( '#' + sortablesIds[ sortablesIndex - 1 ] );
186
+
}
187
+
188
+
if ( 'next' === position ) {
189
+
$( detachedPostbox ).prependTo( '#' + sortablesIds[ sortablesIndex + 1 ] );
190
+
}
191
+
192
+
postboxes._mark_area();
193
+
button.focus();
194
+
postboxes.updateOrderButtonsProperties();
195
+
postboxes.save_order( postboxes.page );
196
+
},
197
+
198
+
/**
199
+
* Update the move buttons properties depending on the postbox position.
200
+
*
201
+
* @since 5.5.0
202
+
*
203
+
* @return {void}
204
+
*/
205
+
updateOrderButtonsProperties: function() {
206
+
var firstSortablesId = $( '.meta-box-sortables:visible:first' ).attr( 'id' ),
207
+
lastSortablesId = $( '.meta-box-sortables:visible:last' ).attr( 'id' ),
208
+
firstPostbox = $( '.postbox:visible:first' ),
209
+
lastPostbox = $( '.postbox:visible:last' ),
210
+
firstPostboxId = firstPostbox.attr( 'id' ),
211
+
lastPostboxId = lastPostbox.attr( 'id' ),
212
+
firstPostboxSortablesId = firstPostbox.closest( '.meta-box-sortables' ).attr( 'id' ),
213
+
lastPostboxSortablesId = lastPostbox.closest( '.meta-box-sortables' ).attr( 'id' ),
214
+
moveUpButtons = $( '.handle-order-higher' ),
215
+
moveDownButtons = $( '.handle-order-lower' );
216
+
217
+
// Enable all buttons as a reset first.
218
+
moveUpButtons
219
+
.attr( 'aria-disabled', 'false' )
220
+
.removeClass( 'hidden' );
221
+
moveDownButtons
222
+
.attr( 'aria-disabled', 'false' )
223
+
.removeClass( 'hidden' );
224
+
225
+
// When there's only one "sortables" area (e.g. in the block editor) and only one visible postbox, hide the buttons.
226
+
if ( firstSortablesId === lastSortablesId && firstPostboxId === lastPostboxId ) {
227
+
moveUpButtons.addClass( 'hidden' );
228
+
moveDownButtons.addClass( 'hidden' );
229
+
}
230
+
231
+
// Set an aria-disabled=true attribute on the first visible "move" buttons.
232
+
if ( firstSortablesId === firstPostboxSortablesId ) {
233
+
$( firstPostbox ).find( '.handle-order-higher' ).attr( 'aria-disabled', 'true' );
234
+
}
235
+
236
+
// Set an aria-disabled=true attribute on the last visible "move" buttons.
237
+
if ( lastSortablesId === lastPostboxSortablesId ) {
238
+
$( '.postbox:visible .handle-order-lower' ).last().attr( 'aria-disabled', 'true' );
239
+
}
240
+
},
241
+
242
+
/**
243
+
* Adds event handlers to all postboxes and screen option on the current page.
244
+
*
245
+
* @since 2.7.0
246
+
*
247
+
* @memberof postboxes
248
+
*
249
+
* @param {string} page The page we are currently on.
250
+
* @param {Object} [args]
251
+
* @param {Function} args.pbshow A callback that is called when a postbox opens.
252
+
* @param {Function} args.pbhide A callback that is called when a postbox closes.
253
+
* @return {void}
254
+
*/
255
+
add_postbox_toggles : function (page, args) {
256
+
var $handles = $( '.postbox .hndle, .postbox .handlediv' ),
257
+
$orderButtons = $( '.postbox .handle-order-higher, .postbox .handle-order-lower' );
258
+
259
+
this.page = page;
260
+
this.init( page, args );
261
+
262
+
$handles.on( 'click.postboxes', this.handle_click );
263
+
264
+
// Handle the order of the postboxes.
265
+
$orderButtons.on( 'click.postboxes', this.handleOrder );
266
+
267
+
/**
268
+
* @since 2.7.0
269
+
*/
270
+
$('.postbox .hndle a').on( 'click', function(e) {
271
+
e.stopPropagation();
272
+
});
273
+
274
+
/**
275
+
* Hides a postbox.
276
+
*
277
+
* Event handler for the postbox dismiss button. After clicking the button
278
+
* the postbox will be hidden.
279
+
*
280
+
* As of WordPress 5.5, this is only used for the browser update nag.
281
+
*
282
+
* @since 3.2.0
283
+
*
284
+
* @return {void}
285
+
*/
286
+
$( '.postbox a.dismiss' ).on( 'click.postboxes', function( e ) {
287
+
var hide_id = $(this).parents('.postbox').attr('id') + '-hide';
288
+
e.preventDefault();
289
+
$( '#' + hide_id ).prop('checked', false).triggerHandler('click');
290
+
});
291
+
292
+
/**
293
+
* Hides the postbox element
294
+
*
295
+
* Event handler for the screen options checkboxes. When a checkbox is
296
+
* clicked this function will hide or show the relevant postboxes.
297
+
*
298
+
* @since 2.7.0
299
+
* @ignore
300
+
*
301
+
* @fires postboxes#postbox-toggled
302
+
*
303
+
* @return {void}
304
+
*/
305
+
$('.hide-postbox-tog').on('click.postboxes', function() {
306
+
var $el = $(this),
307
+
boxId = $el.val(),
308
+
$postbox = $( '#' + boxId );
309
+
310
+
if ( $el.prop( 'checked' ) ) {
311
+
$postbox.show();
312
+
if ( typeof postboxes.pbshow === 'function' ) {
313
+
postboxes.pbshow( boxId );
314
+
}
315
+
} else {
316
+
$postbox.hide();
317
+
if ( typeof postboxes.pbhide === 'function' ) {
318
+
postboxes.pbhide( boxId );
319
+
}
320
+
}
321
+
322
+
postboxes.save_state( page );
323
+
postboxes._mark_area();
324
+
325
+
/**
326
+
* @since 4.0.0
327
+
* @see postboxes.handle_click
328
+
*/
329
+
$document.trigger( 'postbox-toggled', $postbox );
330
+
});
331
+
332
+
/**
333
+
* Changes the amount of columns based on the layout preferences.
334
+
*
335
+
* @since 2.8.0
336
+
*
337
+
* @return {void}
338
+
*/
339
+
$('.columns-prefs input[type="radio"]').on('click.postboxes', function(){
340
+
var n = parseInt($(this).val(), 10);
341
+
342
+
if ( n ) {
343
+
postboxes._pb_edit(n);
344
+
postboxes.save_order( page );
345
+
}
346
+
});
347
+
},
348
+
349
+
/**
350
+
* Initializes all the postboxes, mainly their sortable behavior.
351
+
*
352
+
* @since 2.7.0
353
+
*
354
+
* @memberof postboxes
355
+
*
356
+
* @param {string} page The page we are currently on.
357
+
* @param {Object} [args={}] The arguments for the postbox initializer.
358
+
* @param {Function} args.pbshow A callback that is called when a postbox opens.
359
+
* @param {Function} args.pbhide A callback that is called when a postbox
360
+
* closes.
361
+
*
362
+
* @return {void}
363
+
*/
364
+
init : function(page, args) {
365
+
var isMobile = $( document.body ).hasClass( 'mobile' ),
366
+
$handleButtons = $( '.postbox .handlediv' );
367
+
368
+
$.extend( this, args || {} );
369
+
$('.meta-box-sortables').sortable({
370
+
placeholder: 'sortable-placeholder',
371
+
connectWith: '.meta-box-sortables',
372
+
items: '.postbox',
373
+
handle: '.hndle',
374
+
cursor: 'move',
375
+
delay: ( isMobile ? 200 : 0 ),
376
+
distance: 2,
377
+
tolerance: 'pointer',
378
+
forcePlaceholderSize: true,
379
+
helper: function( event, element ) {
380
+
/* `helper: 'clone'` is equivalent to `return element.clone();`
381
+
* Cloning a checked radio and then inserting that clone next to the original
382
+
* radio unchecks the original radio (since only one of the two can be checked).
383
+
* We get around this by renaming the helper's inputs' name attributes so that,
384
+
* when the helper is inserted into the DOM for the sortable, no radios are
385
+
* duplicated, and no original radio gets unchecked.
386
+
*/
387
+
return element.clone()
388
+
.find( ':input' )
389
+
.attr( 'name', function( i, currentName ) {
390
+
return 'sort_' + parseInt( Math.random() * 100000, 10 ).toString() + '_' + currentName;
391
+
} )
392
+
.end();
393
+
},
394
+
opacity: 0.65,
395
+
start: function() {
396
+
$( 'body' ).addClass( 'is-dragging-metaboxes' );
397
+
// Refresh the cached positions of all the sortable items so that the min-height set while dragging works.
398
+
$( '.meta-box-sortables' ).sortable( 'refreshPositions' );
399
+
},
400
+
stop: function() {
401
+
var $el = $( this );
402
+
403
+
$( 'body' ).removeClass( 'is-dragging-metaboxes' );
404
+
405
+
if ( $el.find( '#dashboard_browser_nag' ).is( ':visible' ) && 'dashboard_browser_nag' != this.firstChild.id ) {
406
+
$el.sortable('cancel');
407
+
return;
408
+
}
409
+
410
+
postboxes.updateOrderButtonsProperties();
411
+
postboxes.save_order(page);
412
+
},
413
+
receive: function(e,ui) {
414
+
if ( 'dashboard_browser_nag' == ui.item[0].id )
415
+
$(ui.sender).sortable('cancel');
416
+
417
+
postboxes._mark_area();
418
+
$document.trigger( 'postbox-moved', ui.item );
419
+
}
420
+
});
421
+
422
+
if ( isMobile ) {
423
+
$(document.body).on('orientationchange.postboxes', function(){ postboxes._pb_change(); });
424
+
this._pb_change();
425
+
}
426
+
427
+
this._mark_area();
428
+
429
+
// Update the "move" buttons properties.
430
+
this.updateOrderButtonsProperties();
431
+
$document.on( 'postbox-toggled', this.updateOrderButtonsProperties );
432
+
433
+
// Set the handle buttons `aria-expanded` attribute initial value on page load.
434
+
$handleButtons.each( function () {
435
+
var $el = $( this );
436
+
$el.attr( 'aria-expanded', ! $el.closest( '.postbox' ).hasClass( 'closed' ) );
437
+
});
438
+
},
439
+
440
+
/**
441
+
* Saves the state of the postboxes to the server.
442
+
*
443
+
* It sends two lists, one with all the closed postboxes, one with all the
444
+
* hidden postboxes.
445
+
*
446
+
* @since 2.7.0
447
+
*
448
+
* @memberof postboxes
449
+
*
450
+
* @param {string} page The page we are currently on.
451
+
* @return {void}
452
+
*/
453
+
save_state : function(page) {
454
+
var closed, hidden;
455
+
456
+
// Return on the nav-menus.php screen, see #35112.
457
+
if ( 'nav-menus' === page ) {
458
+
return;
459
+
}
460
+
461
+
closed = $( '.postbox' ).filter( '.closed' ).map( function() { return this.id; } ).get().join( ',' );
462
+
hidden = $( '.postbox' ).filter( ':hidden' ).map( function() { return this.id; } ).get().join( ',' );
463
+
464
+
$.post(
465
+
ajaxurl,
466
+
{
467
+
action: 'closed-postboxes',
468
+
closed: closed,
469
+
hidden: hidden,
470
+
closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(),
471
+
page: page
472
+
},
473
+
function() {
474
+
wp.a11y.speak( __( 'Screen Options updated.' ) );
475
+
}
476
+
);
477
+
},
478
+
479
+
/**
480
+
* Saves the order of the postboxes to the server.
481
+
*
482
+
* Sends a list of all postboxes inside a sortable area to the server.
483
+
*
484
+
* @since 2.8.0
485
+
*
486
+
* @memberof postboxes
487
+
*
488
+
* @param {string} page The page we are currently on.
489
+
* @return {void}
490
+
*/
491
+
save_order : function(page) {
492
+
var postVars, page_columns = $('.columns-prefs input:checked').val() || 0;
493
+
494
+
postVars = {
495
+
action: 'meta-box-order',
496
+
_ajax_nonce: $('#meta-box-order-nonce').val(),
497
+
page_columns: page_columns,
498
+
page: page
499
+
};
500
+
501
+
$('.meta-box-sortables').each( function() {
502
+
postVars[ 'order[' + this.id.split( '-' )[0] + ']' ] = $( this ).sortable( 'toArray' ).join( ',' );
503
+
} );
504
+
505
+
$.post(
506
+
ajaxurl,
507
+
postVars,
508
+
function( response ) {
509
+
if ( response.success ) {
510
+
wp.a11y.speak( __( 'The boxes order has been saved.' ) );
511
+
}
512
+
}
513
+
);
514
+
},
515
+
516
+
/**
517
+
* Marks empty postbox areas.
518
+
*
519
+
* Adds a message to empty sortable areas on the dashboard page. Also adds a
520
+
* border around the side area on the post edit screen if there are no postboxes
521
+
* present.
522
+
*
523
+
* @since 3.3.0
524
+
* @access private
525
+
*
526
+
* @memberof postboxes
527
+
*
528
+
* @return {void}
529
+
*/
530
+
_mark_area : function() {
531
+
var visible = $( 'div.postbox:visible' ).length,
532
+
visibleSortables = $( '#dashboard-widgets .meta-box-sortables:visible, #post-body .meta-box-sortables:visible' ),
533
+
areAllVisibleSortablesEmpty = true;
534
+
535
+
visibleSortables.each( function() {
536
+
var t = $(this);
537
+
538
+
if ( visible == 1 || t.children( '.postbox:visible' ).length ) {
539
+
t.removeClass('empty-container');
540
+
areAllVisibleSortablesEmpty = false;
541
+
}
542
+
else {
543
+
t.addClass('empty-container');
544
+
}
545
+
});
546
+
547
+
postboxes.updateEmptySortablesText( visibleSortables, areAllVisibleSortablesEmpty );
548
+
},
549
+
550
+
/**
551
+
* Updates the text for the empty sortable areas on the Dashboard.
552
+
*
553
+
* @since 5.5.0
554
+
*
555
+
* @param {Object} visibleSortables The jQuery object representing the visible sortable areas.
556
+
* @param {boolean} areAllVisibleSortablesEmpty Whether all the visible sortable areas are "empty".
557
+
*
558
+
* @return {void}
559
+
*/
560
+
updateEmptySortablesText: function( visibleSortables, areAllVisibleSortablesEmpty ) {
561
+
var isDashboard = $( '#dashboard-widgets' ).length,
562
+
emptySortableText = areAllVisibleSortablesEmpty ? __( 'Add boxes from the Screen Options menu' ) : __( 'Drag boxes here' );
563
+
564
+
if ( ! isDashboard ) {
565
+
return;
566
+
}
567
+
568
+
visibleSortables.each( function() {
569
+
if ( $( this ).hasClass( 'empty-container' ) ) {
570
+
$( this ).attr( 'data-emptyString', emptySortableText );
571
+
}
572
+
} );
573
+
},
574
+
575
+
/**
576
+
* Changes the amount of columns on the post edit page.
577
+
*
578
+
* @since 3.3.0
579
+
* @access private
580
+
*
581
+
* @memberof postboxes
582
+
*
583
+
* @fires postboxes#postboxes-columnchange
584
+
*
585
+
* @param {number} n The amount of columns to divide the post edit page in.
586
+
* @return {void}
587
+
*/
588
+
_pb_edit : function(n) {
589
+
var el = $('.metabox-holder').get(0);
590
+
591
+
if ( el ) {
592
+
el.className = el.className.replace(/columns-\d+/, 'columns-' + n);
593
+
}
594
+
595
+
/**
596
+
* Fires when the amount of columns on the post edit page has been changed.
597
+
*
598
+
* @since 4.0.0
599
+
* @ignore
600
+
*
601
+
* @event postboxes#postboxes-columnchange
602
+
*/
603
+
$( document ).trigger( 'postboxes-columnchange' );
604
+
},
605
+
606
+
/**
607
+
* Changes the amount of columns the postboxes are in based on the current
608
+
* orientation of the browser.
609
+
*
610
+
* @since 3.3.0
611
+
* @access private
612
+
*
613
+
* @memberof postboxes
614
+
*
615
+
* @return {void}
616
+
*/
617
+
_pb_change : function() {
618
+
var check = $( 'label.columns-prefs-1 input[type="radio"]' );
619
+
620
+
switch ( window.orientation ) {
621
+
case 90:
622
+
case -90:
623
+
if ( !check.length || !check.is(':checked') )
624
+
this._pb_edit(2);
625
+
break;
626
+
case 0:
627
+
case 180:
628
+
if ( $( '#poststuff' ).length ) {
629
+
this._pb_edit(1);
630
+
} else {
631
+
if ( !check.length || !check.is(':checked') )
632
+
this._pb_edit(2);
633
+
}
634
+
break;
635
+
}
636
+
},
637
+
638
+
/* Callbacks */
639
+
640
+
/**
641
+
* @since 2.7.0
642
+
* @access public
643
+
*
644
+
* @property {Function|boolean} pbshow A callback that is called when a postbox
645
+
* is opened.
646
+
* @memberof postboxes
647
+
*/
648
+
pbshow : false,
649
+
650
+
/**
651
+
* @since 2.7.0
652
+
* @access public
653
+
* @property {Function|boolean} pbhide A callback that is called when a postbox
654
+
* is closed.
655
+
* @memberof postboxes
656
+
*/
657
+
pbhide : false
658
+
};
659
+
660
+
}(jQuery));
661
+