-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PLANET-7635 Move remaining code from plugin
This is in preparation to finally retire it
- Loading branch information
Showing
22 changed files
with
1,404 additions
and
14 deletions.
There are no files selected for viewing
187 changes: 187 additions & 0 deletions
187
assets/src/block-editor/AssignOnlyFlatTermSelector/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/** | ||
* The logic of this component was copied from https://github.com/WordPress/gutenberg/blob/master/packages/editor/src/components/post-taxonomies/flat-term-selector.js | ||
* initially, then the functionality of creating non-existing terms was removed from it. | ||
*/ | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import {useEffect, useMemo, useState} from '@wordpress/element'; | ||
import {FormTokenField, withFilters} from '@wordpress/components'; | ||
import {useSelect, useDispatch} from '@wordpress/data'; | ||
import {store as coreStore} from '@wordpress/core-data'; | ||
import {useDebounce} from '@wordpress/compose'; | ||
import {decodeEntities} from '@wordpress/html-entities'; | ||
|
||
const {__, _x, sprintf} = wp.i18n; | ||
|
||
/** | ||
* Shared reference to an empty array for cases where it is important to avoid | ||
* returning a new array reference on every invocation. | ||
* | ||
* @type {Array<any>} | ||
*/ | ||
const EMPTY_ARRAY = []; | ||
|
||
/** | ||
* Module constants | ||
*/ | ||
const MAX_TERMS_SUGGESTIONS = 20; | ||
const DEFAULT_QUERY = { | ||
per_page: MAX_TERMS_SUGGESTIONS, | ||
_fields: 'id,name', | ||
context: 'view', | ||
}; | ||
|
||
const isSameTermName = (termA, termB) => | ||
decodeEntities(termA).toLowerCase() === | ||
decodeEntities(termB).toLowerCase(); | ||
|
||
const termNamesToIds = (names, terms) => names.map( | ||
termName => terms.find(term => isSameTermName(term.name, termName)).id | ||
); | ||
|
||
export const AssignOnlyFlatTermSelector = ({slug}) => { | ||
const [values, setValues] = useState([]); | ||
const [search, setSearch] = useState(''); | ||
const debouncedSearch = useDebounce(setSearch, 500); | ||
|
||
const { | ||
terms, | ||
taxonomy, | ||
hasAssignAction, | ||
hasResolvedTerms, | ||
} = useSelect( | ||
select => { | ||
const {getCurrentPost, getEditedPostAttribute} = select('core/editor'); | ||
const {getEntityRecords, getTaxonomy, hasFinishedResolution} = select(coreStore); | ||
const post = getCurrentPost(); | ||
const _taxonomy = getTaxonomy(slug); | ||
const _termIds = _taxonomy ? getEditedPostAttribute(_taxonomy.rest_base) : EMPTY_ARRAY; | ||
|
||
const query = { | ||
...DEFAULT_QUERY, | ||
include: _termIds.join(','), | ||
per_page: -1, | ||
}; | ||
|
||
return { | ||
hasAssignAction: _taxonomy ? post._links?.['wp:action-assign-' + _taxonomy.rest_base] ?? false : false, | ||
taxonomy: _taxonomy, | ||
termIds: _termIds, | ||
terms: _termIds.length ? getEntityRecords('taxonomy', slug, query) : EMPTY_ARRAY, | ||
hasResolvedTerms: hasFinishedResolution('getEntityRecords', ['taxonomy', slug, query]), | ||
}; | ||
}, | ||
[slug] | ||
); | ||
|
||
const {searchResults} = useSelect( | ||
select => { | ||
const {getEntityRecords} = select(coreStore); | ||
|
||
return { | ||
searchResults: !!search ? getEntityRecords('taxonomy', slug, { | ||
...DEFAULT_QUERY, | ||
search, | ||
}) : EMPTY_ARRAY, | ||
}; | ||
}, | ||
[search, slug] | ||
); | ||
|
||
// Update terms state only after the selectors are resolved. | ||
// We're using this to avoid terms temporarily disappearing on slow networks | ||
// while core data makes REST API requests. | ||
useEffect(() => { | ||
if (hasResolvedTerms) { | ||
const newValues = (terms ?? []).map(term => | ||
decodeEntities(term.name) | ||
); | ||
|
||
setValues(newValues); | ||
} | ||
}, [terms, hasResolvedTerms]); | ||
|
||
const suggestions = useMemo(() => { | ||
return (searchResults ?? []).map(term => | ||
decodeEntities(term.name) | ||
); | ||
}, [searchResults]); | ||
|
||
const {editPost} = useDispatch('core/editor'); | ||
|
||
if (!hasAssignAction) { | ||
return null; | ||
} | ||
|
||
function onUpdateTerms(newTermIds) { | ||
editPost({[taxonomy.rest_base]: newTermIds}); | ||
} | ||
|
||
function onChange(termNames) { | ||
const availableTerms = [ | ||
...(terms ?? []), | ||
...(searchResults ?? []), | ||
]; | ||
|
||
const uniqueTerms = termNames.reduce((acc, name) => { | ||
if ( | ||
!acc.some(n => n.toLowerCase() === name.toLowerCase()) | ||
) { | ||
acc.push(name); | ||
} | ||
return acc; | ||
}, []); | ||
|
||
// Filter to remove new terms since we don't allow creation. | ||
const allowedTerms = uniqueTerms.filter( | ||
termName => availableTerms.find(term => isSameTermName(term.name, termName)) | ||
); | ||
|
||
setValues(allowedTerms); | ||
|
||
return onUpdateTerms(termNamesToIds(allowedTerms, availableTerms)); | ||
} | ||
|
||
const newTermLabel = | ||
taxonomy?.labels?.add_new_item ?? | ||
(slug === 'post_tag' ? __('Add new tag') : __('Add new Term')); | ||
const singularName = | ||
taxonomy?.labels?.singular_name ?? | ||
(slug === 'post_tag' ? __('Tag') : __('Term')); | ||
const termAddedLabel = sprintf( | ||
/* translators: %s: term name. */ | ||
_x('%s added', 'term'), | ||
singularName | ||
); | ||
const termRemovedLabel = sprintf( | ||
/* translators: %s: term name. */ | ||
_x('%s removed', 'term'), | ||
singularName | ||
); | ||
const removeTermLabel = sprintf( | ||
/* translators: %s: term name. */ | ||
_x('Remove %s', 'term'), | ||
singularName | ||
); | ||
|
||
return ( | ||
<FormTokenField | ||
__next40pxDefaultSize | ||
value={values} | ||
suggestions={suggestions} | ||
onChange={onChange} | ||
onInputChange={debouncedSearch} | ||
maxSuggestions={MAX_TERMS_SUGGESTIONS} | ||
label={newTermLabel} | ||
messages={{ | ||
added: termAddedLabel, | ||
removed: termRemovedLabel, | ||
remove: removeTermLabel, | ||
}} | ||
/> | ||
); | ||
}; | ||
|
||
export default withFilters('editor.PostTaxonomyType')(AssignOnlyFlatTermSelector); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* Return an editable image block | ||
* | ||
* - display image credits in caption during edition | ||
* | ||
* @param {Object} BlockEdit | ||
* @return {Object} interface to edit images on the Editor | ||
*/ | ||
export const ImageBlockEdit = BlockEdit => props => { | ||
if ('core/image' !== props.name) { | ||
return <BlockEdit {...props} />; | ||
} | ||
|
||
const {attributes, clientId} = props; | ||
const {id, className = ''} = attributes; | ||
|
||
// Get image data | ||
const image = wp.data.useSelect(select => id ? select('core').getMedia(id) : null); | ||
const credits = image?.meta?._credit_text; | ||
const captionText = image?.caption?.raw; | ||
// Compile data for insertion | ||
let image_credits = null; | ||
if (credits && credits.length > 0 && (!captionText || !captionText.includes(credits))) { | ||
image_credits = credits.includes('©') ? credits : `© ${credits}`; | ||
} | ||
|
||
const block_id = clientId ? `block-${clientId}` : null; | ||
|
||
// Update width and height when sized rounded styles are selected | ||
if (className.includes('is-style-rounded-')) { | ||
const classes = className.split(' '); | ||
const size = classes.find(c => c.includes('is-style-rounded-')).replace('is-style-rounded-', '') || 180; | ||
attributes.width = parseInt(size); | ||
attributes.height = parseInt(size); | ||
} | ||
|
||
// Force to use square images when the class `square-*` is added | ||
if (className.includes('square-')) { | ||
const size = className.slice(className.search('square-') + 'square-'.length).split(' ')[0] || 180; | ||
attributes.width = parseInt(size); | ||
attributes.height = parseInt(size); | ||
} | ||
|
||
return ( | ||
<> | ||
<BlockEdit {...props} /> | ||
{block_id && image_credits && ( | ||
captionText ? | ||
<style dangerouslySetInnerHTML={{ | ||
__html: `#${block_id} figcaption::after { content: " ${image_credits}"; }`, | ||
}}> | ||
</style> : | ||
<figcaption style={{marginTop: -24}}>{image_credits}</figcaption> | ||
)} | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const {addFilter} = wp.hooks; | ||
|
||
import {ImageBlockEdit} from './ImageBlockEdit'; | ||
|
||
export const addBlockFilters = () => { | ||
addFileBlockFilter(); | ||
addImageBlockFilter(); | ||
addGravityFormsBlockFilter(); | ||
}; | ||
|
||
const addFileBlockFilter = () => { | ||
const setDownloadButtonToggleDefaultFalse = (settings, name) => { | ||
if ('core/file' !== name) { | ||
return settings; | ||
} | ||
|
||
settings.attributes.showDownloadButton.default = false; | ||
|
||
return settings; | ||
}; | ||
|
||
addFilter('blocks.registerBlockType', 'planet4-blocks/filters/file', setDownloadButtonToggleDefaultFalse); | ||
}; | ||
|
||
const addImageBlockFilter = () => addFilter('editor.BlockEdit', 'core/image/edit', ImageBlockEdit); | ||
|
||
// Enforce "AJAX" toggle setting enabled by default, on Gravity form block. | ||
const addGravityFormsBlockFilter = () => { | ||
const setAJAXToggleDefaultTrue = (settings, name) => { | ||
if ('gravityforms/form' !== name) { | ||
return settings; | ||
} | ||
|
||
settings.attributes.ajax.default = true; | ||
|
||
return settings; | ||
}; | ||
|
||
addFilter('blocks.registerBlockType', 'planet4-blocks/filters/gravity-form', setAJAXToggleDefaultTrue); | ||
}; |
Oops, something went wrong.