├── .dev-lib
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .gitmodules
├── .jscsrc
├── .jshintignore
├── .jshintrc
├── .travis.yml
├── Gruntfile.js
├── customizer-dev-tools.php
├── js
├── base.js
├── pane.js
└── preview.js
├── package.json
├── php
└── class-plugin.php
├── phpcs.xml
├── readme.md
├── readme.txt
└── wp-assets
├── screenshot-1.png
├── screenshot-2.png
├── screenshot-3.png
├── screenshot-4.png
├── screenshot-5.png
└── screenshot-6.png
/.dev-lib:
--------------------------------------------------------------------------------
1 | PATH_INCLUDES='*.* php js'
2 | WPCS_GIT_TREE=develop
3 | ASSETS_DIR=wp-assets
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | dev-lib/.editorconfig
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dev-lib/.eslintignore
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | dev-lib/.eslintrc
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 |
4 | # Grunt
5 | /build/
6 | /node_modules/
7 | npm-debug.log
8 |
9 | # Composer
10 | composer.lock
11 | /vendor/
12 |
13 | # Compiled files
14 | *.min.js
15 | *.min.css
16 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "dev-lib"]
2 | path = dev-lib
3 | url = https://github.com/xwp/wp-dev-lib.git
4 | branch = master
5 |
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | dev-lib/.jscsrc
--------------------------------------------------------------------------------
/.jshintignore:
--------------------------------------------------------------------------------
1 | **/*.min.js
2 | **/node_modules/**
3 | **/vendor/**
4 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | dev-lib/.jshintrc
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | dist: precise
3 |
4 | language:
5 | - php
6 | - node_js
7 |
8 | php:
9 | - 5.6
10 | - 7.1
11 |
12 | env:
13 | - WP_VERSION=trunk WP_MULTISITE=0
14 | - WP_VERSION=trunk WP_MULTISITE=1
15 |
16 | install:
17 | - nvm install 6 && nvm use 6
18 | - export DEV_LIB_PATH=dev-lib
19 | - if [ ! -e "$DEV_LIB_PATH" ] && [ -L .travis.yml ]; then export DEV_LIB_PATH=$( dirname $( readlink .travis.yml ) ); fi
20 | - if [ ! -e "$DEV_LIB_PATH" ]; then git clone https://github.com/xwp/wp-dev-lib.git $DEV_LIB_PATH; fi
21 | - source $DEV_LIB_PATH/travis.install.sh
22 |
23 | script:
24 | - source $DEV_LIB_PATH/travis.script.sh
25 |
26 | after_script:
27 | - source $DEV_LIB_PATH/travis.after_script.sh
28 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | /* jshint node:true */
3 |
4 | module.exports = function( grunt ) {
5 | 'use strict';
6 |
7 | grunt.initConfig( {
8 |
9 | pkg: grunt.file.readJSON( 'package.json' ),
10 |
11 | // JavaScript linting with JSHint.
12 | jshint: {
13 | options: {
14 | jshintrc: '.jshintrc'
15 | },
16 | all: [
17 | 'Gruntfile.js',
18 | '*.js'
19 | ]
20 | },
21 |
22 | // Build a deploy-able plugin
23 | copy: {
24 | build: {
25 | src: [
26 | '*.php',
27 | 'php/*.php',
28 | 'js/*.js',
29 | 'readme.txt',
30 | '!Gruntfile.js'
31 | ],
32 | dest: 'build',
33 | expand: true,
34 | dot: true
35 | }
36 | },
37 |
38 | // Clean up the build
39 | clean: {
40 | build: {
41 | src: [ 'build' ]
42 | }
43 | },
44 |
45 | // VVV (Varying Vagrant Vagrants) Paths
46 | vvv: {
47 | 'plugin': '/srv/www/wordpress-develop/src/wp-content/plugins/<%= pkg.name %>',
48 | 'coverage': '/srv/www/default/coverage/<%= pkg.name %>'
49 | },
50 |
51 | // Shell actions
52 | shell: {
53 | options: {
54 | stdout: true,
55 | stderr: true
56 | },
57 | readme: {
58 | command: 'cd ./dev-lib && ./generate-markdown-readme' // Generate the readme.md
59 | },
60 | phpunit: {
61 | command: 'vagrant ssh -c "cd <%= vvv.plugin %> && phpunit"'
62 | },
63 | phpunit_c: {
64 | command: 'vagrant ssh -c "cd <%= vvv.plugin %> && phpunit --coverage-html <%= vvv.coverage %>"'
65 | }
66 | },
67 |
68 | // Deploys a git Repo to the WordPress SVN repo
69 | wp_deploy: {
70 | deploy: {
71 | options: {
72 | plugin_slug: '<%= pkg.name %>',
73 | build_dir: 'build',
74 | assets_dir: 'wp-assets'
75 | }
76 | }
77 | }
78 |
79 | } );
80 |
81 | // Load tasks
82 | grunt.loadNpmTasks( 'grunt-contrib-clean' );
83 | grunt.loadNpmTasks( 'grunt-contrib-copy' );
84 | grunt.loadNpmTasks( 'grunt-contrib-jshint' );
85 | grunt.loadNpmTasks( 'grunt-shell' );
86 | grunt.loadNpmTasks( 'grunt-wp-deploy' );
87 |
88 | // Register tasks
89 | grunt.registerTask( 'default', [
90 | 'jshint'
91 | ] );
92 |
93 | grunt.registerTask( 'readme', [
94 | 'shell:readme'
95 | ] );
96 |
97 | grunt.registerTask( 'phpunit', [
98 | 'shell:phpunit'
99 | ] );
100 |
101 | grunt.registerTask( 'phpunit_c', [
102 | 'shell:phpunit_c'
103 | ] );
104 |
105 | grunt.registerTask( 'dev', [
106 | 'default',
107 | 'readme'
108 | ] );
109 |
110 | grunt.registerTask( 'build', [
111 | 'default',
112 | 'readme',
113 | 'copy'
114 | ] );
115 |
116 | grunt.registerTask( 'deploy', [
117 | 'build',
118 | 'wp_deploy',
119 | 'clean'
120 | ] );
121 |
122 | };
123 |
--------------------------------------------------------------------------------
/customizer-dev-tools.php:
--------------------------------------------------------------------------------
1 | 1 ) {
202 | consoleParams.push( {
203 | format: '%O',
204 | value: params.slice( 1 )
205 | } );
206 | }
207 |
208 | component.log({
209 | namespace: namespaceParts,
210 | params: consoleParams
211 | });
212 |
213 | return originalTrigger.apply( this, arguments );
214 | };
215 | };
216 |
217 | /**
218 | * Wrap messenger methods.
219 | *
220 | * @param {object} args Args.
221 | * @param {wp.customize.Messenger} args.object Object.
222 | * @param {string} args.name Name.
223 | * @param {function} [args.filter] Filter.
224 | * @returns {void}
225 | */
226 | component.wrapMessengerMethods = function wrapMessengerMethods( args ) {
227 |
228 | var originalMethods;
229 |
230 | originalMethods = {
231 | send: {
232 | method: args.object.send
233 | },
234 | trigger: {
235 | method: args.object.trigger,
236 | name: 'receive'
237 | }
238 | };
239 |
240 | _.each( originalMethods, function( methodParams, methodName ) {
241 | args.object[ methodName ] = function() { // eslint-disable-line complexity
242 | var params, namespaceParts, id, consoleParams = [];
243 |
244 | params = Array.prototype.slice.call( arguments );
245 | id = params[0];
246 | namespaceParts = [ args.name, methodParams.name || methodName ];
247 |
248 | consoleParams.push( {
249 | format: '%o',
250 | value: id
251 | } );
252 | if ( 2 === params.length ) {
253 | consoleParams.push( {
254 | 'format': '( %o )',
255 | 'value': params[1]
256 | } );
257 | } else if ( params.length > 1 ) {
258 | consoleParams.push( {
259 | 'format': '( %O )',
260 | 'value': params.slice( 1 )
261 | } );
262 | }
263 |
264 | component.log({
265 | namespace: namespaceParts,
266 | params: consoleParams
267 | });
268 |
269 | return methodParams.method.apply( this, arguments );
270 | };
271 | } );
272 | };
273 |
274 | /**
275 | * Add setting change handler.
276 | *
277 | * @todo Be wary of comparing large values. Show smaller contextual diffs.
278 | * @param {wp.customize.Setting|wp.customize.Value} setting Setting.
279 | * @returns {void}
280 | */
281 | component.addSettingChangeListener = function addSettingChangeListener( setting ) {
282 |
283 | var originalFireWith = setting.callbacks.fireWith;
284 | setting.callbacks.fireWith = function fireWith( object, args ) {
285 | var newValue = _.clone( args[0] ), oldValue = _.clone( args[1] );
286 |
287 | if ( $.isPlainObject( newValue ) && $.isPlainObject( oldValue ) ) {
288 | _.each( _.keys( newValue ), function( key ) {
289 | if ( _.isEqual( newValue[ key ], oldValue[ key ] ) ) {
290 | delete newValue[ key ];
291 | delete oldValue[ key ];
292 | }
293 | } );
294 | }
295 |
296 | component.log({
297 | namespace: [ 'setting', 'change' ],
298 | params: [
299 | {
300 | values: [ setting.id, JSON.stringify( oldValue ), JSON.stringify( newValue ) ],
301 | format: '%o\n- %s\n+ %s'
302 | }
303 | ]
304 | });
305 |
306 | return originalFireWith.call( setting.callbacks, object, args );
307 | };
308 | };
309 |
310 | component.initLogging();
311 |
312 | return component;
313 |
314 | } )( wp.customize, jQuery );
315 |
--------------------------------------------------------------------------------
/js/pane.js:
--------------------------------------------------------------------------------
1 | /* global wp, console, CustomizerDevTools, JSON */
2 | ( function( component, api ) {
3 | 'use strict';
4 |
5 | api.bind( 'ready', function() {
6 | component.capturePreviewObjects();
7 | component.watchState( api.state );
8 | } );
9 |
10 | /**
11 | * Start logging.
12 | *
13 | * @param {string|RegExp} [filterPattern] Filter pattern.
14 | * @returns {void}
15 | */
16 | component.startLogging = function startLogging( filterPattern ) { // eslint-disable-line complexity
17 | var filter = null, serializedLoggingFilterPatterns;
18 | if ( filterPattern ) {
19 | filter = filterPattern;
20 | }
21 |
22 | if ( 0 === component.loggingFilterPatterns.length ) {
23 | console.info( 'Reload the customizer to get initial console logs. Logging in the customizer will continue in this browser session. You can stop logging via CustomizerDevTools.stopLogging()' );
24 | }
25 |
26 | if ( -1 === _.indexOf( component.loggingFilterPatterns, filter ) ) {
27 | component.loggingFilterPatterns.push( filter );
28 | }
29 |
30 | serializedLoggingFilterPatterns = JSON.stringify( component.loggingFilterPatterns, function replacer( key, value ) {
31 | if ( value instanceof RegExp ) {
32 | return {
33 | source: value.source,
34 | flags: value.flags
35 | };
36 | } else {
37 | return value;
38 | }
39 | } );
40 |
41 | localStorage.setItem(
42 | component.loggingPatternFiltersStorageKey,
43 | serializedLoggingFilterPatterns
44 | );
45 |
46 | api.previewer.send( 'dev-tools-start-logging', serializedLoggingFilterPatterns );
47 | };
48 |
49 | /**
50 | * Stop logging.
51 | *
52 | * @returns {void}
53 | */
54 | component.stopLogging = function stopLogging() {
55 | component.loggingFilterPatterns = [];
56 | api.previewer.send( 'dev-tools-stop-logging', true );
57 | };
58 |
59 | /**
60 | * Expose Customizer preview window and wp.customize object persistently, even as iframe window is destroyed with each refresh.
61 | *
62 | * @returns {void}
63 | */
64 | component.capturePreviewObjects = function capturePreviewObjects() {
65 | var onWindowChange = function( win ) {
66 | try {
67 | component.previewWindow = win;
68 | component.previewCustomize = component.previewWindow.wp.customize;
69 | } catch ( error ) {
70 | console.info( 'The wp.customize object from the customizer preview cannot be exposed as CustomizerDevTools.previewCustomize in the parent frame due to a cross-domain security restriction.', error );
71 | component.previewWindow = null;
72 | component.previewCustomize = null;
73 | api.previewer.targetWindow.unbind( onWindowChange );
74 | }
75 | };
76 |
77 | api.previewer.targetWindow.bind( onWindowChange );
78 | if ( api.previewer.targetWindow.get() ) {
79 | onWindowChange( api.previewer.targetWindow.get() );
80 | }
81 | };
82 |
83 | /**
84 | * Add construct state change listener.
85 | *
86 | * @param {wp.customize.Panel|wp.customize.Section|wp.customize.Control} construct Construct.
87 | * @returns {void}
88 | */
89 | component.addConstructStateChangeListener = function addConstructStateChangeListener( construct ) { // eslint-disable-line complexity
90 | var type;
91 | if ( construct.extended( api.Control ) ) {
92 | type = 'control';
93 | } else if ( construct.extended( api.Section ) ) {
94 | type = 'section';
95 | } else if ( construct.extended( api.Panel ) ) {
96 | type = 'panel';
97 | } else {
98 | type = 'unknown';
99 | }
100 |
101 | _.each( [ 'active', 'expanded' ], function( property ) {
102 | var originalFireWith, value;
103 | if ( ! construct[ property ] ) {
104 | return;
105 | }
106 | value = construct[ property ];
107 | originalFireWith = value.callbacks.fireWith;
108 |
109 | value.callbacks.fireWith = function fireWith( object, args ) {
110 | if ( args[1] !== args[0] ) {
111 | component.log({
112 | namespace: [ type, property ],
113 | params: [
114 | {
115 | value: construct.id,
116 | format: '%o'
117 | },
118 | {
119 | values: [ args[1], args[0] ],
120 | format: '(%o → %o)'
121 | }
122 | ]
123 | });
124 | }
125 | return originalFireWith.call( value.callbacks, object, args );
126 | };
127 | } );
128 | };
129 |
130 | /**
131 | * Watch state.
132 | *
133 | * @param {wp.customize.Values} state State.
134 | * @param {function} state.each Iterator method.
135 | * @param {function} state.has Add method.
136 | * @param {function} state.add Add method.
137 | * @returns {void}
138 | */
139 | component.watchState = function watchState( state ) {
140 | var originalAdd = state.add;
141 |
142 | // Watch existing state values.
143 | state.each( function( stateValue, id ) {
144 | component.watchStateValue( id, stateValue );
145 | } );
146 |
147 | /**
148 | * Wrap the state.add method since the state ID is not exposed in the add event.
149 | *
150 | * @param {string} id State ID.
151 | * @param {wp.customize.Value} stateValue Value.
152 | * @param {function} stateValue.get Getter.
153 | * @returns {void}
154 | */
155 | state.add = function addState( id, stateValue ) {
156 | if ( ! state.has( id ) ) {
157 |
158 | component.log({
159 | namespace: [ 'state', 'add' ],
160 | params: [
161 | {
162 | value: id,
163 | format: '%o'
164 | },
165 | {
166 | value: stateValue.get(),
167 | format: '%o'
168 | }
169 | ]
170 | });
171 | component.watchStateValue( id, stateValue );
172 | }
173 | originalAdd.call( this, id, stateValue );
174 | };
175 | };
176 |
177 | /**
178 | * Watch state value.
179 | *
180 | * The fireWith method is wrapped so that the event is guaranteed to log before
181 | * any of the registered callbacks.
182 | *
183 | * @param {string} id State ID.
184 | * @param {wp.customize.Value} stateValue State value.
185 | * @param {jQuery.Callbacks} stateValue.callbacks Callbacks.
186 | * @returns {void}
187 | */
188 | component.watchStateValue = function watchStateValue( id, stateValue ) {
189 | var originalFireWith = stateValue.callbacks.fireWith;
190 | stateValue.callbacks.fireWith = function fireWith( object, args ) {
191 |
192 | component.log({
193 | namespace: [ 'state', 'change' ],
194 | params: [
195 | {
196 | value: id,
197 | format: '%o'
198 | },
199 | {
200 | values: [ args[1], args[0] ],
201 | format: '(%o → %o)'
202 | }
203 | ]
204 | });
205 |
206 | return originalFireWith.call( stateValue.callbacks, object, args );
207 | };
208 | };
209 |
210 | component.wrapValuesMethods({
211 | object: api,
212 | name: 'setting',
213 | ignoreUntilReady: true
214 | });
215 | component.wrapValuesMethods({
216 | object: api.panel,
217 | name: 'panel',
218 | ignoreUntilReady: true
219 | });
220 | component.wrapValuesMethods({
221 | object: api.section,
222 | name: 'section',
223 | ignoreUntilReady: true
224 | });
225 | component.wrapValuesMethods({
226 | object: api.control,
227 | name: 'control',
228 | ignoreUntilReady: true
229 | });
230 |
231 | component.wrapTriggerMethod({
232 | object: api,
233 | name: 'events',
234 | filter: function( id ) {
235 | return ! ( 'add' === id || 'change' === id || 'remove' === id );
236 | }
237 | });
238 |
239 | component.wrapMessengerMethods({
240 | object: api.Previewer.prototype,
241 | name: 'messenger.previewer'
242 | });
243 |
244 | component.wrapMessengerMethods({
245 | object: api.PreviewFrame.prototype,
246 | name: 'messenger.previewframe'
247 | });
248 |
249 | api.bind( 'add', component.addSettingChangeListener );
250 | api.control.bind( 'add', component.addConstructStateChangeListener );
251 | api.section.bind( 'add', component.addConstructStateChangeListener );
252 | api.panel.bind( 'add', component.addConstructStateChangeListener );
253 |
254 | } )( CustomizerDevTools, wp.customize );
255 |
--------------------------------------------------------------------------------
/js/preview.js:
--------------------------------------------------------------------------------
1 | /* global wp, CustomizerDevTools, console */
2 | ( function( component, api ) {
3 | 'use strict';
4 |
5 | component.wrapValuesMethods({
6 | object: api,
7 | name: 'setting',
8 | ignoreUntilReady: true
9 | });
10 | component.wrapValuesMethods({
11 | object: api.selectiveRefresh.partial,
12 | name: 'partial',
13 | ignoreUntilReady: true
14 | });
15 |
16 | component.wrapTriggerMethod({
17 | object: api,
18 | name: 'events',
19 | filter: function( id ) {
20 | return ! ( 'add' === id || 'change' === id || 'remove' === id );
21 | }
22 | });
23 |
24 | component.wrapMessengerMethods({
25 | object: api.Preview.prototype,
26 | name: 'messenger.preview'
27 | });
28 |
29 | // @todo Add inspection of selective refresh events.
30 |
31 | api.bind( 'add', component.addSettingChangeListener );
32 |
33 | api.bind( 'preview-ready', function() {
34 | api.preview.bind( 'dev-tools-start-logging', function startLoggingPreview( serializedLoggingFilterPatterns ) {
35 | var loggingFilterPatterns;
36 | try {
37 | loggingFilterPatterns = component.parseSerializedLoggingFilterPatterns( serializedLoggingFilterPatterns );
38 | sessionStorage.setItem( component.loggingPatternFiltersStorageKey, serializedLoggingFilterPatterns );
39 | component.loggingFilterPatterns = loggingFilterPatterns;
40 | } catch ( err ) {
41 | console.error( err );
42 | }
43 | } );
44 |
45 | api.preview.bind( 'dev-tools-stop-logging', function() {
46 | sessionStorage.removeItem( component.loggingPatternFiltersStorageKey );
47 | component.loggingFilterPatterns = [];
48 | } );
49 | } );
50 |
51 | } )( CustomizerDevTools, wp.customize );
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "customizer-dev-tools",
3 | "version": "0.1.1",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/xwp/customizer-dev-tools.git"
11 | },
12 | "author": "XWP",
13 | "license": "GPL-2.0",
14 | "bugs": {
15 | "url": "https://github.com/xwp/customizer-dev-tools/issues"
16 | },
17 | "homepage": "https://github.com/xwp/customizer-dev-tools#readme",
18 | "devDependencies": {
19 | "eslint": "^3.0.1",
20 | "grunt": "~0.4.5",
21 | "grunt-contrib-clean": "~1.0.0",
22 | "grunt-contrib-copy": "~1.0.0",
23 | "grunt-contrib-jshint": "~1.0.0",
24 | "grunt-shell": "~1.3.0",
25 | "grunt-wp-deploy": "^1.1.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/php/class-plugin.php:
--------------------------------------------------------------------------------
1 | version = $matches[1];
30 | }
31 | }
32 |
33 | /**
34 | * Init.
35 | */
36 | public function init() {
37 | load_plugin_textdomain( 'customizer-dev-tools' );
38 |
39 | add_action( 'wp_default_scripts', array( $this, 'register_scripts' ), 11 );
40 | add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_controls_scripts' ) );
41 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_preview_scripts' ) );
42 | }
43 |
44 | /**
45 | * Register scripts.
46 | *
47 | * @param \WP_Scripts $wp_scripts Scripts.
48 | */
49 | public function register_scripts( \WP_Scripts $wp_scripts ) {
50 | $base_handle = 'customizer-dev-tools-base';
51 | $src = plugins_url( 'js/base.js', __DIR__ );
52 | $deps = array( 'customize-base' );
53 | $in_footer = 0;
54 | $wp_scripts->add( $base_handle, $src, $deps, $this->version, $in_footer );
55 | $wp_scripts->registered['customize-controls']->deps[] = $base_handle;
56 | $wp_scripts->registered['customize-preview']->deps[] = $base_handle;
57 |
58 | $handle_pane = 'customizer-dev-tools-pane';
59 | $src = plugins_url( 'js/pane.js', __DIR__ );
60 | $deps = array( 'customize-controls' );
61 | $in_footer = 0;
62 | $wp_scripts->add( $handle_pane, $src, $deps, $this->version, $in_footer );
63 |
64 | $handle_preview = 'customizer-dev-tools-preview';
65 | $src = plugins_url( 'js/preview.js', __DIR__ );
66 | $deps = array( 'customize-preview', 'customize-selective-refresh' );
67 | $in_footer = 0;
68 | $wp_scripts->add( $handle_preview, $src, $deps, $this->version, $in_footer );
69 | }
70 |
71 | /**
72 | * Enqueue pane (controls) scripts.
73 | */
74 | public function enqueue_controls_scripts() {
75 | wp_add_inline_script( 'customizer-dev-tools-base', 'CustomizerDevTools.context = "pane";', 'after' );
76 | wp_enqueue_script( 'customizer-dev-tools-pane' );
77 | }
78 |
79 | /**
80 | * Enqueue preview scripts.
81 | */
82 | public function enqueue_preview_scripts() {
83 | if ( ! is_customize_preview() ) {
84 | return;
85 | }
86 | wp_add_inline_script( 'customizer-dev-tools-base', 'CustomizerDevTools.context = "preview";', 'after' );
87 | wp_enqueue_script( 'customizer-dev-tools-preview' );
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 | CustomizerDevTools.startLogging()
20 |
21 |
22 | You can then either start interacting with the customizer app to see the log entries from that point, or you can reload the customizer to see the log entries emitted during the customizer initialization.
23 |
24 | Not everything in the customizer is currently implemented to emit a log entry. File an issue for any specific event that may be needed.
25 |
26 | Features:
27 |
28 | * Start logging of customizer events via running `CustomizerDevTools.startLogging()` from your browser console, and stop via `CustomizerDevTools.stopLogging()`. In the former, you can filter what is logged out by passing a string or regular expression (`RegExp` object) to match against the given log, or you can use the browser console's built-in log filtering.
29 | * Logs out all events triggered on `wp.customize`.
30 | * Logs out additions and changes to to `wp.customize.state`.
31 | * Logs changes to the `active` and `expanded` states for panels, sections, and controls.
32 | * Logs out messages sent and received by the pane (controls) and preview.
33 | * Logs out dynamic addition and removal of panels, sections, controls, partials, and settings (after the `ready` event triggers).
34 | * The `wp.customize` object from the Customizer preview is made persistently available from the parent frame via `CustomizerDevTools.previewCustomize`. This reference is updated whenever the preview refreshes, so you no longer have to change the frame window context to access this object.
35 | * In the same way, the current Customizer preview `window` is exposed as `CustomizerDevTools.previewWindow`. This is a shortcut for doing `wp.customize.previewer.targetWindow.get()`, and it has the added benefit of allowing the browser's dev tools to provide auto-completion.
36 |
37 | Make sure you also install the [Customizer Browser History](https://github.com/xwp/wp-customizer-browser-history) and [Customize Snapshots](https://github.com/xwp/wp-customize-snapshots) plugins so that you can reload the browser window and have the Customizer load with the same state as before you reloaded, including the persistence of the focused panel, section, control, the previewed URL, the scroll position in the preview, and which device is being previewed.
38 |
39 | Requires PHP≥5.3.
40 |
41 | == Screenshots ==
42 |
43 | 1. Messages sent/received and events triggered during Customizer load.
44 | 2. Logging the changing of the Site Title.
45 | 3. Logging the change of a nav menu item from a saved sate.
46 | 4. Expanding the Site Identity section and then navigating to edit a widget.
47 | 5. Changes to `wp.customize.state` when saving the customizer changes.
48 | 6. State changes, messages, and events related to saving.
49 |
50 | == Changelog ==
51 |
52 | = 0.1.1 [2017-11-14] =
53 |
54 | * Add setting change listener for settings in preview.
55 | * Tested up to 4.9.
56 |
57 | = 0.1.0 [2016-08-18] =
58 |
59 | Initial release
60 |
--------------------------------------------------------------------------------
/wp-assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xwp/wp-customizer-dev-tools/1e9e102070c146113edce6e1f1ad6395d98fdf29/wp-assets/screenshot-1.png
--------------------------------------------------------------------------------
/wp-assets/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xwp/wp-customizer-dev-tools/1e9e102070c146113edce6e1f1ad6395d98fdf29/wp-assets/screenshot-2.png
--------------------------------------------------------------------------------
/wp-assets/screenshot-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xwp/wp-customizer-dev-tools/1e9e102070c146113edce6e1f1ad6395d98fdf29/wp-assets/screenshot-3.png
--------------------------------------------------------------------------------
/wp-assets/screenshot-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xwp/wp-customizer-dev-tools/1e9e102070c146113edce6e1f1ad6395d98fdf29/wp-assets/screenshot-4.png
--------------------------------------------------------------------------------
/wp-assets/screenshot-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xwp/wp-customizer-dev-tools/1e9e102070c146113edce6e1f1ad6395d98fdf29/wp-assets/screenshot-5.png
--------------------------------------------------------------------------------
/wp-assets/screenshot-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xwp/wp-customizer-dev-tools/1e9e102070c146113edce6e1f1ad6395d98fdf29/wp-assets/screenshot-6.png
--------------------------------------------------------------------------------