*/
api.Preview = api.Messenger.extend({
/**
- * @param {string} url The URL of preview frame
+ * @param {object} params - Parameters to configure the messenger.
+ * @param {object} options - Extend any instance parameter or method with this object.
*/
initialize: function( params, options ) {
var self = this;
this.body = $( document.body );
this.body.on( 'click.preview', 'a', function( event ) {
+ var link, isInternalJumpLink;
+ link = $( this );
+ isInternalJumpLink = ( '#' === link.attr( 'href' ).substr( 0, 1 ) );
event.preventDefault();
+
+ if ( isInternalJumpLink && '#' !== link.attr( 'href' ) ) {
+ $( link.attr( 'href' ) ).each( function() {
+ this.scrollIntoView();
+ } );
+ }
+
+ /*
+ * Note the shift key is checked so shift+click on widgets or
+ * nav menu items can just result on focusing on the corresponding
+ * control instead of also navigating to the URL linked to.
+ */
+ if ( event.shiftKey || isInternalJumpLink ) {
+ return;
+ }
self.send( 'scroll', 0 );
- self.send( 'url', $(this).prop('href') );
+ self.send( 'url', link.prop( 'href' ) );
});
// You cannot submit forms.
});
$( function() {
+ var bg, setValue;
+
api.settings = window._wpCustomizeSettings;
- if ( ! api.settings )
+ if ( ! api.settings ) {
return;
-
- var bg;
+ }
api.preview = new api.Preview({
url: window.location.href,
channel: api.settings.channel
});
+ /**
+ * Create/update a setting value.
+ *
+ * @param {string} id - Setting ID.
+ * @param {*} value - Setting value.
+ * @param {boolean} [createDirty] - Whether to create a setting as dirty. Defaults to false.
+ */
+ setValue = function( id, value, createDirty ) {
+ var setting = api( id );
+ if ( setting ) {
+ setting.set( value );
+ } else {
+ createDirty = createDirty || false;
+ setting = api.create( id, value, {
+ id: id
+ } );
+
+ // Mark dynamically-created settings as dirty so they will get posted.
+ if ( createDirty ) {
+ setting._dirty = true;
+ }
+ }
+ };
+
api.preview.bind( 'settings', function( values ) {
- $.each( values, function( id, value ) {
- if ( api.has( id ) )
- api( id ).set( value );
- else
- api.create( id, value );
- });
+ $.each( values, setValue );
});
api.preview.trigger( 'settings', api.settings.values );
- api.preview.bind( 'setting', function( args ) {
- var value;
-
- args = args.slice();
+ $.each( api.settings._dirty, function( i, id ) {
+ var setting = api( id );
+ if ( setting ) {
+ setting._dirty = true;
+ }
+ } );
- if ( value = api( args.shift() ) )
- value.set.apply( value, args );
+ api.preview.bind( 'setting', function( args ) {
+ var createDirty = true;
+ setValue.apply( null, args.concat( createDirty ) );
});
api.preview.bind( 'sync', function( events ) {
});
api.preview.bind( 'active', function() {
- if ( api.settings.nonce ) {
- api.preview.send( 'nonce', api.settings.nonce );
- }
+ api.preview.send( 'nonce', api.settings.nonce );
api.preview.send( 'documentTitle', document.title );
});
+ api.preview.bind( 'saved', function( response ) {
+ api.trigger( 'saved', response );
+ } );
+
+ api.bind( 'saved', function() {
+ api.each( function( setting ) {
+ setting._dirty = false;
+ } );
+ } );
+
+ api.preview.bind( 'nonce-refresh', function( nonce ) {
+ $.extend( api.settings.nonce, nonce );
+ } );
+
/*
* Send a message to the parent customize frame with a list of which
* containers and controls are active.
});
});
+ /**
+ * Custom Logo
+ *
+ * Toggle the wp-custom-logo body class when a logo is added or removed.
+ *
+ * @since 4.5.0
+ */
+ api( 'custom_logo', function( setting ) {
+ $( 'body' ).toggleClass( 'wp-custom-logo', !! setting.get() );
+ setting.bind( function( attachmentId ) {
+ $( 'body' ).toggleClass( 'wp-custom-logo', !! attachmentId );
+ } );
+ } );
+
api.trigger( 'preview-ready' );
});