-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Inserter: use lighter grammar parse to check allowed status #64902
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
Changes from 1 commit
8e42420
9f497fc
cadcd81
8d78213
3a244ab
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 |
|---|---|---|
|
|
@@ -20,7 +20,7 @@ import { | |
| checkAllowListRecursive, | ||
| getAllPatternsDependants, | ||
| getInsertBlockTypeDependants, | ||
| getParsedPattern, | ||
| getGrammar, | ||
| } from './utils'; | ||
| import { INSERTER_PATTERN_TYPES } from '../components/inserter/block-patterns-tab/utils'; | ||
| import { STORE_NAME } from './constants'; | ||
|
|
@@ -300,10 +300,10 @@ export const hasAllowedPatterns = createRegistrySelector( ( select ) => | |
| if ( ! inserter ) { | ||
| return false; | ||
| } | ||
| const { blocks } = getParsedPattern( pattern ); | ||
| const grammar = getGrammar( pattern ); | ||
| return ( | ||
| checkAllowListRecursive( blocks, allowedBlockTypes ) && | ||
| blocks.every( ( { name: blockName } ) => | ||
| checkAllowListRecursive( grammar, allowedBlockTypes ) && | ||
|
Member
Author
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. It's funny that
Member
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. It looks like it was used when the method was introduced - #30366. We should probably check why it was removed in case there was an issue with grammar parser.
Member
Author
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. My guess is that there was a need elsewhere for parsed content, and someone switched it to a full parse. But yes we should try to fish it out of the history.
Member
Author
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. It was removed in #32376.
Member
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. And it was removed to improve correctness of the block names: fallback names, deprecations that migrate to another block type etc.
Member
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.
I'm now looking at the code and it's totally intentional! There is a token of type
Member
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 the goal of the parser is to represent the source document, so creating a fallback block for whitespace captures that and lets us write it back. there was considerable discussion about this a number of years ago. the suggestion in each case is just to ignore the whitespace-only fallback blocks.
Member
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. @dmsnell do you remember why the fallback blocks with whitespace are created only on top level, but not in inner blocks? If the goal of the parser is to represent the source document well, it should also capture whitespace in a nested markup. Two nice things about using the lightweight parser for parsing patterns:
Member
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.
@jsnajdr are you certain what you are seeing is as you describe it? these aren't "empty blocks" so much as they are HTML content outside of a block, or "HTML soup." the whitespace isn't ignored just because it's inside of another block, but when it's HTML content inside of a block it becomes part of that block's inner HTML and inner content. in fact, this is always the case because the whitespace is just You can explore this at my parser explorer - https://dmsnell.github.io/peg-parser-explorer/ - just make sure to click the Fetch button to load the block grammar.
Member
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. Thanks for clarification @dmsnell, now I fully understand what's going on. At the top level the whitespace is represented as void blocks, because there is no For inner blocks, the whitespace is in There is also |
||
| grammar.every( ( { name: blockName } ) => | ||
| canInsertBlockType( state, blockName, rootClientId ) | ||
| ) | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ import { | |
| getAllPatternsDependants, | ||
| getInsertBlockTypeDependants, | ||
| getParsedPattern, | ||
| getGrammar, | ||
| } from './utils'; | ||
| import { orderBy } from '../utils/sorting'; | ||
| import { STORE_NAME } from './constants'; | ||
|
|
@@ -2376,17 +2377,27 @@ export const __experimentalGetAllowedPatterns = createRegistrySelector( | |
| const { getAllPatterns } = unlock( select( STORE_NAME ) ); | ||
| const patterns = getAllPatterns(); | ||
| const { allowedBlockTypes } = getSettings( state ); | ||
|
|
||
| const parsedPatterns = patterns | ||
| .filter( ( { inserter = true } ) => !! inserter ) | ||
| .map( getParsedPattern ); | ||
| .map( ( pattern ) => { | ||
| return { | ||
| ...pattern, | ||
| get blocks() { | ||
|
Member
Author
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. I'm adding this for back compat and also for us. Eventually we should adjust the uses of this selector to not expect blocks and only parse when it's needed. |
||
| return getParsedPattern( pattern ).blocks; | ||
| }, | ||
| }; | ||
| } ); | ||
|
|
||
| const availableParsedPatterns = parsedPatterns.filter( | ||
| ( { blocks } ) => | ||
| checkAllowListRecursive( blocks, allowedBlockTypes ) | ||
| ( pattern ) => | ||
| checkAllowListRecursive( | ||
| getGrammar( pattern ), | ||
| allowedBlockTypes | ||
| ) | ||
| ); | ||
| const patternsAllowed = availableParsedPatterns.filter( | ||
| ( { blocks } ) => | ||
| blocks.every( ( { name } ) => | ||
| ( pattern ) => | ||
| getGrammar( pattern ).every( ( { blockName: name } ) => | ||
| canInsertBlockType( state, name, rootClientId ) | ||
| ) | ||
| ); | ||
|
|
||
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.
Grammar parse is lightening fast, but probably still a good idea to cache.
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.
It's worth measuring the impact if possible, sometimes caching adds more overhead than the actual operation.