]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-includes/js/customize-preview-nav-menus.js
WordPress 4.7-scripts
[autoinstalls/wordpress.git] / wp-includes / js / customize-preview-nav-menus.js
index bd42f5e0817e38878cc468bca393671cda4bfbde..27c525107bcf31044f4cf411bba5d6992082b179 100644 (file)
@@ -15,7 +15,19 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
         * Initialize nav menus preview.
         */
        self.init = function() {
-               var self = this;
+               var self = this, synced = false;
+
+               /*
+                * Keep track of whether we synced to determine whether or not bindSettingListener
+                * should also initially fire the listener. This initial firing needs to wait until
+                * after all of the settings have been synced from the pane in order to prevent
+                * an infinite selective fallback-refresh. Note that this sync handler will be
+                * added after the sync handler in customize-preview.js, so it will be triggered
+                * after all of the settings are added.
+                */
+               api.preview.bind( 'sync', function() {
+                       synced = true;
+               } );
 
                if ( api.selectiveRefresh ) {
                        // Listen for changes to settings related to nav menus.
@@ -23,7 +35,17 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
                                self.bindSettingListener( setting );
                        } );
                        api.bind( 'add', function( setting ) {
-                               self.bindSettingListener( setting, { fire: true } );
+
+                               /*
+                                * Handle case where an invalid nav menu item (one for which its associated object has been deleted)
+                                * is synced from the controls into the preview. Since invalid nav menu items are filtered out from
+                                * being exported to the frontend by the _is_valid_nav_menu_item filter in wp_get_nav_menu_items(),
+                                * the customizer controls will have a nav_menu_item setting where the preview will have none, and
+                                * this can trigger an infinite fallback refresh when the nav menu item lacks any valid items.
+                                */
+                               if ( setting.get() && ! setting.get()._invalid ) {
+                                       self.bindSettingListener( setting, { fire: synced } );
+                               }
                        } );
                        api.bind( 'remove', function( setting ) {
                                self.unbindSettingListener( setting );
@@ -106,7 +128,7 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
                         * @returns {boolean}
                         */
                        isRelatedSetting: function( setting, newValue, oldValue ) {
-                               var partial = this, navMenuLocationSetting, navMenuId, isNavMenuItemSetting;
+                               var partial = this, navMenuLocationSetting, navMenuId, isNavMenuItemSetting, _newValue, _oldValue, urlParser;
                                if ( _.isString( setting ) ) {
                                        setting = api( setting );
                                }
@@ -123,9 +145,29 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
                                 */
                                isNavMenuItemSetting = /^nav_menu_item\[/.test( setting.id );
                                if ( isNavMenuItemSetting && _.isObject( newValue ) && _.isObject( oldValue ) ) {
-                                       delete newValue.type_label;
-                                       delete oldValue.type_label;
-                                       if ( _.isEqual( oldValue, newValue ) ) {
+                                       _newValue = _.clone( newValue );
+                                       _oldValue = _.clone( oldValue );
+                                       delete _newValue.type_label;
+                                       delete _oldValue.type_label;
+
+                                       // Normalize URL scheme when parent frame is HTTPS to prevent selective refresh upon initial page load.
+                                       if ( 'https' === api.preview.scheme.get() ) {
+                                               urlParser = document.createElement( 'a' );
+                                               urlParser.href = _newValue.url;
+                                               urlParser.protocol = 'https:';
+                                               _newValue.url = urlParser.href;
+                                               urlParser.href = _oldValue.url;
+                                               urlParser.protocol = 'https:';
+                                               _oldValue.url = urlParser.href;
+                                       }
+
+                                       // Prevent original_title differences from causing refreshes if title is present.
+                                       if ( newValue.title ) {
+                                               delete _oldValue.original_title;
+                                               delete _newValue.original_title;
+                                       }
+
+                                       if ( _.isEqual( _oldValue, _newValue ) ) {
                                                return false;
                                        }
                                }
@@ -365,6 +407,11 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
        self.highlightControls = function() {
                var selector = '.menu-item';
 
+               // Skip adding highlights if not in the customizer preview iframe.
+               if ( ! api.settings.channel ) {
+                       return;
+               }
+
                // Focus on the menu item control when shift+clicking the menu item.
                $( document ).on( 'click', selector, function( e ) {
                        var navMenuItemParts;