29 | | /** |
30 | | * Bootstrap functionality. |
31 | | */ |
32 | | self.init = function() { |
33 | | var self = this; |
| 24 | utils = api.NavMenusCustomizerPreview = { |
| 25 | |
| 26 | refreshDebounced: function( instance ) { |
| 27 | if ( debouncedCalls[ instance ] ) { |
| 28 | window.clearTimeout( debouncedCalls[ instance ] ); |
| 29 | } |
| 30 | debouncedCalls[ instance ] = window.setTimeout( _.bind( function() { |
| 31 | this.refreshMenuInstance( instance ); |
| 32 | }, this ), refreshDelay ); |
| 33 | }, |
45 | | api.preview.bind( 'setting', function( args ) { |
46 | | var id, value, setting; |
47 | | args = args.slice(); |
48 | | id = args.shift(); |
49 | | value = args.shift(); |
50 | | if ( ! api.has( id ) ) { |
51 | | // Currently customize-preview.js is not creating settings for dynamically-created settings in the pane; so we have to do it |
52 | | setting = api.create( id, value ); // @todo This should be in core |
53 | | setting.id = id; |
54 | | if ( self.bindListener( setting ) ) { |
55 | | setting.callbacks.fireWith( setting, [ setting(), setting() ] ); |
56 | | } |
| 50 | _.each( settings.args, function( args, instance ) { |
| 51 | if ( menuId === args.menu || -1 !== _.indexOf( locations, args.theme_location ) ) { |
| 52 | this.refreshDebounced( instance ); |
84 | | matches = setting.id.match( /^nav_menu_locations\[(.+?)]/ ); |
85 | | if ( matches ) { |
86 | | themeLocation = matches[1]; |
87 | | setting.bind( function() { |
88 | | self.refreshMenuLocation( themeLocation ); |
| 72 | /** |
| 73 | * Update a specific instance of a given menu on the page. |
| 74 | * |
| 75 | * @param {int} instance |
| 76 | */ |
| 77 | refreshMenuInstance : function( instance ) { |
| 78 | var data, customized, container, wpNavArgs; |
| 79 | |
| 80 | if ( ! settings.args[ instance ] ) { |
| 81 | throw new Error( 'unknown_instance_number' ); |
| 82 | } |
| 83 | |
| 84 | container = $( '#partial-refresh-menu-container-' + instance ); |
| 85 | |
| 86 | if ( ! settings.args[ instance ].can_partial_refresh || 0 === container.length ) { |
| 87 | api.preview.send( 'refresh' ); |
| 88 | return; |
| 89 | } |
| 90 | |
| 91 | data = { |
| 92 | nonce: settings.previewCustomizeNonce, |
| 93 | wp_customize: 'on' |
| 94 | }; |
| 95 | if ( ! settings.theme.active ) { |
| 96 | data.theme = settings.theme.stylesheet; |
| 97 | } |
| 98 | data[ settings.renderQueryVar ] = '1'; |
| 99 | |
| 100 | customized = {}; |
| 101 | api.each( function( setting, id ) { |
| 102 | // @todo We need to limit this to just the menu items that are associated with this menu/location. |
| 103 | if ( /^(nav_menu|nav_menu_locations)/.test( id ) ) { |
| 104 | customized[ id ] = setting.get(); |
| 105 | } |
109 | | /** |
110 | | * Handle changing of a nav_menu_item setting. |
111 | | * |
112 | | * @this {wp.customize.Setting} |
113 | | * @param {object} to |
114 | | * @param {object} from |
115 | | */ |
116 | | self.onChangeNavMenuItemSetting = function( to, from ) { |
117 | | if ( from && from.nav_menu_term_id && ( ! to || from.nav_menu_term_id !== to.nav_menu_term_id ) ) { |
118 | | self.refreshMenu( from.nav_menu_term_id ); |
119 | | } |
120 | | if ( to && to.nav_menu_term_id ) { |
121 | | self.refreshMenu( to.nav_menu_term_id ); |
122 | | } |
123 | | }; |
| 117 | wp.ajax.send( null, { |
| 118 | data: data, |
| 119 | url: settings.requestUri |
| 120 | } ) |
| 121 | .done( function( data ) { |
| 122 | var eventParam; |
| 123 | container.empty().append( $( data ) ); |
| 124 | eventParam = { |
| 125 | instanceNumber: instance, |
| 126 | wpNavArgs: wpNavArgs |
| 127 | }; |
| 128 | $( document ).trigger( 'customize-preview-menu-refreshed', [ eventParam ] ); |
| 129 | } ) |
| 130 | .fail( function() { |
| 131 | // @todo provide some indication for why |
| 132 | } ) |
| 133 | .always( function() { |
| 134 | container.removeClass( 'customize-partial-refreshing' ); |
| 135 | } ); |
| 136 | }, |
133 | | api.each(function( setting, id ) { |
134 | | var matches = id.match( /^nav_menu_locations\[(.+?)]/ ); |
135 | | if ( matches && menuId === setting() ) { |
136 | | assignedLocations.push( matches[1] ); |
| 146 | matches = setting.id.match( /^nav_menu\[(-?\d+)]$/ ); |
| 147 | if ( matches ) { |
| 148 | setting.navMenuId = parseInt( matches[1], 10 ); |
| 149 | setting.bind( function() { |
| 150 | if ( ! this.navMenuId ) { |
| 151 | throw new Error( 'Expected navMenuId property to be set.' ); |
| 152 | } |
| 153 | utils.refreshMenu( this.navMenuId ); |
| 154 | } ); |
| 155 | return true; |
140 | | _.each( self.navMenuInstanceArgs, function( navMenuArgs, instanceNumber ) { |
141 | | if ( menuId === navMenuArgs.menu || -1 !== _.indexOf( assignedLocations, navMenuArgs.theme_location ) ) { |
142 | | self.refreshMenuInstanceDebounced( instanceNumber ); |
| 158 | matches = setting.id.match( /^nav_menu_item\[(-?\d+)]$/ ); |
| 159 | if ( matches ) { |
| 160 | setting.navMenuItemId = parseInt( matches[1], 10 ); |
| 161 | setting.bind( function( to, from ) { |
| 162 | if ( from && from.nav_menu_term_id && |
| 163 | ( ! to || from.nav_menu_term_id !== to.nav_menu_term_id ) ) { |
| 164 | utils.refreshMenu( from.nav_menu_term_id ); |
| 165 | } |
| 166 | if ( to && to.nav_menu_term_id ) { |
| 167 | utils.refreshMenu( to.nav_menu_term_id ); |
| 168 | } |
| 169 | } ); |
| 170 | return true; |
147 | | self.refreshMenuLocation = function( location ) { |
148 | | var foundInstance = false; |
149 | | _.each( self.navMenuInstanceArgs, function( navMenuArgs, instanceNumber ) { |
150 | | if ( location === navMenuArgs.theme_location ) { |
151 | | self.refreshMenuInstanceDebounced( instanceNumber ); |
152 | | foundInstance = true; |
| 173 | matches = setting.id.match( /^nav_menu_locations\[(.+?)]/ ); |
| 174 | if ( matches ) { |
| 175 | themeLocation = matches[1]; |
| 176 | setting.bind( function() { |
| 177 | utils.refreshMenuLocation( themeLocation ); |
| 178 | } ); |
| 179 | return true; |
160 | | /** |
161 | | * Update a specific instance of a given menu on the page. |
162 | | * |
163 | | * @param {int} instanceNumber |
164 | | */ |
165 | | self.refreshMenuInstance = function( instanceNumber ) { |
166 | | var self = this, data, customized, container, request, wpNavArgs, instance; |
167 | | |
168 | | if ( ! self.navMenuInstanceArgs[ instanceNumber ] ) { |
169 | | throw new Error( 'unknown_instance_number' ); |
| 186 | api.bind( 'preview-ready', function() { |
| 187 | if ( 'undefined' !== typeof _wpCustomizePreviewNavMenus ) { |
| 188 | $.extend( settings, _wpCustomizePreviewNavMenus ); |
198 | | wpNavArgs = $.extend( {}, instance ); |
199 | | data.wp_nav_menu_args_hash = wpNavArgs.args_hash; |
200 | | delete wpNavArgs.args_hash; |
201 | | data.wp_nav_menu_args = JSON.stringify( wpNavArgs ); |
202 | | |
203 | | container.addClass( 'customize-partial-refreshing' ); |
204 | | |
205 | | request = wp.ajax.send( null, { |
206 | | data: data, |
207 | | url: self.requestUri |
| 196 | api.preview.bind( 'setting', function( args ) { |
| 197 | var id, value, setting; |
| 198 | args = args.slice(); |
| 199 | id = args.shift(); |
| 200 | value = args.shift(); |
| 201 | if ( ! api.has( id ) ) { |
| 202 | // Currently customize-preview.js is not creating settings for dynamically-created settings in the pane; so we have to do it |
| 203 | setting = api.create( id, value ); // @todo This should be in core |
| 204 | setting.id = id; |
| 205 | if ( utils.bindListener( setting ) ) { |
| 206 | setting.callbacks.fireWith( setting, [ setting(), setting() ] ); |
| 207 | } |
| 208 | } |
209 | | request.done( function( data ) { |
210 | | var eventParam; |
211 | | container.empty().append( $( data ) ); |
212 | | eventParam = { |
213 | | instanceNumber: instanceNumber, |
214 | | wpNavArgs: wpNavArgs |
215 | | }; |
216 | | $( document ).trigger( 'customize-preview-menu-refreshed', [ eventParam ] ); |
217 | | } ); |
218 | | request.fail( function() { |
219 | | // @todo provide some indication for why |
220 | | } ); |
221 | | request.always( function() { |
222 | | container.removeClass( 'customize-partial-refreshing' ); |
223 | | } ); |
224 | | }; |
| 210 | } ); |