How to use partial method in Cypress

Best JavaScript code snippet using cypress

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

customize-selective-refresh.js

Source: customize-selective-refresh.js Github

copy
1/* global jQuery, JSON, _customizePartialRefreshExports, console */
2
3wp.customize.selectiveRefresh = ( function( $, api ) {
4	'use strict';
5	var self, Partial, Placement;
6
7	self = {
8		ready: $.Deferred(),
9		data: {
10			partials: {},
11			renderQueryVar: '',
12			l10n: {
13				shiftClickToEdit: ''
14			},
15			refreshBuffer: 250
16		},
17		currentRequest: null
18	};
19
20	_.extend( self, api.Events );
21
22	/**
23	 * A Customizer Partial.
24	 *
25	 * A partial provides a rendering of one or more settings according to a template.
26	 *
27	 * @see PHP class WP_Customize_Partial.
28	 *
29	 * @class
30	 * @augments wp.customize.Class
31	 * @since 4.5.0
32	 *
33	 * @param {string} id                              Unique identifier for the control instance.
34	 * @param {object} options                         Options hash for the control instance.
35	 * @param {object} options.params
36	 * @param {string} options.params.type             Type of partial (e.g. nav_menu, widget, etc)
37	 * @param {string} options.params.selector         jQuery selector to find the container element in the page.
38	 * @param {array}  options.params.settings         The IDs for the settings the partial relates to.
39	 * @param {string} options.params.primarySetting   The ID for the primary setting the partial renders.
40	 * @param {bool}   options.params.fallbackRefresh  Whether to refresh the entire preview in case of a partial refresh failure.
41	 */
42	Partial = self.Partial = api.Class.extend({
43
44		id: null,
45
46		 /**
47		 * Constructor.
48		 *
49		 * @since 4.5.0
50		 *
51		 * @param {string} id - Partial ID.
52		 * @param {Object} options
53		 * @param {Object} options.params
54		 */
55		initialize: function( id, options ) {
56			var partial = this;
57			options = options || {};
58			partial.id = id;
59
60			partial.params = _.extend(
61				{
62					selector: null,
63					settings: [],
64					primarySetting: null,
65					containerInclusive: false,
66					fallbackRefresh: true // Note this needs to be false in a front-end editing context.
67				},
68				options.params || {}
69			);
70
71			partial.deferred = {};
72			partial.deferred.ready = $.Deferred();
73
74			partial.deferred.ready.done( function() {
75				partial.ready();
76			} );
77		},
78
79		/**
80		 * Set up the partial.
81		 *
82		 * @since 4.5.0
83		 */
84		ready: function() {
85			var partial = this;
86			_.each( _.pluck( partial.placements(), 'container' ), function( container ) {
87				$( container ).attr( 'title', self.data.l10n.shiftClickToEdit );
88			} );
89			$( document ).on( 'click', partial.params.selector, function( e ) {
90				if ( ! e.shiftKey ) {
91					return;
92				}
93				e.preventDefault();
94				_.each( partial.placements(), function( placement ) {
95					if ( $( placement.container ).is( e.currentTarget ) ) {
96						partial.showControl();
97					}
98				} );
99			} );
100		},
101
102		/**
103		 * Find all placements for this partial int he document.
104		 *
105		 * @since 4.5.0
106		 *
107		 * @return {Array.<Placement>}
108		 */
109		placements: function() {
110			var partial = this, selector;
111
112			selector = partial.params.selector || '';
113			if ( selector ) {
114				selector += ', ';
115			}
116			selector += '[data-customize-partial-id="' + partial.id + '"]'; // @todo Consider injecting customize-partial-id-${id} classnames instead.
117
118			return $( selector ).map( function() {
119				var container = $( this ), context;
120
121				context = container.data( 'customize-partial-placement-context' );
122				if ( _.isString( context ) && '{' === context.substr( 0, 1 ) ) {
123					throw new Error( 'context JSON parse error' );
124				}
125
126				return new Placement( {
127					partial: partial,
128					container: container,
129					context: context
130				} );
131			} ).get();
132		},
133
134		/**
135		 * Get list of setting IDs related to this partial.
136		 *
137		 * @since 4.5.0
138		 *
139		 * @return {String[]}
140		 */
141		settings: function() {
142			var partial = this;
143			if ( partial.params.settings && 0 !== partial.params.settings.length ) {
144				return partial.params.settings;
145			} else if ( partial.params.primarySetting ) {
146				return [ partial.params.primarySetting ];
147			} else {
148				return [ partial.id ];
149			}
150		},
151
152		/**
153		 * Return whether the setting is related to the partial.
154		 *
155		 * @since 4.5.0
156		 *
157		 * @param {wp.customize.Value|string} setting  ID or object for setting.
158		 * @return {boolean} Whether the setting is related to the partial.
159		 */
160		isRelatedSetting: function( setting /*... newValue, oldValue */ ) {
161			var partial = this;
162			if ( _.isString( setting ) ) {
163				setting = api( setting );
164			}
165			if ( ! setting ) {
166				return false;
167			}
168			return -1 !== _.indexOf( partial.settings(), setting.id );
169		},
170
171		/**
172		 * Show the control to modify this partial's setting(s).
173		 *
174		 * This may be overridden for inline editing.
175		 *
176		 * @since 4.5.0
177		 */
178		showControl: function() {
179			var partial = this, settingId = partial.params.primarySetting;
180			if ( ! settingId ) {
181				settingId = _.first( partial.settings() );
182			}
183			api.preview.send( 'focus-control-for-setting', settingId );
184		},
185
186		/**
187		 * Prepare container for selective refresh.
188		 *
189		 * @since 4.5.0
190		 *
191		 * @param {Placement} placement
192		 */
193		preparePlacement: function( placement ) {
194			$( placement.container ).addClass( 'customize-partial-refreshing' );
195		},
196
197		/**
198		 * Reference to the pending promise returned from self.requestPartial().
199		 *
200		 * @since 4.5.0
201		 * @private
202		 */
203		_pendingRefreshPromise: null,
204
205		/**
206		 * Request the new partial and render it into the placements.
207		 *
208		 * @since 4.5.0
209		 *
210		 * @this {wp.customize.selectiveRefresh.Partial}
211		 * @return {jQuery.Promise}
212		 */
213		refresh: function() {
214			var partial = this, refreshPromise;
215
216			refreshPromise = self.requestPartial( partial );
217
218			if ( ! partial._pendingRefreshPromise ) {
219				_.each( partial.placements(), function( placement ) {
220					partial.preparePlacement( placement );
221				} );
222
223				refreshPromise.done( function( placements ) {
224					_.each( placements, function( placement ) {
225						partial.renderContent( placement );
226					} );
227				} );
228
229				refreshPromise.fail( function( data, placements ) {
230					partial.fallback( data, placements );
231				} );
232
233				// Allow new request when this one finishes.
234				partial._pendingRefreshPromise = refreshPromise;
235				refreshPromise.always( function() {
236					partial._pendingRefreshPromise = null;
237				} );
238			}
239
240			return refreshPromise;
241		},
242
243		/**
244		 * Apply the addedContent in the placement to the document.
245		 *
246		 * Note the placement object will have its container and removedNodes
247		 * properties updated.
248		 *
249		 * @since 4.5.0
250		 *
251		 * @param {Placement}             placement
252		 * @param {Element|jQuery}        [placement.container]  - This param will be empty if there was no element matching the selector.
253		 * @param {string|object|boolean} placement.addedContent - Rendered HTML content, a data object for JS templates to render, or false if no render.
254		 * @param {object}                [placement.context]    - Optional context information about the container.
255		 * @returns {boolean} Whether the rendering was successful and the fallback was not invoked.
256		 */
257		renderContent: function( placement ) {
258			var partial = this, content, newContainerElement;
259			if ( ! placement.container ) {
260				partial.fallback( new Error( 'no_container' ), [ placement ] );
261				return false;
262			}
263			placement.container = $( placement.container );
264			if ( false === placement.addedContent ) {
265				partial.fallback( new Error( 'missing_render' ), [ placement ] );
266				return false;
267			}
268
269			// Currently a subclass needs to override renderContent to handle partials returning data object.
270			if ( ! _.isString( placement.addedContent ) ) {
271				partial.fallback( new Error( 'non_string_content' ), [ placement ] );
272				return false;
273			}
274
275			/* jshint ignore:start */
276			self.orginalDocumentWrite = document.write;
277			document.write = function() {
278				throw new Error( self.data.l10n.badDocumentWrite );
279			};
280			/* jshint ignore:end */
281			try {
282				content = placement.addedContent;
283				if ( wp.emoji && wp.emoji.parse && ! $.contains( document.head, placement.container[0] ) ) {
284					content = wp.emoji.parse( content );
285				}
286
287				if ( partial.params.containerInclusive ) {
288
289					// Note that content may be an empty string, and in this case jQuery will just remove the oldContainer
290					newContainerElement = $( content );
291
292					// Merge the new context on top of the old context.
293					placement.context = _.extend(
294						placement.context,
295						newContainerElement.data( 'customize-partial-placement-context' ) || {}
296					);
297					newContainerElement.data( 'customize-partial-placement-context', placement.context );
298
299					placement.removedNodes = placement.container;
300					placement.container = newContainerElement;
301					placement.removedNodes.replaceWith( placement.container );
302					placement.container.attr( 'title', self.data.l10n.shiftClickToEdit );
303				} else {
304					placement.removedNodes = document.createDocumentFragment();
305					while ( placement.container[0].firstChild ) {
306						placement.removedNodes.appendChild( placement.container[0].firstChild );
307					}
308
309					placement.container.html( content );
310				}
311
312				placement.container.removeClass( 'customize-render-content-error' );
313			} catch ( error ) {
314				if ( 'undefined' !== typeof console && console.error ) {
315					console.error( partial.id, error );
316				}
317			}
318			/* jshint ignore:start */
319			document.write = self.orginalDocumentWrite;
320			self.orginalDocumentWrite = null;
321			/* jshint ignore:end */
322
323			placement.container.removeClass( 'customize-partial-refreshing' );
324
325			// Prevent placement container from being being re-triggered as being rendered among nested partials.
326			placement.container.data( 'customize-partial-content-rendered', true );
327
328			/**
329			 * Announce when a partial's placement has been rendered so that dynamic elements can be re-built.
330			 */
331			self.trigger( 'partial-content-rendered', placement );
332			return true;
333		},
334
335		/**
336		 * Handle fail to render partial.
337		 *
338		 * The first argument is either the failing jqXHR or an Error object, and the second argument is the array of containers.
339		 *
340		 * @since 4.5.0
341		 */
342		fallback: function() {
343			var partial = this;
344			if ( partial.params.fallbackRefresh ) {
345				self.requestFullRefresh();
346			}
347		}
348	} );
349
350	/**
351	 * A Placement for a Partial.
352	 *
353	 * A partial placement is the actual physical representation of a partial for a given context.
354	 * It also may have information in relation to how a placement may have just changed.
355	 * The placement is conceptually similar to a DOM Range or MutationRecord.
356	 *
357	 * @class
358	 * @augments wp.customize.Class
359	 * @since 4.5.0
360	 */
361	self.Placement = Placement = api.Class.extend({
362
363		/**
364		 * The partial with which the container is associated.
365		 *
366		 * @param {wp.customize.selectiveRefresh.Partial}
367		 */
368		partial: null,
369
370		/**
371		 * DOM element which contains the placement's contents.
372		 *
373		 * This will be null if the startNode and endNode do not point to the same
374		 * DOM element, such as in the case of a sidebar partial.
375		 * This container element itself will be replaced for partials that
376		 * have containerInclusive param defined as true.
377		 */
378		container: null,
379
380		/**
381		 * DOM node for the initial boundary of the placement.
382		 *
383		 * This will normally be the same as endNode since most placements appear as elements.
384		 * This is primarily useful for widget sidebars which do not have intrinsic containers, but
385		 * for which an HTML comment is output before to mark the starting position.
386		 */
387		startNode: null,
388
389		/**
390		 * DOM node for the terminal boundary of the placement.
391		 *
392		 * This will normally be the same as startNode since most placements appear as elements.
393		 * This is primarily useful for widget sidebars which do not have intrinsic containers, but
394		 * for which an HTML comment is output before to mark the ending position.
395		 */
396		endNode: null,
397
398		/**
399		 * Context data.
400		 *
401		 * This provides information about the placement which is included in the request
402		 * in order to render the partial properly.
403		 *
404		 * @param {object}
405		 */
406		context: null,
407
408		/**
409		 * The content for the partial when refreshed.
410		 *
411		 * @param {string}
412		 */
413		addedContent: null,
414
415		/**
416		 * DOM node(s) removed when the partial is refreshed.
417		 *
418		 * If the partial is containerInclusive, then the removedNodes will be
419		 * the single Element that was the partial's former placement. If the
420		 * partial is not containerInclusive, then the removedNodes will be a
421		 * documentFragment containing the nodes removed.
422		 *
423		 * @param {Element|DocumentFragment}
424		 */
425		removedNodes: null,
426
427		/**
428		 * Constructor.
429		 *
430		 * @since 4.5.0
431		 *
432		 * @param {object}                   args
433		 * @param {Partial}                  args.partial
434		 * @param {jQuery|Element}           [args.container]
435		 * @param {Node}                     [args.startNode]
436		 * @param {Node}                     [args.endNode]
437		 * @param {object}                   [args.context]
438		 * @param {string}                   [args.addedContent]
439		 * @param {jQuery|DocumentFragment}  [args.removedNodes]
440		 */
441		initialize: function( args ) {
442			var placement = this;
443
444			args = _.extend( {}, args || {} );
445			if ( ! args.partial || ! args.partial.extended( Partial ) ) {
446				throw new Error( 'Missing partial' );
447			}
448			args.context = args.context || {};
449			if ( args.container ) {
450				args.container = $( args.container );
451			}
452
453			_.extend( placement, args );
454		}
455
456	});
457
458	/**
459	 * Mapping of type names to Partial constructor subclasses.
460	 *
461	 * @since 4.5.0
462	 *
463	 * @type {Object.<string, wp.customize.selectiveRefresh.Partial>}
464	 */
465	self.partialConstructor = {};
466
467	self.partial = new api.Values({ defaultConstructor: Partial });
468
469	/**
470	 * Get the POST vars for a Customizer preview request.
471	 *
472	 * @since 4.5.0
473	 * @see wp.customize.previewer.query()
474	 *
475	 * @return {object}
476	 */
477	self.getCustomizeQuery = function() {
478		var dirtyCustomized = {};
479		api.each( function( value, key ) {
480			if ( value._dirty ) {
481				dirtyCustomized[ key ] = value();
482			}
483		} );
484
485		return {
486			wp_customize: 'on',
487			nonce: api.settings.nonce.preview,
488			theme: api.settings.theme.stylesheet,
489			customized: JSON.stringify( dirtyCustomized )
490		};
491	};
492
493	/**
494	 * Currently-requested partials and their associated deferreds.
495	 *
496	 * @since 4.5.0
497	 * @type {Object<string, { deferred: jQuery.Promise, partial: wp.customize.selectiveRefresh.Partial }>}
498	 */
499	self._pendingPartialRequests = {};
500
501	/**
502	 * Timeout ID for the current requesr, or null if no request is current.
503	 *
504	 * @since 4.5.0
505	 * @type {number|null}
506	 * @private
507	 */
508	self._debouncedTimeoutId = null;
509
510	/**
511	 * Current jqXHR for the request to the partials.
512	 *
513	 * @since 4.5.0
514	 * @type {jQuery.jqXHR|null}
515	 * @private
516	 */
517	self._currentRequest = null;
518
519	/**
520	 * Request full page refresh.
521	 *
522	 * When selective refresh is embedded in the context of front-end editing, this request
523	 * must fail or else changes will be lost, unless transactions are implemented.
524	 *
525	 * @since 4.5.0
526	 */
527	self.requestFullRefresh = function() {
528		api.preview.send( 'refresh' );
529	};
530
531	/**
532	 * Request a re-rendering of a partial.
533	 *
534	 * @since 4.5.0
535	 *
536	 * @param {wp.customize.selectiveRefresh.Partial} partial
537	 * @return {jQuery.Promise}
538	 */
539	self.requestPartial = function( partial ) {
540		var partialRequest;
541
542		if ( self._debouncedTimeoutId ) {
543			clearTimeout( self._debouncedTimeoutId );
544			self._debouncedTimeoutId = null;
545		}
546		if ( self._currentRequest ) {
547			self._currentRequest.abort();
548			self._currentRequest = null;
549		}
550
551		partialRequest = self._pendingPartialRequests[ partial.id ];
552		if ( ! partialRequest || 'pending' !== partialRequest.deferred.state() ) {
553			partialRequest = {
554				deferred: $.Deferred(),
555				partial: partial
556			};
557			self._pendingPartialRequests[ partial.id ] = partialRequest;
558		}
559
560		// Prevent leaking partial into debounced timeout callback.
561		partial = null;
562
563		self._debouncedTimeoutId = setTimeout(
564			function() {
565				var data, partialPlacementContexts, partialsPlacements, request;
566
567				self._debouncedTimeoutId = null;
568				data = self.getCustomizeQuery();
569
570				/*
571				 * It is key that the containers be fetched exactly at the point of the request being
572				 * made, because the containers need to be mapped to responses by array indices.
573				 */
574				partialsPlacements = {};
575
576				partialPlacementContexts = {};
577
578				_.each( self._pendingPartialRequests, function( pending, partialId ) {
579					partialsPlacements[ partialId ] = pending.partial.placements();
580					if ( ! self.partial.has( partialId ) ) {
581						pending.deferred.rejectWith( pending.partial, [ new Error( 'partial_removed' ), partialsPlacements[ partialId ] ] );
582					} else {
583						/*
584						 * Note that this may in fact be an empty array. In that case, it is the responsibility
585						 * of the Partial subclass instance to know where to inject the response, or else to
586						 * just issue a refresh (default behavior). The data being returned with each container
587						 * is the context information that may be needed to render certain partials, such as
588						 * the contained sidebar for rendering widgets or what the nav menu args are for a menu.
589						 */
590						partialPlacementContexts[ partialId ] = _.map( partialsPlacements[ partialId ], function( placement ) {
591							return placement.context || {};
592						} );
593					}
594				} );
595
596				data.partials = JSON.stringify( partialPlacementContexts );
597				data[ self.data.renderQueryVar ] = '1';
598
599				request = self._currentRequest = wp.ajax.send( null, {
600					data: data,
601					url: api.settings.url.self
602				} );
603
604				request.done( function( data ) {
605
606					/**
607					 * Announce the data returned from a request to render partials.
608					 *
609					 * The data is filtered on the server via customize_render_partials_response
610					 * so plugins can inject data from the server to be utilized
611					 * on the client via this event. Plugins may use this filter
612					 * to communicate script and style dependencies that need to get
613					 * injected into the page to support the rendered partials.
614					 * This is similar to the 'saved' event.
615					 */
616					self.trigger( 'render-partials-response', data );
617
618					// Relay errors (warnings) captured during rendering and relay to console.
619					if ( data.errors && 'undefined' !== typeof console && console.warn ) {
620						_.each( data.errors, function( error ) {
621							console.warn( error );
622						} );
623					}
624
625					/*
626					 * Note that data is an array of items that correspond to the array of
627					 * containers that were submitted in the request. So we zip up the
628					 * array of containers with the array of contents for those containers,
629					 * and send them into .
630					 */
631					_.each( self._pendingPartialRequests, function( pending, partialId ) {
632						var placementsContents;
633						if ( ! _.isArray( data.contents[ partialId ] ) ) {
634							pending.deferred.rejectWith( pending.partial, [ new Error( 'unrecognized_partial' ), partialsPlacements[ partialId ] ] );
635						} else {
636							placementsContents = _.map( data.contents[ partialId ], function( content, i ) {
637								var partialPlacement = partialsPlacements[ partialId ][ i ];
638								if ( partialPlacement ) {
639									partialPlacement.addedContent = content;
640								} else {
641									partialPlacement = new Placement( {
642										partial: pending.partial,
643										addedContent: content
644									} );
645								}
646								return partialPlacement;
647							} );
648							pending.deferred.resolveWith( pending.partial, [ placementsContents ] );
649						}
650					} );
651					self._pendingPartialRequests = {};
652				} );
653
654				request.fail( function( data, statusText ) {
655
656					/*
657					 * Ignore failures caused by partial.currentRequest.abort()
658					 * The pending deferreds will remain in self._pendingPartialRequests
659					 * for re-use with the next request.
660					 */
661					if ( 'abort' === statusText ) {
662						return;
663					}
664
665					_.each( self._pendingPartialRequests, function( pending, partialId ) {
666						pending.deferred.rejectWith( pending.partial, [ data, partialsPlacements[ partialId ] ] );
667					} );
668					self._pendingPartialRequests = {};
669				} );
670			},
671			self.data.refreshBuffer
672		);
673
674		return partialRequest.deferred.promise();
675	};
676
677	/**
678	 * Add partials for any nav menu container elements in the document.
679	 *
680	 * This method may be called multiple times. Containers that already have been
681	 * seen will be skipped.
682	 *
683	 * @since 4.5.0
684	 *
685	 * @param {jQuery|HTMLElement} [rootElement]
686	 * @param {object}             [options]
687	 * @param {boolean=true}       [options.triggerRendered]
688	 */
689	self.addPartials = function( rootElement, options ) {
690		var containerElements;
691		if ( ! rootElement ) {
692			rootElement = document.documentElement;
693		}
694		rootElement = $( rootElement );
695		options = _.extend(
696			{
697				triggerRendered: true
698			},
699			options || {}
700		);
701
702		containerElements = rootElement.find( '[data-customize-partial-id]' );
703		if ( rootElement.is( '[data-customize-partial-id]' ) ) {
704			containerElements = containerElements.add( rootElement );
705		}
706		containerElements.each( function() {
707			var containerElement = $( this ), partial, id, Constructor, partialOptions, containerContext;
708			id = containerElement.data( 'customize-partial-id' );
709			if ( ! id ) {
710				return;
711			}
712			containerContext = containerElement.data( 'customize-partial-placement-context' ) || {};
713
714			partial = self.partial( id );
715			if ( ! partial ) {
716				partialOptions = containerElement.data( 'customize-partial-options' ) || {};
717				partialOptions.constructingContainerContext = containerElement.data( 'customize-partial-placement-context' ) || {};
718				Constructor = self.partialConstructor[ containerElement.data( 'customize-partial-type' ) ] || self.Partial;
719				partial = new Constructor( id, partialOptions );
720				self.partial.add( partial.id, partial );
721			}
722
723			/*
724			 * Only trigger renders on (nested) partials that have been not been
725			 * handled yet. An example where this would apply is a nav menu
726			 * embedded inside of a custom menu widget. When the widget's title
727			 * is updated, the entire widget will re-render and then the event
728			 * will be triggered for the nested nav menu to do any initialization.
729			 */
730			if ( options.triggerRendered && ! containerElement.data( 'customize-partial-content-rendered' ) ) {
731
732				/**
733				 * Announce when a partial's nested placement has been re-rendered.
734				 */
735				self.trigger( 'partial-content-rendered', new Placement( {
736					partial: partial,
737					context: containerContext,
738					container: containerElement
739				} ) );
740			}
741			containerElement.data( 'customize-partial-content-rendered', true );
742		} );
743	};
744
745	api.bind( 'preview-ready', function() {
746		var handleSettingChange, watchSettingChange, unwatchSettingChange;
747
748		// Polyfill for IE8 to support the document.head attribute.
749		if ( ! document.head ) {
750			document.head = $( 'head:first' )[0];
751		}
752
753		_.extend( self.data, _customizePartialRefreshExports );
754
755		// Create the partial JS models.
756		_.each( self.data.partials, function( data, id ) {
757			var Constructor, partial = self.partial( id );
758			if ( ! partial ) {
759				Constructor = self.partialConstructor[ data.type ] || self.Partial;
760				partial = new Constructor( id, { params: data } );
761				self.partial.add( id, partial );
762			} else {
763				_.extend( partial.params, data );
764			}
765		} );
766
767		/**
768		 * Handle change to a setting.
769		 *
770		 * Note this is largely needed because adding a 'change' event handler to wp.customize
771		 * will only include the changed setting object as an argument, not including the
772		 * new value or the old value.
773		 *
774		 * @since 4.5.0
775		 * @this {wp.customize.Setting}
776		 *
777		 * @param {*|null} newValue New value, or null if the setting was just removed.
778		 * @param {*|null} oldValue Old value, or null if the setting was just added.
779		 */
780		handleSettingChange = function( newValue, oldValue ) {
781			var setting = this;
782			self.partial.each( function( partial ) {
783				if ( partial.isRelatedSetting( setting, newValue, oldValue ) ) {
784					partial.refresh();
785				}
786			} );
787		};
788
789		/**
790		 * Trigger the initial change for the added setting, and watch for changes.
791		 *
792		 * @since 4.5.0
793		 * @this {wp.customize.Values}
794		 *
795		 * @param {wp.customize.Setting} setting
796		 */
797		watchSettingChange = function( setting ) {
798			handleSettingChange.call( setting, setting(), null );
799			setting.bind( handleSettingChange );
800		};
801
802		/**
803		 * Trigger the final change for the removed setting, and unwatch for changes.
804		 *
805		 * @since 4.5.0
806		 * @this {wp.customize.Values}
807		 *
808		 * @param {wp.customize.Setting} setting
809		 */
810		unwatchSettingChange = function( setting ) {
811			handleSettingChange.call( setting, null, setting() );
812			setting.unbind( handleSettingChange );
813		};
814
815		api.bind( 'add', watchSettingChange );
816		api.bind( 'remove', unwatchSettingChange );
817		api.each( function( setting ) {
818			setting.bind( handleSettingChange );
819		} );
820
821		// Add (dynamic) initial partials that are declared via data-* attributes.
822		self.addPartials( document.documentElement, {
823			triggerRendered: false
824		} );
825
826		// Add new dynamic partials when the document changes.
827		if ( 'undefined' !== typeof MutationObserver ) {
828			self.mutationObserver = new MutationObserver( function( mutations ) {
829				_.each( mutations, function( mutation ) {
830					self.addPartials( $( mutation.target ) );
831				} );
832			} );
833			self.mutationObserver.observe( document.documentElement, {
834				childList: true,
835				subtree: true
836			} );
837		}
838
839		/**
840		 * Handle rendering of partials.
841		 *
842		 * @param {api.selectiveRefresh.Placement} placement
843		 */
844		api.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
845			if ( placement.container ) {
846				self.addPartials( placement.container );
847			}
848		} );
849
850		/**
851		 * Handle setting validities in partial refresh response.
852		 *
853		 * @param {object} data Response data.
854		 * @param {object} data.setting_validities Setting validities.
855		 */
856		api.selectiveRefresh.bind( 'render-partials-response', function handleSettingValiditiesResponse( data ) {
857			if ( data.setting_validities ) {
858				api.preview.send( 'selective-refresh-setting-validities', data.setting_validities );
859			}
860		} );
861
862		api.preview.bind( 'active', function() {
863
864			// Make all partials ready.
865			self.partial.each( function( partial ) {
866				partial.deferred.ready.resolve();
867			} );
868
869			// Make all partials added henceforth as ready upon add.
870			self.partial.bind( 'add', function( partial ) {
871				partial.deferred.ready.resolve();
872			} );
873		} );
874
875	} );
876
877	return self;
878}( jQuery, wp.customize ) );
879
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Cypress on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)