-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
effects.js
190 lines (168 loc) · 6.07 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/**
* External dependencies
*/
import { reduce } from 'lodash';
/**
* WordPress dependencies
*/
import { select, subscribe, dispatch } from '@wordpress/data';
import { speak } from '@wordpress/a11y';
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
import {
metaBoxUpdatesSuccess,
requestMetaBoxUpdates,
openGeneralSidebar,
closeGeneralSidebar,
} from './actions';
import {
getActiveMetaBoxLocations,
getActiveGeneralSidebarName,
} from './selectors';
import { getMetaBoxContainer } from '../utils/meta-boxes';
import { onChangeListener } from './utils';
const VIEW_AS_LINK_SELECTOR = '#wp-admin-bar-view a';
const effects = {
SET_META_BOXES_PER_LOCATIONS( action, store ) {
// 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 );
}
} );
let wasSavingPost = select( 'core/editor' ).isSavingPost();
let wasAutosavingPost = select( 'core/editor' ).isAutosavingPost();
let wasPreviewingPost = select( 'core/editor' ).isPreviewingPost();
// Save metaboxes when performing a full save on the post.
subscribe( () => {
const isSavingPost = select( 'core/editor' ).isSavingPost();
const isAutosavingPost = select( 'core/editor' ).isAutosavingPost();
const isPreviewingPost = select( 'core/editor' ).isPreviewingPost();
const hasActiveMetaBoxes = select( 'core/edit-post' ).hasMetaBoxes();
// Save metaboxes on save completion, except for autosaves that are not a post preview.
const shouldTriggerMetaboxesSave = (
hasActiveMetaBoxes && (
( wasSavingPost && ! isSavingPost && ! wasAutosavingPost ) ||
( wasAutosavingPost && wasPreviewingPost && ! isPreviewingPost )
)
);
// Save current state for next inspection.
wasSavingPost = isSavingPost;
wasAutosavingPost = isAutosavingPost;
wasPreviewingPost = isPreviewingPost;
if ( shouldTriggerMetaboxesSave ) {
store.dispatch( requestMetaBoxUpdates() );
}
} );
},
REQUEST_META_BOX_UPDATES( action, store ) {
// Saves the wp_editor fields
if ( window.tinyMCE ) {
window.tinyMCE.triggerSave();
}
const state = store.getState();
// Additional data needed for backward compatibility.
// If we do not provide this data, the post will be overridden 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 = [
baseFormData,
...getActiveMetaBoxLocations( state ).map( ( location ) => (
new window.FormData( getMetaBoxContainer( location ) )
) ),
];
// 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
apiFetch( {
url: window._wpMetaBoxUrl,
method: 'POST',
body: formData,
parse: false,
} )
.then( () => store.dispatch( metaBoxUpdatesSuccess() ) );
},
SWITCH_MODE( action ) {
// Unselect blocks when we switch to the code editor.
if ( action.mode !== 'visual' ) {
dispatch( 'core/block-editor' ).clearSelectedBlock();
}
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/block-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 ) );
// Update View as link when currentPost link changes
const updateViewAsLink = ( newPermalink ) => {
if ( ! newPermalink ) {
return;
}
const nodeToUpdate = document.querySelector(
VIEW_AS_LINK_SELECTOR
);
if ( ! nodeToUpdate ) {
return;
}
nodeToUpdate.setAttribute( 'href', newPermalink );
};
subscribe( onChangeListener(
() => select( 'core/editor' ).getCurrentPost().link,
updateViewAsLink
) );
},
};
export default effects;