From 44dace3487ce1b6c0fd09113690e0af3d0c31c2c Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Sat, 5 Sep 2015 19:53:24 +0000 Subject: [PATCH] Add Customizer docs. Props ericlewis. See #33503. Built from https://develop.svn.wordpress.org/trunk@33911 git-svn-id: http://core.svn.wordpress.org/trunk@33880 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/js/customize-controls.js | 110 ++++++++++++++++----- wp-includes/class-wp-customize-setting.php | 8 +- wp-includes/js/customize-base.js | 68 ++++++++++++- wp-includes/js/customize-loader.js | 6 +- wp-includes/js/customize-preview.js | 4 + wp-includes/version.php | 2 +- 6 files changed, 170 insertions(+), 28 deletions(-) diff --git a/wp-admin/js/customize-controls.js b/wp-admin/js/customize-controls.js index 1fdbd15d4c..913f8253c2 100644 --- a/wp-admin/js/customize-controls.js +++ b/wp-admin/js/customize-controls.js @@ -3,13 +3,22 @@ var Container, focus, api = wp.customize; /** + * A Customizer Setting. + * + * A setting is WordPress data (theme mod, option, menu, etc.) that the user can + * draft changes to in the Customizer. + * + * @see PHP class WP_Customize_Setting. + * * @class * @augments wp.customize.Value * @augments wp.customize.Class * - * @param options - * - previewer - The Previewer instance to sync with. - * - transport - The transport to use for previewing. Supports 'refresh' and 'postMessage'. + * @param {object} id The Setting ID. + * @param {object} value The initial value of the setting. + * @param {object} options.previewer The Previewer instance to sync with. + * @param {object} options.transport The transport to use for previewing. Supports 'refresh' and 'postMessage'. + * @param {object} options.dirty */ api.Setting = api.Value.extend({ initialize: function( id, value, options ) { @@ -19,8 +28,13 @@ this.transport = this.transport || 'refresh'; this._dirty = options.dirty || false; + // Whenever the setting's value changes, refresh the preview. this.bind( this.preview ); }, + + /** + * Refresh the preview, respective of the setting's refresh policy. + */ preview: function() { switch ( this.transport ) { case 'refresh': @@ -270,10 +284,9 @@ }, /** - * Handle changes to the active state. + * Active state change handler. * - * This does not change the active state, it merely handles the behavior - * for when it does change. + * Shows the container if it is active, hides it if not. * * To override by subclass, update the container's UI to reflect the provided active state. * @@ -1347,14 +1360,16 @@ * @class * @augments wp.customize.Class * - * @param {string} id Unique identifier for the control instance. - * @param {object} options Options hash for the control instance. + * @param {string} id Unique identifier for the control instance. + * @param {object} options Options hash for the control instance. * @param {object} options.params - * @param {object} options.params.type Type of control (e.g. text, radio, dropdown-pages, etc.) - * @param {string} options.params.content The HTML content for the control. - * @param {string} options.params.priority Order of priority to show the control within the section. + * @param {object} options.params.type Type of control (e.g. text, radio, dropdown-pages, etc.) + * @param {string} options.params.content The HTML content for the control. + * @param {string} options.params.priority Order of priority to show the control within the section. * @param {string} options.params.active - * @param {string} options.params.section + * @param {string} options.params.section The ID of the section the control belongs to. + * @param {string} options.params.settings.default The ID of the setting the control relates to. + * @param {string} options.params.settings.data * @param {string} options.params.label * @param {string} options.params.description * @param {string} options.params.instanceNumber Order in which this instance was created in relation to other instances. @@ -1420,7 +1435,10 @@ api.utils.bubbleChildValueChanges( control, [ 'section', 'priority', 'active' ] ); - // Associate this control with its settings when they are created + /* + * After all settings related to the control are available, + * make them available on the control and embed the control into the page. + */ settings = $.map( control.params.settings, function( value ) { return value; }); @@ -1437,6 +1455,7 @@ control.embed(); }) ); + // After the control is embedded on the page, invoke the "ready" method. control.deferred.embedded.done( function () { control.ready(); }); @@ -2573,6 +2592,9 @@ api.panel = new api.Values({ defaultConstructor: api.Panel }); /** + * An object that fetches a preview in the background of the document, which + * allows for seamless replacement of an existing preview. + * * @class * @augments wp.customize.Messenger * @augments wp.customize.Class @@ -2581,10 +2603,22 @@ api.PreviewFrame = api.Messenger.extend({ sensitivity: 2000, + /** + * Initialize the PreviewFrame. + * + * @param {object} params.container + * @param {object} params.signature + * @param {object} params.previewUrl + * @param {object} params.query + * @param {object} options + */ initialize: function( params, options ) { var deferred = $.Deferred(); - // This is the promise object. + /* + * Make the instance of the PreviewFrame the promise object + * so other objects can easily interact with it. + */ deferred.promise( this ); this.container = params.container; @@ -2601,6 +2635,12 @@ this.run( deferred ); }, + /** + * Run the preview request. + * + * @param {object} deferred jQuery Deferred object to be resolved with + * the request. + */ run: function( deferred ) { var self = this, loaded = false, @@ -2804,9 +2844,13 @@ refreshBuffer: 250, /** - * Requires params: - * - container - a selector or jQuery element - * - previewUrl - the URL of preview frame + * @param {array} params.allowedUrls + * @param {string} params.container A selector or jQuery element for the preview + * frame to be placed. + * @param {string} params.form + * @param {string} params.previewUrl The URL to preview. + * @param {string} params.signature + * @param {object} options */ initialize: function( params, options ) { var self = this, @@ -2919,6 +2963,11 @@ } ); }, + /** + * Query string data sent with each preview request. + * + * @abstract + */ query: function() {}, abort: function() { @@ -2928,6 +2977,9 @@ } }, + /** + * Refresh the preview. + */ refresh: function() { var self = this; @@ -3140,6 +3192,11 @@ nonce: api.settings.nonce, + /** + * Build the query to send along with the Preview request. + * + * @return {object} + */ query: function() { var dirtyCustomized = {}; api.each( function ( value, key ) { @@ -3467,14 +3524,21 @@ } ); } - // Create a potential postMessage connection with the parent frame. + /* + * Create a postMessage connection with a parent frame, + * in case the Customizer frame was opened with the Customize loader. + * + * @see wp.customize.Loader + */ parent = new api.Messenger({ url: api.settings.url.parent, channel: 'loader' }); - // If we receive a 'back' event, we're inside an iframe. - // Send any clicks to the 'Return' link to the parent page. + /* + * If we receive a 'back' event, we're inside an iframe. + * Send any clicks to the 'Return' link to the parent page. + */ parent.bind( 'back', function() { closeBtn.on( 'click.customize-controls-close', function( event ) { event.preventDefault(); @@ -3499,8 +3563,10 @@ }); } ); - // When activated, let the loader handle redirecting the page. - // If no loader exists, redirect the page ourselves (if a url exists). + /* + * When activated, let the loader handle redirecting the page. + * If no loader exists, redirect the page ourselves (if a url exists). + */ api.bind( 'activated', function() { if ( parent.targetWindow() ) parent.send( 'activated', api.settings.url.activated ); diff --git a/wp-includes/class-wp-customize-setting.php b/wp-includes/class-wp-customize-setting.php index d007965e8a..98f37f9c78 100644 --- a/wp-includes/class-wp-customize-setting.php +++ b/wp-includes/class-wp-customize-setting.php @@ -24,6 +24,8 @@ class WP_Customize_Setting { public $manager; /** + * Unique string identifier for the setting. + * * @access public * @var string */ @@ -74,6 +76,9 @@ class WP_Customize_Setting { */ public $dirty = false; + /** + * @var array + */ protected $id_data = array(); /** @@ -148,7 +153,8 @@ class WP_Customize_Setting { protected $_original_value; /** - * Handle previewing the setting. + * Set up filters for the setting so that the preview request + * will render the drafted changes. * * @since 3.4.0 */ diff --git a/wp-includes/js/customize-base.js b/wp-includes/js/customize-base.js index 720a312ccb..79ba46430a 100644 --- a/wp-includes/js/customize-base.js +++ b/wp-includes/js/customize-base.js @@ -78,7 +78,9 @@ window.wp = window.wp || {}; /* * If the class has a method called "instance", * the return value from the class' constructor will be a function that - * calls invoked, along with all the object properties of the class. + * calls the "instance" method. + * + * It is also an object that has properties and methods inside it. */ if ( this.instance ) { magic = function() { @@ -166,6 +168,10 @@ window.wp = window.wp || {}; * @constuctor */ api.Value = api.Class.extend({ + /** + * @param {mixed} initial The initial value. + * @param {object} options + */ initialize: function( initial, options ) { this._value = initial; // @todo: potentially change this to a this.set() call. this.callbacks = $.Callbacks(); @@ -184,10 +190,20 @@ window.wp = window.wp || {}; return arguments.length ? this.set.apply( this, arguments ) : this.get(); }, + /** + * Get the value. + * + * @return {mixed} + */ get: function() { return this._value; }, + /** + * Set the value and trigger all bound callbacks. + * + * @param {object} to New value. + */ set: function( to ) { var from = this._value; @@ -230,11 +246,21 @@ window.wp = window.wp || {}; return value; }, + /** + * Bind a function to be invoked whenever the value changes. + * + * @param {...Function} A function, or multiple functions, to add to the callback stack. + */ bind: function() { this.callbacks.add.apply( this.callbacks, arguments ); return this; }, + /** + * Unbind a previously bound function. + * + * @param {...Function} A function, or multiple functions, to remove from the callback stack. + */ unbind: function() { this.callbacks.remove.apply( this.callbacks, arguments ); return this; @@ -283,6 +309,12 @@ window.wp = window.wp || {}; * @mixes wp.customize.Events */ api.Values = api.Class.extend({ + + /** + * The default constructor for items of the collection. + * + * @type {object} + */ defaultConstructor: api.Value, initialize: function( options ) { @@ -347,6 +379,8 @@ window.wp = window.wp || {}; this._value[ id ] = value; value.parent = this; + + // Propagate a 'change' event on an item up to the collection. if ( value.extended( api.Value ) ) value.bind( this._change ); @@ -372,6 +406,12 @@ window.wp = window.wp || {}; return this.add( id, new this.defaultConstructor( api.Class.applicator, slice.call( arguments, 1 ) ) ); }, + /** + * Iterate over all items in the collection invoking the provided callback. + * + * @param {Function} callback Function to invoke. + * @param {object} context Object context to invoke the function with. Optional. + */ each: function( callback, context ) { context = typeof context === 'undefined' ? this : context; @@ -453,11 +493,16 @@ window.wp = window.wp || {}; return dfd.promise(); }, + /** + * A helper function to propagate a 'change' event from an item + * to the collection itself. + */ _change: function() { this.parent.trigger( 'change', this ); } }); + // Create a global events bus on the Customizer. $.extend( api.Values.prototype, api.Events ); @@ -570,7 +615,7 @@ window.wp = window.wp || {}; $.support.postMessage = !! window.postMessage; /** - * Messenger for postMessage. + * A communicator for sending data from one window to another over postMessage. * * @constuctor * @augments wp.customize.Class @@ -649,6 +694,11 @@ window.wp = window.wp || {}; $( window ).off( 'message', this.receive ); }, + /** + * Receive data from the other window. + * + * @param {jQuery.Event} event Event with embedded data. + */ receive: function( event ) { var message; @@ -679,6 +729,12 @@ window.wp = window.wp || {}; this.trigger( message.id, message.data ); }, + /** + * Send data to the other window. + * + * @param {string} id The event name. + * @param {object} data Data. + */ send: function( id, data ) { var message; @@ -698,8 +754,14 @@ window.wp = window.wp || {}; // Add the Events mixin to api.Messenger. $.extend( api.Messenger.prototype, api.Events ); - // Core customize object. + // The main API object is also a collection of all customizer settings. api = $.extend( new api.Values(), api ); + + /** + * Get all customize settings. + * + * @return {object} + */ api.get = function() { var result = {}; diff --git a/wp-includes/js/customize-loader.js b/wp-includes/js/customize-loader.js index 5bc34c4367..f853f37d85 100644 --- a/wp-includes/js/customize-loader.js +++ b/wp-includes/js/customize-loader.js @@ -115,7 +115,11 @@ window.wp = window.wp || {}; this.active = true; this.body.addClass('customize-loading'); - // Dirty state of Customizer in iframe + /* + * Track the dirtiness state (whether the drafted changes have been published) + * of the Customizer in the iframe. This is used to decide whether to display + * an AYS alert if the user tries to close the window before saving changes. + */ this.saved = new api.Value( true ); this.iframe = $( '