-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathdom-updater.js
64 lines (59 loc) · 2.13 KB
/
dom-updater.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* External dependencies
*/
import { subscribe, select } from '@wordpress/data';
import domReady from '@wordpress/dom-ready';
import { isEmpty, isEqual } from 'lodash';
/**
* DOM updater
*
* @param {string[]} options A list of option names to keep track of.
* @param {Function} getOptionValue A function that given an option name as a string, returns the current option value.
*/
export default ( options, getOptionValue ) => {
domReady( () => {
// Book-keeping.
const currentOptions = {};
let previousOptions = {};
const cssVariables = {};
options.forEach( ( option ) => {
cssVariables[ option ] = `--${ option.replace( '_', '-' ) }`;
} );
let styleElement = null;
subscribe( () => {
/**
* Do nothing until the editor is ready. This is required when
* working in wpcom iframe environment to avoid running code before
* everything has loaded, which can cause bugs like the following.
*
* @see https://github.com/Automattic/wp-calypso/pull/40690
*/
const isEditorReady = select( 'core/editor' ).__unstableIsEditorReady;
if ( isEditorReady && isEditorReady() === false ) {
return;
}
// Create style element if it has not been created yet. Must happen
// after the editor is ready or the style element will be appended
// before the styles it needs to affect.
if ( ! styleElement ) {
styleElement = document.createElement( 'style' );
document.body.appendChild( styleElement );
}
// Maybe bail-out early.
options.forEach( ( option ) => {
currentOptions[ option ] = getOptionValue( option );
} );
if ( isEmpty( currentOptions ) || isEqual( currentOptions, previousOptions ) ) {
return;
}
previousOptions = { ...currentOptions };
// Update style node. We need this to be a stylesheet rather than inline styles
// so the styles apply to all editor instances incl. previews.
let declarationList = '';
Object.keys( currentOptions ).forEach( ( key ) => {
declarationList += `${ cssVariables[ key ] }:${ currentOptions[ key ] };`;
} );
styleElement.textContent = `.edit-post-visual-editor.editor-styles-wrapper{${ declarationList }}`;
} );
} );
};