Changeset 36889 for trunk/src/wp-includes/js/customize-preview-nav-menus.js
- Timestamp:
- 03/09/2016 12:08:51 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/js/customize-preview-nav-menus.js
r36586 r36889 1 /* global _wpCustomizePreviewNavMenusExports */ 1 2 wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function( $, _, wp, api ) { 2 3 'use strict'; 3 4 4 var self = {}; 5 var self = { 6 data: { 7 navMenuInstanceArgs: {} 8 } 9 }; 10 if ( 'undefined' !== typeof _wpCustomizePreviewNavMenusExports ) { 11 _.extend( self.data, _wpCustomizePreviewNavMenusExports ); 12 } 5 13 6 14 /** … … 11 19 12 20 if ( api.selectiveRefresh ) { 13 self.watchNavMenuLocationChanges(); 21 // Listen for changes to settings related to nav menus. 22 api.each( function( setting ) { 23 self.bindSettingListener( setting ); 24 } ); 25 api.bind( 'add', function( setting ) { 26 self.bindSettingListener( setting, { fire: true } ); 27 } ); 28 api.bind( 'remove', function( setting ) { 29 self.unbindSettingListener( setting ); 30 } ); 31 32 /* 33 * Ensure that wp_nav_menu() instances nested inside of other partials 34 * will be recognized as being present on the page. 35 */ 36 api.selectiveRefresh.bind( 'render-partials-response', function( response ) { 37 if ( response.nav_menu_instance_args ) { 38 _.extend( self.data.navMenuInstanceArgs, response.nav_menu_instance_args ); 39 } 40 } ); 14 41 } 15 42 … … 129 156 130 157 /** 158 * Make sure that partial fallback behavior is invoked if there is no associated menu. 159 * 160 * @since 4.5.0 161 * 162 * @returns {Promise} 163 */ 164 refresh: function() { 165 var partial = this, menuId, deferred = $.Deferred(); 166 167 // Make sure the fallback behavior is invoked when the partial is no longer associated with a menu. 168 if ( _.isNumber( partial.params.navMenuArgs.menu ) ) { 169 menuId = partial.params.navMenuArgs.menu; 170 } else if ( partial.params.navMenuArgs.theme_location && api.has( 'nav_menu_locations[' + partial.params.navMenuArgs.theme_location + ']' ) ) { 171 menuId = api( 'nav_menu_locations[' + partial.params.navMenuArgs.theme_location + ']' ).get(); 172 } 173 if ( ! menuId ) { 174 partial.fallback(); 175 deferred.reject(); 176 return deferred.promise(); 177 } 178 179 return api.selectiveRefresh.Partial.prototype.refresh.call( partial ); 180 }, 181 182 /** 131 183 * Render content. 132 184 * … … 136 188 renderContent: function( placement ) { 137 189 var partial = this, previousContainer = placement.container; 190 191 // Do fallback behavior to refresh preview if menu is now empty. 192 if ( '' === placement.addedContent ) { 193 placement.partial.fallback(); 194 } 195 138 196 if ( api.selectiveRefresh.Partial.prototype.renderContent.call( partial, placement ) ) { 139 197 … … 153 211 154 212 /** 155 * Watch for changes to nav_menu_locations[] settings. 156 * 157 * Refresh partials associated with the given nav_menu_locations[] setting, 158 * or request an entire preview refresh if there are no containers in the 159 * document for a partial associated with the theme location. 160 * 161 * @since 4.5.0 162 */ 163 self.watchNavMenuLocationChanges = function() { 164 api.bind( 'change', function( setting ) { 165 var themeLocation, themeLocationPartialFound = false, matches = setting.id.match( /^nav_menu_locations\[(.+)]$/ ); 166 if ( ! matches ) { 213 * Request full refresh if there are nav menu instances that lack partials which also match the supplied args. 214 * 215 * @param {object} navMenuInstanceArgs 216 */ 217 self.handleUnplacedNavMenuInstances = function( navMenuInstanceArgs ) { 218 var unplacedNavMenuInstances; 219 unplacedNavMenuInstances = _.filter( _.values( self.data.navMenuInstanceArgs ), function( args ) { 220 return ! api.selectiveRefresh.partial.has( 'nav_menu_instance[' + args.args_hmac + ']' ); 221 } ); 222 if ( _.findWhere( unplacedNavMenuInstances, navMenuInstanceArgs ) ) { 223 api.selectiveRefresh.requestFullRefresh(); 224 return true; 225 } 226 return false; 227 }; 228 229 /** 230 * Add change listener for a nav_menu[], nav_menu_item[], or nav_menu_locations[] setting. 231 * 232 * @since 4.5.0 233 * 234 * @param {wp.customize.Value} setting 235 * @param {object} [options] 236 * @param {boolean} options.fire Whether to invoke the callback after binding. 237 * This is used when a dynamic setting is added. 238 * @return {boolean} Whether the setting was bound. 239 */ 240 self.bindSettingListener = function( setting, options ) { 241 var matches; 242 options = options || {}; 243 244 matches = setting.id.match( /^nav_menu\[(-?\d+)]$/ ); 245 if ( matches ) { 246 setting._navMenuId = parseInt( matches[1], 10 ); 247 setting.bind( this.onChangeNavMenuSetting ); 248 if ( options.fire ) { 249 this.onChangeNavMenuSetting.call( setting, setting(), false ); 250 } 251 return true; 252 } 253 254 matches = setting.id.match( /^nav_menu_item\[(-?\d+)]$/ ); 255 if ( matches ) { 256 setting._navMenuItemId = parseInt( matches[1], 10 ); 257 setting.bind( this.onChangeNavMenuItemSetting ); 258 if ( options.fire ) { 259 this.onChangeNavMenuItemSetting.call( setting, setting(), false ); 260 } 261 return true; 262 } 263 264 matches = setting.id.match( /^nav_menu_locations\[(.+?)]/ ); 265 if ( matches ) { 266 setting._navMenuThemeLocation = matches[1]; 267 setting.bind( this.onChangeNavMenuLocationsSetting ); 268 if ( options.fire ) { 269 this.onChangeNavMenuLocationsSetting.call( setting, setting(), false ); 270 } 271 return true; 272 } 273 274 return false; 275 }; 276 277 /** 278 * Remove change listeners for nav_menu[], nav_menu_item[], or nav_menu_locations[] setting. 279 * 280 * @since 4.5.0 281 * 282 * @param {wp.customize.Value} setting 283 */ 284 self.unbindSettingListener = function( setting ) { 285 setting.unbind( this.onChangeNavMenuSetting ); 286 setting.unbind( this.onChangeNavMenuItemSetting ); 287 setting.unbind( this.onChangeNavMenuLocationsSetting ); 288 }; 289 290 /** 291 * Handle change for nav_menu[] setting for nav menu instances lacking partials. 292 * 293 * @since 4.5.0 294 * 295 * @this {wp.customize.Value} 296 */ 297 self.onChangeNavMenuSetting = function() { 298 var setting = this; 299 300 self.handleUnplacedNavMenuInstances( { 301 menu: setting._navMenuId 302 } ); 303 304 // Ensure all nav menu instances with a theme_location assigned to this menu are handled. 305 api.each( function( otherSetting ) { 306 if ( ! otherSetting._navMenuThemeLocation ) { 167 307 return; 168 308 } 169 themeLocation = matches[1]; 170 api.selectiveRefresh.partial.each( function( partial ) { 171 if ( partial.extended( self.NavMenuInstancePartial ) && partial.params.navMenuArgs.theme_location === themeLocation ) { 172 partial.refresh(); 173 themeLocationPartialFound = true; 174 } 175 } ); 176 177 if ( ! themeLocationPartialFound ) { 178 api.selectiveRefresh.requestFullRefresh(); 179 } 180 } ); 309 if ( setting._navMenuId === otherSetting() ) { 310 self.handleUnplacedNavMenuInstances( { 311 theme_location: otherSetting._navMenuThemeLocation 312 } ); 313 } 314 } ); 315 }; 316 317 /** 318 * Handle change for nav_menu_item[] setting for nav menu instances lacking partials. 319 * 320 * @since 4.5.0 321 * 322 * @param {object} newItem New value for nav_menu_item[] setting. 323 * @param {object} oldItem Old value for nav_menu_item[] setting. 324 * @this {wp.customize.Value} 325 */ 326 self.onChangeNavMenuItemSetting = function( newItem, oldItem ) { 327 var item = newItem || oldItem, navMenuSetting; 328 navMenuSetting = api( 'nav_menu[' + String( item.nav_menu_term_id ) + ']' ); 329 if ( navMenuSetting ) { 330 self.onChangeNavMenuSetting.call( navMenuSetting ); 331 } 332 }; 333 334 /** 335 * Handle change for nav_menu_locations[] setting for nav menu instances lacking partials. 336 * 337 * @since 4.5.0 338 * 339 * @this {wp.customize.Value} 340 */ 341 self.onChangeNavMenuLocationsSetting = function() { 342 var setting = this, hasNavMenuInstance; 343 self.handleUnplacedNavMenuInstances( { 344 theme_location: setting._navMenuThemeLocation 345 } ); 346 347 // If there are no wp_nav_menu() instances that refer to the theme location, do full refresh. 348 hasNavMenuInstance = !! _.findWhere( _.values( self.data.navMenuInstanceArgs ), { 349 theme_location: setting._navMenuThemeLocation 350 } ); 351 if ( ! hasNavMenuInstance ) { 352 api.selectiveRefresh.requestFullRefresh(); 353 } 181 354 }; 182 355 }
Note: See TracChangeset
for help on using the changeset viewer.