Diff: STRATO-apps/wordpress_03/app/wp-includes/js/admin-bar.js
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
/**
2
+
* @output wp-includes/js/admin-bar.js
3
+
*/
4
+
/**
5
+
* Admin bar with Vanilla JS, no external dependencies.
6
+
*
7
+
* @since 5.3.1
8
+
*
9
+
* @param {Object} document The document object.
10
+
* @param {Object} window The window object.
11
+
* @param {Object} navigator The navigator object.
12
+
*
13
+
* @return {void}
14
+
*/
15
+
( function( document, window, navigator ) {
16
+
document.addEventListener( 'DOMContentLoaded', function() {
17
+
var adminBar = document.getElementById( 'wpadminbar' ),
18
+
topMenuItems,
19
+
allMenuItems,
20
+
adminBarLogout,
21
+
adminBarSearchForm,
22
+
shortlink,
23
+
skipLink,
24
+
mobileEvent,
25
+
adminBarSearchInput,
26
+
i;
27
+
28
+
if ( ! adminBar || ! ( 'querySelectorAll' in adminBar ) ) {
29
+
return;
30
+
}
31
+
32
+
topMenuItems = adminBar.querySelectorAll( 'li.menupop' );
33
+
allMenuItems = adminBar.querySelectorAll( '.ab-item' );
34
+
adminBarLogout = document.querySelector( '#wp-admin-bar-logout a' );
35
+
adminBarSearchForm = document.getElementById( 'adminbarsearch' );
36
+
shortlink = document.getElementById( 'wp-admin-bar-get-shortlink' );
37
+
skipLink = adminBar.querySelector( '.screen-reader-shortcut' );
38
+
mobileEvent = /Mobile\/.+Safari/.test( navigator.userAgent ) ? 'touchstart' : 'click';
39
+
40
+
// Remove nojs class after the DOM is loaded.
41
+
removeClass( adminBar, 'nojs' );
42
+
43
+
if ( 'ontouchstart' in window ) {
44
+
// Remove hover class when the user touches outside the menu items.
45
+
document.body.addEventListener( mobileEvent, function( e ) {
46
+
if ( ! getClosest( e.target, 'li.menupop' ) ) {
47
+
removeAllHoverClass( topMenuItems );
48
+
}
49
+
} );
50
+
51
+
// Add listener for menu items to toggle hover class by touches.
52
+
// Remove the callback later for better performance.
53
+
adminBar.addEventListener( 'touchstart', function bindMobileEvents() {
54
+
for ( var i = 0; i < topMenuItems.length; i++ ) {
55
+
topMenuItems[i].addEventListener( 'click', mobileHover.bind( null, topMenuItems ) );
56
+
}
57
+
58
+
adminBar.removeEventListener( 'touchstart', bindMobileEvents );
59
+
} );
60
+
}
61
+
62
+
// Scroll page to top when clicking on the admin bar.
63
+
adminBar.addEventListener( 'click', scrollToTop );
64
+
65
+
for ( i = 0; i < topMenuItems.length; i++ ) {
66
+
// Adds or removes the hover class based on the hover intent.
67
+
window.hoverintent(
68
+
topMenuItems[i],
69
+
addClass.bind( null, topMenuItems[i], 'hover' ),
70
+
removeClass.bind( null, topMenuItems[i], 'hover' )
71
+
).options( {
72
+
timeout: 180
73
+
} );
74
+
75
+
// Toggle hover class if the enter key is pressed.
76
+
topMenuItems[i].addEventListener( 'keydown', toggleHoverIfEnter );
77
+
}
78
+
79
+
// Remove hover class if the escape key is pressed.
80
+
for ( i = 0; i < allMenuItems.length; i++ ) {
81
+
allMenuItems[i].addEventListener( 'keydown', removeHoverIfEscape );
82
+
}
83
+
84
+
if ( adminBarSearchForm ) {
85
+
adminBarSearchInput = document.getElementById( 'adminbar-search' );
86
+
87
+
// Adds the adminbar-focused class on focus.
88
+
adminBarSearchInput.addEventListener( 'focus', function() {
89
+
addClass( adminBarSearchForm, 'adminbar-focused' );
90
+
} );
91
+
92
+
// Removes the adminbar-focused class on blur.
93
+
adminBarSearchInput.addEventListener( 'blur', function() {
94
+
removeClass( adminBarSearchForm, 'adminbar-focused' );
95
+
} );
96
+
}
97
+
98
+
if ( shortlink ) {
99
+
shortlink.addEventListener( 'click', clickShortlink );
100
+
}
101
+
102
+
// Prevents the toolbar from covering up content when a hash is present in the URL.
103
+
if ( window.location.hash ) {
104
+
window.scrollBy( 0, -32 );
105
+
}
106
+
107
+
// Clear sessionStorage on logging out.
108
+
if ( adminBarLogout ) {
109
+
adminBarLogout.addEventListener( 'click', emptySessionStorage );
110
+
}
111
+
} );
112
+
113
+
/**
114
+
* Remove hover class for top level menu item when escape is pressed.
115
+
*
116
+
* @since 5.3.1
117
+
*
118
+
* @param {Event} event The keydown event.
119
+
*/
120
+
function removeHoverIfEscape( event ) {
121
+
var wrapper;
122
+
123
+
if ( event.which !== 27 ) {
124
+
return;
125
+
}
126
+
127
+
wrapper = getClosest( event.target, '.menupop' );
128
+
129
+
if ( ! wrapper ) {
130
+
return;
131
+
}
132
+
133
+
wrapper.querySelector( '.menupop > .ab-item' ).focus();
134
+
removeClass( wrapper, 'hover' );
135
+
}
136
+
137
+
/**
138
+
* Toggle hover class for top level menu item when enter is pressed.
139
+
*
140
+
* @since 5.3.1
141
+
*
142
+
* @param {Event} event The keydown event.
143
+
*/
144
+
function toggleHoverIfEnter( event ) {
145
+
var wrapper;
146
+
147
+
// Follow link if pressing Ctrl and/or Shift with Enter (opening in a new tab or window).
148
+
if ( event.which !== 13 || event.ctrlKey || event.shiftKey ) {
149
+
return;
150
+
}
151
+
152
+
if ( !! getClosest( event.target, '.ab-sub-wrapper' ) ) {
153
+
return;
154
+
}
155
+
156
+
wrapper = getClosest( event.target, '.menupop' );
157
+
158
+
if ( ! wrapper ) {
159
+
return;
160
+
}
161
+
162
+
event.preventDefault();
163
+
164
+
if ( hasClass( wrapper, 'hover' ) ) {
165
+
removeClass( wrapper, 'hover' );
166
+
} else {
167
+
addClass( wrapper, 'hover' );
168
+
}
169
+
}
170
+
171
+
/**
172
+
* Toggle hover class for mobile devices.
173
+
*
174
+
* @since 5.3.1
175
+
*
176
+
* @param {NodeList} topMenuItems All menu items.
177
+
* @param {Event} event The click event.
178
+
*/
179
+
function mobileHover( topMenuItems, event ) {
180
+
var wrapper;
181
+
182
+
if ( !! getClosest( event.target, '.ab-sub-wrapper' ) ) {
183
+
return;
184
+
}
185
+
186
+
event.preventDefault();
187
+
188
+
wrapper = getClosest( event.target, '.menupop' );
189
+
190
+
if ( ! wrapper ) {
191
+
return;
192
+
}
193
+
194
+
if ( hasClass( wrapper, 'hover' ) ) {
195
+
removeClass( wrapper, 'hover' );
196
+
} else {
197
+
removeAllHoverClass( topMenuItems );
198
+
addClass( wrapper, 'hover' );
199
+
}
200
+
}
201
+
202
+
/**
203
+
* Handles the click on the Shortlink link in the adminbar.
204
+
*
205
+
* @since 3.1.0
206
+
* @since 5.3.1 Use querySelector to clean up the function.
207
+
*
208
+
* @param {Event} event The click event.
209
+
* @return {boolean} Returns false to prevent default click behavior.
210
+
*/
211
+
function clickShortlink( event ) {
212
+
var wrapper = event.target.parentNode,
213
+
input;
214
+
215
+
if ( wrapper ) {
216
+
input = wrapper.querySelector( '.shortlink-input' );
217
+
}
218
+
219
+
if ( ! input ) {
220
+
return;
221
+
}
222
+
223
+
// (Old) IE doesn't support preventDefault, and does support returnValue.
224
+
if ( event.preventDefault ) {
225
+
event.preventDefault();
226
+
}
227
+
228
+
event.returnValue = false;
229
+
230
+
addClass( wrapper, 'selected' );
231
+
232
+
input.focus();
233
+
input.select();
234
+
input.onblur = function() {
235
+
removeClass( wrapper, 'selected' );
236
+
};
237
+
238
+
return false;
239
+
}
240
+
241
+
/**
242
+
* Clear sessionStorage on logging out.
243
+
*
244
+
* @since 5.3.1
245
+
*/
246
+
function emptySessionStorage() {
247
+
if ( 'sessionStorage' in window ) {
248
+
try {
249
+
for ( var key in sessionStorage ) {
250
+
if ( key.indexOf( 'wp-autosave-' ) > -1 ) {
251
+
sessionStorage.removeItem( key );
252
+
}
253
+
}
254
+
} catch ( er ) {}
255
+
}
256
+
}
257
+
258
+
/**
259
+
* Check if element has class.
260
+
*
261
+
* @since 5.3.1
262
+
*
263
+
* @param {HTMLElement} element The HTML element.
264
+
* @param {string} className The class name.
265
+
* @return {boolean} Whether the element has the className.
266
+
*/
267
+
function hasClass( element, className ) {
268
+
var classNames;
269
+
270
+
if ( ! element ) {
271
+
return false;
272
+
}
273
+
274
+
if ( element.classList && element.classList.contains ) {
275
+
return element.classList.contains( className );
276
+
} else if ( element.className ) {
277
+
classNames = element.className.split( ' ' );
278
+
return classNames.indexOf( className ) > -1;
279
+
}
280
+
281
+
return false;
282
+
}
283
+
284
+
/**
285
+
* Add class to an element.
286
+
*
287
+
* @since 5.3.1
288
+
*
289
+
* @param {HTMLElement} element The HTML element.
290
+
* @param {string} className The class name.
291
+
*/
292
+
function addClass( element, className ) {
293
+
if ( ! element ) {
294
+
return;
295
+
}
296
+
297
+
if ( element.classList && element.classList.add ) {
298
+
element.classList.add( className );
299
+
} else if ( ! hasClass( element, className ) ) {
300
+
if ( element.className ) {
301
+
element.className += ' ';
302
+
}
303
+
304
+
element.className += className;
305
+
}
306
+
307
+
var menuItemToggle = element.querySelector( 'a' );
308
+
if ( className === 'hover' && menuItemToggle && menuItemToggle.hasAttribute( 'aria-expanded' ) ) {
309
+
menuItemToggle.setAttribute( 'aria-expanded', 'true' );
310
+
}
311
+
}
312
+
313
+
/**
314
+
* Remove class from an element.
315
+
*
316
+
* @since 5.3.1
317
+
*
318
+
* @param {HTMLElement} element The HTML element.
319
+
* @param {string} className The class name.
320
+
*/
321
+
function removeClass( element, className ) {
322
+
var testName,
323
+
classes;
324
+
325
+
if ( ! element || ! hasClass( element, className ) ) {
326
+
return;
327
+
}
328
+
329
+
if ( element.classList && element.classList.remove ) {
330
+
element.classList.remove( className );
331
+
} else {
332
+
testName = ' ' + className + ' ';
333
+
classes = ' ' + element.className + ' ';
334
+
335
+
while ( classes.indexOf( testName ) > -1 ) {
336
+
classes = classes.replace( testName, '' );
337
+
}
338
+
339
+
element.className = classes.replace( /^[\s]+|[\s]+$/g, '' );
340
+
}
341
+
342
+
var menuItemToggle = element.querySelector( 'a' );
343
+
if ( className === 'hover' && menuItemToggle && menuItemToggle.hasAttribute( 'aria-expanded' ) ) {
344
+
menuItemToggle.setAttribute( 'aria-expanded', 'false' );
345
+
}
346
+
}
347
+
348
+
/**
349
+
* Remove hover class for all menu items.
350
+
*
351
+
* @since 5.3.1
352
+
*
353
+
* @param {NodeList} topMenuItems All menu items.
354
+
*/
355
+
function removeAllHoverClass( topMenuItems ) {
356
+
if ( topMenuItems && topMenuItems.length ) {
357
+
for ( var i = 0; i < topMenuItems.length; i++ ) {
358
+
removeClass( topMenuItems[i], 'hover' );
359
+
}
360
+
}
361
+
}
362
+
363
+
/**
364
+
* Scrolls to the top of the page.
365
+
*
366
+
* @since 3.4.0
367
+
*
368
+
* @param {Event} event The Click event.
369
+
*
370
+
* @return {void}
371
+
*/
372
+
function scrollToTop( event ) {
373
+
// Only scroll when clicking on the wpadminbar, not on menus or submenus.
374
+
if (
375
+
event.target &&
376
+
event.target.id !== 'wpadminbar' &&
377
+
event.target.id !== 'wp-admin-bar-top-secondary'
378
+
) {
379
+
return;
380
+
}
381
+
382
+
try {
383
+
window.scrollTo( {
384
+
top: -32,
385
+
left: 0,
386
+
behavior: 'smooth'
387
+
} );
388
+
} catch ( er ) {
389
+
window.scrollTo( 0, -32 );
390
+
}
391
+
}
392
+
393
+
/**
394
+
* Get closest Element.
395
+
*
396
+
* @since 5.3.1
397
+
*
398
+
* @param {HTMLElement} el Element to get parent.
399
+
* @param {string} selector CSS selector to match.
400
+
*/
401
+
function getClosest( el, selector ) {
402
+
if ( ! window.Element.prototype.matches ) {
403
+
// Polyfill from https://developer.mozilla.org/en-US/docs/Web/API/Element/matches.
404
+
window.Element.prototype.matches =
405
+
window.Element.prototype.matchesSelector ||
406
+
window.Element.prototype.mozMatchesSelector ||
407
+
window.Element.prototype.msMatchesSelector ||
408
+
window.Element.prototype.oMatchesSelector ||
409
+
window.Element.prototype.webkitMatchesSelector ||
410
+
function( s ) {
411
+
var matches = ( this.document || this.ownerDocument ).querySelectorAll( s ),
412
+
i = matches.length;
413
+
414
+
while ( --i >= 0 && matches.item( i ) !== this ) { }
415
+
416
+
return i > -1;
417
+
};
418
+
}
419
+
420
+
// Get the closest matching elent.
421
+
for ( ; el && el !== document; el = el.parentNode ) {
422
+
if ( el.matches( selector ) ) {
423
+
return el;
424
+
}
425
+
}
426
+
427
+
return null;
428
+
}
429
+
430
+
} )( document, window, navigator );
431
+