diff --git a/cypress/tests/core/blocks/block-anchors.js b/cypress/tests/core/blocks/block-anchors.js index 1166b0ce26..91fe8ed989 100644 --- a/cypress/tests/core/blocks/block-anchors.js +++ b/cypress/tests/core/blocks/block-anchors.js @@ -63,9 +63,9 @@ describe('Block Tests: Anchors', () => { cy.contains('Slate Heading Anchors'); cy.get('h2[id="title-1"]').contains('Title 1'); cy.get('h2[id="title-2"]').contains('Title 2'); - cy.get('a[href="#title-1"]').click(); + cy.get('.table-of-contents a[href="/my-page#title-1"]').click(); cy.get('h2[id="title-1"]').scrollIntoView().should('be.visible'); - cy.get('a[href="#title-2"]').click(); + cy.get('.table-of-contents a[href="/my-page#title-2"]').click(); cy.get('h2[id="title-2"]').scrollIntoView().should('be.visible'); }); }); diff --git a/news/4402.bugfix b/news/4402.bugfix new file mode 100644 index 0000000000..aee68dbeb1 --- /dev/null +++ b/news/4402.bugfix @@ -0,0 +1 @@ +Fix back button in the search block to execute the search by adding two useEffects that update the facets and search data based on the current URL. @MihaelaCretu11 \ No newline at end of file diff --git a/news/5019.bugfix b/news/5019.bugfix new file mode 100644 index 0000000000..f3a5d4a243 --- /dev/null +++ b/news/5019.bugfix @@ -0,0 +1 @@ +Fix use of CSS modules in webpack 5. @wesleybl diff --git a/news/5058.bugfix b/news/5058.bugfix new file mode 100644 index 0000000000..2a67cc6d3e --- /dev/null +++ b/news/5058.bugfix @@ -0,0 +1 @@ +Fix toc accessibility issue @dobri1408 diff --git a/packages/volto-slate/src/editor/render.jsx b/packages/volto-slate/src/editor/render.jsx index 45ab42ca75..5b5542e4f0 100644 --- a/packages/volto-slate/src/editor/render.jsx +++ b/packages/volto-slate/src/editor/render.jsx @@ -174,13 +174,12 @@ export const renderLinkElement = (tagName) => { appPathname.concat(`#${slug}`), ); const intl = useIntl(); - return slate.useLinkedHeadings === false ? ( - + {children} ) : ( - + {children} {mode === 'view' && slug && ( (WrappedComponent) => { const multiFacets = data.facets ?.filter((facet) => facet?.multiple) .map((facet) => facet?.field?.value); - const [facets, setFacets] = React.useState( - Object.assign( - {}, - ...urlQuery.map(({ i, v }) => ({ [i]: v })), // TODO: the 'o' should be kept. This would be a major refactoring of the facets - - // support for simple filters like ?Subject=something - // TODO: since the move to hash params this is no longer working. - // We'd have to treat the location.search and manage it just like the - // hash, to support it. We can read it, but we'd have to reset it as - // well, so at that point what's the difference to the hash? - ...configuredFacets.map((f) => - locationSearchData[f] - ? { - [f]: - multiFacets.indexOf(f) > -1 - ? [locationSearchData[f]] - : locationSearchData[f], - } - : {}, - ), - ), - ); + const [facets, setFacets] = React.useState({}); + const previousUrlQuery = usePrevious(urlQuery); + + React.useEffect(() => { + if (!isEqual(urlQuery, previousUrlQuery)) { + setFacets( + Object.assign( + {}, + ...urlQuery.map(({ i, v }) => ({ [i]: v })), // TODO: the 'o' should be kept. This would be a major refactoring of the facets + + // support for simple filters like ?Subject=something + // TODO: since the move to hash params this is no longer working. + // We'd have to treat the location.search and manage it just like the + // hash, to support it. We can read it, but we'd have to reset it as + // well, so at that point what's the difference to the hash? + ...configuredFacets.map((f) => + locationSearchData[f] + ? { + [f]: + multiFacets.indexOf(f) > -1 + ? [locationSearchData[f]] + : locationSearchData[f], + } + : {}, + ), + ), + ); + } + }, [ + urlQuery, + configuredFacets, + locationSearchData, + multiFacets, + previousUrlQuery, + ]); const [sortOn, setSortOn] = React.useState(data?.query?.sort_on); const [sortOrder, setSortOrder] = React.useState(data?.query?.sort_order); - const [searchData, setSearchData] = React.useState( - getInitialState(data, facets, urlSearchText, id), - ); + const [searchData, setSearchData] = React.useState({}); + + React.useEffect(() => { + setSearchData(getInitialState(data, facets, urlSearchText, id)); + }, [facets, data, urlSearchText, id]); const timeoutRef = React.useRef(); const facetSettings = data?.facets; diff --git a/src/components/manage/Blocks/Title/__snapshots__/View.test.jsx.snap b/src/components/manage/Blocks/Title/__snapshots__/View.test.jsx.snap index cc62ae1b9c..7c7c1c0d60 100644 --- a/src/components/manage/Blocks/Title/__snapshots__/View.test.jsx.snap +++ b/src/components/manage/Blocks/Title/__snapshots__/View.test.jsx.snap @@ -4,6 +4,7 @@ exports[`renders a view title component 1`] = `

My Title { - const history = useHistory(); - return map(items, (item) => { const { id, level, title, override_toc, plaintext } = item; const slug = override_toc @@ -23,14 +20,7 @@ const RenderListItems = ({ items, data }) => { return ( item && ( - { - history.push({ hash: slug }); - }} - > - {title} - + {title} {item.items?.length > 0 && ( Hello this is a sample page @@ -28,8 +31,11 @@ Array [ role="listitem" > Test level 3 diff --git a/webpack-plugins/webpack-less-plugin.js b/webpack-plugins/webpack-less-plugin.js index eed28455a5..1b35d87e46 100644 --- a/webpack-plugins/webpack-less-plugin.js +++ b/webpack-plugins/webpack-less-plugin.js @@ -4,6 +4,24 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const PostCssFlexBugFixes = require('postcss-flexbugs-fixes'); const postcssLoadConfig = require('postcss-load-config'); +const interpolateName = require('loader-utils').interpolateName; + +function normalizePath(file) { + return path.sep === '\\' ? file.replace(/\\/g, '/') : file; +} + +// Custom function to not use 'loaderContext._module.matchResource' in hashing CSS class name. +function getLocalIdent(loaderContext, localIdentName, localName, options) { + const relativeResourcePath = normalizePath( + path.relative(options.context, loaderContext.resourcePath), + ); + + // eslint-disable-next-line no-param-reassign + options.content = `${options.hashPrefix}${relativeResourcePath}\x00${localName}`; + + return interpolateName(loaderContext, localIdentName, options); +} + const hasPostCssConfig = () => { try { return !!postcssLoadConfig.sync(); @@ -52,6 +70,7 @@ const defaultOptions = { modules: { auto: true, localIdentName: '[name]__[local]___[hash:base64:5]', + getLocalIdent: getLocalIdent, }, }, },