-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
effects.js
156 lines (141 loc) · 5.16 KB
/
effects.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* External dependencies
*/
import { reduce, some } from 'lodash';
/**
* WordPress dependencies
*/
import { select, subscribe } from '@wordpress/data';
import { speak } from '@wordpress/a11y';
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import {
metaBoxUpdatesSuccess,
setMetaBoxSavedData,
requestMetaBoxUpdates,
openGeneralSidebar,
closeGeneralSidebar,
} from './actions';
import { getMetaBoxes, getActiveGeneralSidebarName } from './selectors';
import { getMetaBoxContainer } from '../utils/meta-boxes';
import { onChangeListener } from './utils';
const effects = {
INITIALIZE_META_BOX_STATE( action, store ) {
const hasActiveMetaBoxes = some( action.metaBoxes );
if ( ! hasActiveMetaBoxes ) {
return;
}
// Allow toggling metaboxes panels
// We need to wait for all scripts to load
// If the meta box loads the post script, it will already trigger this.
// After merge in Core, make sure to drop the timeout and update the postboxes script
// to avoid the double binding.
setTimeout( () => {
const postType = select( 'core/editor' ).getCurrentPostType();
if ( window.postboxes.page !== postType ) {
window.postboxes.add_postbox_toggles( postType );
}
} );
// Initialize metaboxes state
const dataPerLocation = reduce( action.metaBoxes, ( memo, isActive, location ) => {
if ( isActive ) {
memo[ location ] = jQuery( getMetaBoxContainer( location ) ).serialize();
}
return memo;
}, {} );
store.dispatch( setMetaBoxSavedData( dataPerLocation ) );
// Saving metaboxes when saving posts
subscribe( onChangeListener( select( 'core/editor' ).isSavingPost, ( isSavingPost ) => {
if ( ! isSavingPost ) {
store.dispatch( requestMetaBoxUpdates() );
}
} ) );
},
REQUEST_META_BOX_UPDATES( action, store ) {
const state = store.getState();
const dataPerLocation = reduce( getMetaBoxes( state ), ( memo, metabox, location ) => {
if ( metabox.isActive ) {
memo[ location ] = jQuery( getMetaBoxContainer( location ) ).serialize();
}
return memo;
}, {} );
store.dispatch( setMetaBoxSavedData( dataPerLocation ) );
// Additional data needed for backwards compatibility.
// If we do not provide this data the post will be overriden with the default values.
const post = select( 'core/editor' ).getCurrentPost( state );
const additionalData = [
post.comment_status ? [ 'comment_status', post.comment_status ] : false,
post.ping_status ? [ 'ping_status', post.ping_status ] : false,
post.sticky ? [ 'sticky', post.sticky ] : false,
[ 'post_author', post.author ],
].filter( Boolean );
// We gather all the metaboxes locations data and the base form data
const baseFormData = new window.FormData( document.querySelector( '.metabox-base-form' ) );
const formDataToMerge = reduce( getMetaBoxes( state ), ( memo, metabox, location ) => {
if ( metabox.isActive ) {
memo.push( new window.FormData( getMetaBoxContainer( location ) ) );
}
return memo;
}, [ baseFormData ] );
// Merge all form data objects into a single one.
const formData = reduce( formDataToMerge, ( memo, currentFormData ) => {
for ( const [ key, value ] of currentFormData ) {
memo.append( key, value );
}
return memo;
}, new window.FormData() );
additionalData.forEach( ( [ key, value ] ) => formData.append( key, value ) );
// Save the metaboxes
wp.apiRequest( {
url: window._wpMetaBoxUrl,
method: 'POST',
processData: false,
contentType: false,
data: formData,
} )
.then( () => store.dispatch( metaBoxUpdatesSuccess() ) );
},
SWITCH_MODE( action ) {
const message = action.mode === 'visual' ? __( 'Visual editor selected' ) : __( 'Code editor selected' );
speak( message, 'assertive' );
},
INIT( _, store ) {
// Select the block settings tab when the selected block changes
subscribe( onChangeListener(
() => !! select( 'core/editor' ).getBlockSelectionStart(),
( hasBlockSelection ) => {
if ( ! select( 'core/edit-post' ).isEditorSidebarOpened() ) {
return;
}
if ( hasBlockSelection ) {
store.dispatch( openGeneralSidebar( 'edit-post/block' ) );
} else {
store.dispatch( openGeneralSidebar( 'edit-post/document' ) );
}
} )
);
const isMobileViewPort = () => select( 'core/viewport' ).isViewportMatch( '< medium' );
const adjustSidebar = ( () => {
// contains the sidebar we close when going to viewport sizes lower than medium.
// This allows to reopen it when going again to viewport sizes greater than medium.
let sidebarToReOpenOnExpand = null;
return ( isSmall ) => {
if ( isSmall ) {
sidebarToReOpenOnExpand = getActiveGeneralSidebarName( store.getState() );
if ( sidebarToReOpenOnExpand ) {
store.dispatch( closeGeneralSidebar() );
}
} else if ( sidebarToReOpenOnExpand && ! getActiveGeneralSidebarName( store.getState() ) ) {
store.dispatch( openGeneralSidebar( sidebarToReOpenOnExpand ) );
}
};
} )();
adjustSidebar( isMobileViewPort() );
// Collapse sidebar when viewport shrinks.
// Reopen sidebar it if viewport expands and it was closed because of a previous shrink.
subscribe( onChangeListener( isMobileViewPort, adjustSidebar ) );
},
};
export default effects;