New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
State: Set template validity on block reset #9916
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { last } from 'lodash'; | ||
import { compact, last } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
|
@@ -35,6 +35,7 @@ import { | |
getSelectedBlock, | ||
getTemplate, | ||
getTemplateLock, | ||
isValidTemplate, | ||
} from './selectors'; | ||
import { | ||
fetchReusableBlocks, | ||
|
@@ -54,6 +55,36 @@ import { | |
AUTOSAVE_POST_NOTICE_ID, | ||
} from './effects/posts'; | ||
|
||
/** | ||
* Block validity is a function of blocks state (at the point of a | ||
* reset) and the template setting. As a compromise to its placement | ||
* across distinct parts of state, it is implemented here as a side- | ||
* effect of the block reset action. | ||
* | ||
* @param {Object} action RESET_BLOCKS action. | ||
* @param {Object} store Store instance. | ||
* | ||
* @return {?Object} New validity set action if validity has changed. | ||
*/ | ||
export function validateBlocksToTemplate( action, store ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As right now, besides the RESET_BLOCKS action this function also receives the SETUP_EDITOR_STATE, and my expectation is that this function will probably never need anything from the action besides the blocks, would it make sense for this function to receive the blocks instead of the action? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So part of my purpose here in extracting this to a named function is to try to set a precedent for well-named / intentioned effect handlers. As you propose, we'd need a function which itself calls to Illustrated by code: // Bad:
RANDOM_ACTION( action, store ) {
// Do A
// Do B
// Do C
}
// Good:
RANDOM_ACTION: [
doA( action, store ) {},
doB( action, store ) {},
doC( action, store ) {},
] In general, I would have no issue with what you propose, and it'd probably make things even more clearly intentioned and easier to test. With needing the template and template lock details, it becomes a little more effort to be able to organize. I might poke around at it to see if I can find some happy compromise, but otherwise I'm not strongly inclined to change it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's a fair point, even a function that is just supposed to pass the blocks to another function can then be changed to a different purpose. Feel free to keep the current version as probably it will keep code more organized in the long run. |
||
const state = store.getState(); | ||
const template = getTemplate( state ); | ||
const templateLock = getTemplateLock( state ); | ||
|
||
// Unlocked templates are considered always valid because they act | ||
// as default values only. | ||
const isBlocksValidToTemplate = ( | ||
! template || | ||
templateLock !== 'all' || | ||
doBlocksMatchTemplate( action.blocks, template ) | ||
); | ||
|
||
// Update if validity has changed. | ||
if ( isBlocksValidToTemplate !== isValidTemplate( state ) ) { | ||
return setTemplateValidity( isBlocksValidToTemplate ); | ||
} | ||
} | ||
|
||
export default { | ||
REQUEST_POST_UPDATE: ( action, store ) => { | ||
requestPostUpdate( action, store ); | ||
|
@@ -113,26 +144,18 @@ export default { | |
] | ||
) ); | ||
}, | ||
SETUP_EDITOR( action, { getState } ) { | ||
SETUP_EDITOR( action, store ) { | ||
const { post, autosave } = action; | ||
const state = getState(); | ||
const template = getTemplate( state ); | ||
const templateLock = getTemplateLock( state ); | ||
const isNewPost = post.status === 'auto-draft'; | ||
const state = store.getState(); | ||
|
||
// Parse content as blocks | ||
let blocks = parse( post.content.raw ); | ||
let isValidTemplate = true; | ||
|
||
// Apply a template for new posts only, if exists. | ||
const isNewPost = post.status === 'auto-draft'; | ||
const template = getTemplate( state ); | ||
if ( isNewPost && template ) { | ||
// Apply a template for new posts only, if exists. | ||
blocks = synchronizeBlocksWithTemplate( blocks, template ); | ||
} else { | ||
// Unlocked templates are considered always valid because they act as default values only. | ||
isValidTemplate = ( | ||
! template || | ||
templateLock !== 'all' || | ||
doBlocksMatchTemplate( blocks, template ) | ||
); | ||
} | ||
|
||
// Include auto draft title in edits while not flagging post as dirty | ||
|
@@ -158,22 +181,29 @@ export default { | |
); | ||
} | ||
|
||
return [ | ||
setTemplateValidity( isValidTemplate ), | ||
setupEditorState( post, blocks, edits ), | ||
...( autosaveAction ? [ autosaveAction ] : [] ), | ||
]; | ||
const setupAction = setupEditorState( post, blocks, edits ); | ||
|
||
return compact( [ | ||
setupAction, | ||
autosaveAction, | ||
|
||
// TODO: This is temporary, necessary only so long as editor setup | ||
// is a separate action from block resetting. | ||
// | ||
// See: https://github.com/WordPress/gutenberg/pull/9403 | ||
validateBlocksToTemplate( setupAction, store ), | ||
] ); | ||
}, | ||
RESET_BLOCKS: [ | ||
validateBlocksToTemplate, | ||
], | ||
SYNCHRONIZE_TEMPLATE( action, { getState } ) { | ||
const state = getState(); | ||
const blocks = getBlocks( state ); | ||
const template = getTemplate( state ); | ||
const updatedBlockList = synchronizeBlocksWithTemplate( blocks, template ); | ||
|
||
return [ | ||
resetBlocks( updatedBlockList ), | ||
setTemplateValidity( true ), | ||
]; | ||
return resetBlocks( updatedBlockList ); | ||
}, | ||
CHECK_TEMPLATE_VALIDITY( action, { getState } ) { | ||
const state = getState(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we are deprecating this function should we keep the effect that allows plugins to invoke an explicit validation?
Imagining a plugin that adds blocks (wrongly without verifying the locking) after each block insert the plugin called checkTemplateValidity to have an explicit check and if necessary the warning would appear, now that will not work right?
I think the version should be 4.1 and not 4.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we should try to keep the behavior intact, yes. This probably explains why I hadn't removed it from #9403.
Will change 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the rebased b94c076, I both restored the
CHECK_TEMPLATE_VALIDITY
effect handler and changed the deprecation version from 4.0 to 4.1.