Make WordPress Core

source: branches/5.0/src/wp-content/themes/twentynineteen/js/priority-menu.js @ 43904

Last change on this file since 43904 was 43904, checked in by allancole, 6 years ago

Updating Twenty Nineteen, our new default theme for 2019, set for 5.0.

This update changes the following:

  • Improve menu UI to support keyboard navigation in both directions
  • Improve more-menu-link visibility when no menu items are hidden
  • Improve text-selection custom colors for better contrast and legibility
  • Improve support for sticky toolbars in the editor
  • Improve table element fonts
  • Add .button class support
  • Remove translation escaping
  • Fix menu JS to prevent unused touched event listeners
  • Fix duplicate more-menu-link issue on selective refresh in the customizer
  • Fix editor font-weights for headings
  • Fix search form input style
  • Fix nested blockquote styles
  • Fix download block button style when download text stretches more than one line
  • Fix audio block centering issue
  • Fix align-full blocks in the editor so they don’t create horizontal scrollbars
  • Fix editor to prevent Gutenberg's meta boxes area from overlapping the content

Initial development occurred on GitHub. See: https://github.com/WordPress/twentynineteen

Props allancole, karmatosed, kjellr, yingling017, mrasharirfan, milana_cap, fabiankaegy, westonruter, aaronjorbin, ntwb, b-07, khleomix, audrasjb, nielslange, mmaumio, richsalvucci, littlebigthing, dimadin, joyously, anevins12, peterwilsoncc, DannyCooper, WPprodigy, siriokun, briannaorg, 00travelgirl00, shahjehanali1, ianbelanger79, nadim1992, Ismail-elkorchi, nativeinside, iamchetanp, grappler, ocean90, joshfeck, frankew, abdulwahab610, mendezcode, eliorivero, melchoyce, jasmussen, laurelfulford, mdawaffe, kraftbj, dereksmart, naokomc, mayukojpn, enodekciw, chetansatasiya, ketuchetan, atanas-angelov-dev, carolinan, sharazghouri, artisan-asad, mukeshpanchal27, mukesh27, burhandodhy, @crunnells, aryaprakasa, tlxo, themeroots, whizbangik, yingles, tlxo, youthkee, brentswisher, smy315, ahmadawais, desi-developer, 2ndkauboy, mor10.

File size: 4.7 KB
Line 
1(function() {
2
3        /**
4         * Debounce
5         *
6         * @param {Function} func
7         * @param {number} wait
8         * @param {boolean} immediate
9         */
10        function debounce(func, wait, immediate) {
11                'use strict';
12
13                var timeout;
14                wait      = (typeof wait !== 'undefined') ? wait : 20;
15                immediate = (typeof immediate !== 'undefined') ? immediate : true;
16
17                return function() {
18
19                        var context = this, args = arguments;
20                        var later = function() {
21                                timeout = null;
22
23                                if (!immediate) {
24                                        func.apply(context, args);
25                                }
26                        };
27
28                        var callNow = immediate && !timeout;
29
30                        clearTimeout(timeout);
31                        timeout = setTimeout(later, wait);
32
33                        if (callNow) {
34                                func.apply(context, args);
35                        }
36                };
37        }
38
39        /**
40         * Prepends an element to a container.
41         *
42         * @param {Element} container
43         * @param {Element} element
44         */
45        function prependElement(container, element) {
46                if (container.firstChild.nextSibling) {
47                        return container.insertBefore(element, container.firstChild.nextSibling);
48                } else {
49                        return container.appendChild(element);
50                }
51        }
52
53        /**
54         * Shows an element by adding a hidden className.
55         *
56         * @param {Element} element
57         */
58        function showButton(element) {
59                // classList.remove is not supported in IE11
60                element.className = element.className.replace('is-empty', '');
61        }
62
63        /**
64         * Hides an element by removing the hidden className.
65         *
66         * @param {Element} element
67         */
68        function hideButton(element) {
69                // classList.add is not supported in IE11
70                if (!element.classList.contains('is-empty')) {
71                        element.className += ' is-empty';
72                }
73        }
74
75        /**
76         * Returns the currently available space in the menu container.
77         *
78         * @returns {number} Available space
79         */
80        function getAvailableSpace( button, container ) {
81                return container.offsetWidth - button.offsetWidth - 50;
82        }
83
84        /**
85         * Returns whether the current menu is overflowing or not.
86         *
87         * @returns {boolean} Is overflowing
88         */
89        function isOverflowingNavivation( list, button, container ) {
90                return list.offsetWidth > getAvailableSpace( button, container );
91        }
92
93        /**
94         * Set menu container variable
95         */
96        var navContainer = document.querySelector('.main-navigation');
97        var breaks       = [];
98
99        /**
100         * Refreshes the list item from the menu depending on the menu size
101         */
102        function updateNavigationMenu( container ) {
103
104                // Adds the necessary UI to operate the menu.
105                var visibleList  = container.parentNode.querySelector('.main-menu[id]');
106                var hiddenList   = visibleList.parentNode.nextElementSibling.querySelector('.hidden-links');
107                var toggleButton = visibleList.parentNode.nextElementSibling.querySelector('.main-menu-more-toggle');
108
109                if ( isOverflowingNavivation( visibleList, toggleButton, container ) ) {
110
111                        // Record the width of the list
112                        breaks.push( visibleList.offsetWidth );
113                        // Move last item to the hidden list
114                        prependElement( hiddenList, ! visibleList.lastChild || null === visibleList.lastChild ? visibleList.previousElementSibling : visibleList.lastChild );
115                        // Show the toggle button
116                        showButton( toggleButton );
117
118                } else {
119
120                        // There is space for another item in the nav
121                        if ( getAvailableSpace( toggleButton, container ) > breaks[breaks.length - 1] ) {
122                                // Move the item to the visible list
123                                visibleList.appendChild( hiddenList.firstChild.nextSibling );
124                                breaks.pop();
125                        }
126
127                        // Hide the dropdown btn if hidden list is empty
128                        if (breaks.length < 2) {
129                                hideButton( toggleButton );
130                        }
131                }
132
133                // Recur if the visible list is still overflowing the nav
134                if ( isOverflowingNavivation( visibleList, toggleButton, container ) ) {
135                        updateNavigationMenu( container );
136                }
137        }
138
139        /**
140         * Run our priority+ function as soon as the document is `ready`
141         */
142        document.addEventListener( 'DOMContentLoaded', function() {
143
144                updateNavigationMenu( navContainer );
145
146                // Also, run our priority+ function on selective refresh in the customizer
147                var hasSelectiveRefresh = (
148                        'undefined' !== typeof wp &&
149                        wp.customize &&
150                        wp.customize.selectiveRefresh
151                );
152
153                if ( hasSelectiveRefresh ) {
154                        // Force a full refresh on partial content renders to re-run updateNavigationMenu()
155                        wp.customize.selectiveRefresh.bind('partial-content-rendered', function () {
156                                wp.customize.preview.send('refresh');
157                        });
158        }
159        });
160
161        /**
162         * Run our priority+ function on load
163         */
164        window.addEventListener('load', function() {
165                updateNavigationMenu( navContainer );
166        });
167
168        /**
169         * Run our priority+ function every time the window resizes
170         */
171        var isResizing = false;
172        window.addEventListener( 'resize',
173                debounce( function() {
174                        if ( isResizing ) {
175                                return;
176                        }
177
178                        isResizing = true;
179                        setTimeout( function() {
180                                updateNavigationMenu( navContainer );
181                                isResizing = false;
182                        }, 150 );
183                } )
184        );
185
186        /**
187         * Run our priority+ function
188         */
189        updateNavigationMenu( navContainer );
190
191})();
Note: See TracBrowser for help on using the repository browser.