diff --git a/packages/api-fetch/CHANGELOG.md b/packages/api-fetch/CHANGELOG.md index 92be444b5299b5..acf08ace60ee54 100644 --- a/packages/api-fetch/CHANGELOG.md +++ b/packages/api-fetch/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Removed `getStablePath` function. Please use `normalizePath` from `@wordpress/url` package instead ([#35992](https://github.com/WordPress/gutenberg/pull/35992)).`` + ## 5.2.0 (2021-07-21) ### New feature diff --git a/packages/api-fetch/src/middlewares/preloading.js b/packages/api-fetch/src/middlewares/preloading.js index 6fba40edde4951..16b061f1d1668b 100644 --- a/packages/api-fetch/src/middlewares/preloading.js +++ b/packages/api-fetch/src/middlewares/preloading.js @@ -1,37 +1,7 @@ /** - * Given a path, returns a normalized path where equal query parameter values - * will be treated as identical, regardless of order they appear in the original - * text. - * - * @param {string} path Original path. - * - * @return {string} Normalized path. + * WordPress dependencies */ -export function getStablePath( path ) { - const splitted = path.split( '?' ); - const query = splitted[ 1 ]; - const base = splitted[ 0 ]; - if ( ! query ) { - return base; - } - - // 'b=1&c=2&a=5' - return ( - base + - '?' + - query - // [ 'b=1', 'c=2', 'a=5' ] - .split( '&' ) - // [ [ 'b, '1' ], [ 'c', '2' ], [ 'a', '5' ] ] - .map( ( entry ) => entry.split( '=' ) ) - // [ [ 'a', '5' ], [ 'b, '1' ], [ 'c', '2' ] ] - .sort( ( a, b ) => a[ 0 ].localeCompare( b[ 0 ] ) ) - // [ 'a=5', 'b=1', 'c=2' ] - .map( ( pair ) => pair.join( '=' ) ) - // 'a=5&b=1&c=2' - .join( '&' ) - ); -} +import { normalizePath } from '@wordpress/url'; /** * @param {Record} preloadedData @@ -39,7 +9,7 @@ export function getStablePath( path ) { */ function createPreloadingMiddleware( preloadedData ) { const cache = Object.keys( preloadedData ).reduce( ( result, path ) => { - result[ getStablePath( path ) ] = preloadedData[ path ]; + result[ normalizePath( path ) ] = preloadedData[ path ]; return result; }, /** @type {Record} */ ( {} ) ); @@ -47,7 +17,7 @@ function createPreloadingMiddleware( preloadedData ) { const { parse = true } = options; if ( typeof options.path === 'string' ) { const method = options.method || 'GET'; - const path = getStablePath( options.path ); + const path = normalizePath( options.path ); if ( 'GET' === method && cache[ path ] ) { const cacheData = cache[ path ]; diff --git a/packages/api-fetch/src/middlewares/test/preloading.js b/packages/api-fetch/src/middlewares/test/preloading.js index 4add5a46424cc9..b266ec5e488c47 100644 --- a/packages/api-fetch/src/middlewares/test/preloading.js +++ b/packages/api-fetch/src/middlewares/test/preloading.js @@ -1,32 +1,9 @@ /** * Internal dependencies */ -import createPreloadingMiddleware, { getStablePath } from '../preloading'; +import createPreloadingMiddleware from '../preloading'; describe( 'Preloading Middleware', () => { - describe( 'getStablePath', () => { - it( 'returns same value if no query parameters', () => { - const path = '/foo/bar'; - - expect( getStablePath( path ) ).toBe( path ); - } ); - - it( 'returns a stable path', () => { - const abc = getStablePath( '/foo/bar?a=5&b=1&c=2' ); - const bca = getStablePath( '/foo/bar?b=1&c=2&a=5' ); - const bac = getStablePath( '/foo/bar?b=1&a=5&c=2' ); - const acb = getStablePath( '/foo/bar?a=5&c=2&b=1' ); - const cba = getStablePath( '/foo/bar?c=2&b=1&a=5' ); - const cab = getStablePath( '/foo/bar?c=2&a=5&b=1' ); - - expect( abc ).toBe( bca ); - expect( bca ).toBe( bac ); - expect( bac ).toBe( acb ); - expect( acb ).toBe( cba ); - expect( cba ).toBe( cab ); - } ); - } ); - describe( 'given preloaded data', () => { describe( 'when data is requested from a preloaded endpoint', () => { describe( 'and it is requested for the first time', () => { diff --git a/packages/edit-navigation/CHANGELOG.md b/packages/edit-navigation/CHANGELOG.md index 2e271ef03a604b..26ed24d6d3d82f 100644 --- a/packages/edit-navigation/CHANGELOG.md +++ b/packages/edit-navigation/CHANGELOG.md @@ -2,4 +2,10 @@ ## Unreleased -- Initial version of the package. +### Internal + +- Removed `getStablePath` function. Please use `normalizePath` from `@wordpress/url` package instead ([#35992](https://github.com/WordPress/gutenberg/pull/35992)). + +## 1.0.0 + +- Initial version of the package. diff --git a/packages/edit-navigation/src/utils/index.js b/packages/edit-navigation/src/utils/index.js index 2229f6a1c8b329..1fb79c32c17bc6 100644 --- a/packages/edit-navigation/src/utils/index.js +++ b/packages/edit-navigation/src/utils/index.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { normalizePath } from '@wordpress/url'; + /** * The purpose of this function is to create a middleware that is responsible for preloading menu-related data. * It uses data that is returned from the /__experimental/menus endpoint for requests @@ -10,7 +15,7 @@ */ export function createMenuPreloadingMiddleware( preloadedData ) { const cache = Object.keys( preloadedData ).reduce( ( result, path ) => { - result[ getStablePath( path ) ] = preloadedData[ path ]; + result[ normalizePath( path ) ] = preloadedData[ path ]; return result; }, /** @type {Record} */ ( {} ) ); @@ -28,7 +33,7 @@ export function createMenuPreloadingMiddleware( preloadedData ) { return next( options ); } - const path = getStablePath( options.path ); + const path = normalizePath( options.path ); if ( ! menusDataLoaded && cache[ path ] ) { menusDataLoaded = true; return sendSuccessResponse( cache[ path ], parse ); @@ -85,38 +90,3 @@ function sendSuccessResponse( responseData, parse ) { } ) ); } - -/** - * Given a path, returns a normalized path where equal query parameter values - * will be treated as identical, regardless of order they appear in the original - * text. - * - * @param {string} path Original path. - * - * @return {string} Normalized path. - */ -export function getStablePath( path ) { - const splitted = path.split( '?' ); - const query = splitted[ 1 ]; - const base = splitted[ 0 ]; - if ( ! query ) { - return base; - } - - // 'b=1&c=2&a=5' - return ( - base + - '?' + - query - // [ 'b=1', 'c=2', 'a=5' ] - .split( '&' ) - // [ [ 'b, '1' ], [ 'c', '2' ], [ 'a', '5' ] ] - .map( ( entry ) => entry.split( '=' ) ) - // [ [ 'a', '5' ], [ 'b, '1' ], [ 'c', '2' ] ] - .sort( ( a, b ) => a[ 0 ].localeCompare( b[ 0 ] ) ) - // [ 'a=5', 'b=1', 'c=2' ] - .map( ( pair ) => pair.join( '=' ) ) - // 'a=5&b=1&c=2' - .join( '&' ) - ); -} diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index 43a16de8c58c40..6a5590db93b5fb 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Feature + +- Added new `normalizePath` function ([#35992](https://github.com/WordPress/gutenberg/pull/35992)). + ## 3.2.3 (2021-10-12) ### Bug Fix diff --git a/packages/url/README.md b/packages/url/README.md index 5ab853cf64e9cb..c829b1c199d3d3 100644 --- a/packages/url/README.md +++ b/packages/url/README.md @@ -449,6 +449,20 @@ _Returns_ - `boolean`: True if the argument contains a valid query string. +### normalizePath + +Given a path, returns a normalized path where equal query parameter values +will be treated as identical, regardless of order they appear in the original +text. + +_Parameters_ + +- _path_ `string`: Original path. + +_Returns_ + +- `string`: Normalized path. + ### prependHTTP Prepends "http\://" to a url, if it looks like something that is meant to be a TLD. diff --git a/packages/url/src/index.js b/packages/url/src/index.js index eb4ee3237fab8e..9baa7babdc7898 100644 --- a/packages/url/src/index.js +++ b/packages/url/src/index.js @@ -23,3 +23,4 @@ export { safeDecodeURIComponent } from './safe-decode-uri-component'; export { filterURLForDisplay } from './filter-url-for-display'; export { cleanForSlug } from './clean-for-slug'; export { getFilename } from './get-filename'; +export { normalizePath } from './normalize-path'; diff --git a/packages/url/src/normalize-path.js b/packages/url/src/normalize-path.js new file mode 100644 index 00000000000000..b47e37d836348e --- /dev/null +++ b/packages/url/src/normalize-path.js @@ -0,0 +1,34 @@ +/** + * Given a path, returns a normalized path where equal query parameter values + * will be treated as identical, regardless of order they appear in the original + * text. + * + * @param {string} path Original path. + * + * @return {string} Normalized path. + */ +export function normalizePath( path ) { + const splitted = path.split( '?' ); + const query = splitted[ 1 ]; + const base = splitted[ 0 ]; + if ( ! query ) { + return base; + } + + // 'b=1&c=2&a=5' + return ( + base + + '?' + + query + // [ 'b=1', 'c=2', 'a=5' ] + .split( '&' ) + // [ [ 'b, '1' ], [ 'c', '2' ], [ 'a', '5' ] ] + .map( ( entry ) => entry.split( '=' ) ) + // [ [ 'a', '5' ], [ 'b, '1' ], [ 'c', '2' ] ] + .sort( ( a, b ) => a[ 0 ].localeCompare( b[ 0 ] ) ) + // [ 'a=5', 'b=1', 'c=2' ] + .map( ( pair ) => pair.join( '=' ) ) + // 'a=5&b=1&c=2' + .join( '&' ) + ); +} diff --git a/packages/url/src/test/index.js b/packages/url/src/test/index.js index 51bb69419bfa60..58b5d53a34846f 100644 --- a/packages/url/src/test/index.js +++ b/packages/url/src/test/index.js @@ -30,6 +30,7 @@ import { cleanForSlug, getQueryArgs, getFilename, + normalizePath, } from '../'; import wptData from './fixtures/wpt-data'; @@ -985,3 +986,26 @@ describe( 'cleanForSlug', () => { expect( cleanForSlug( null ) ).toBe( '' ); } ); } ); + +describe( 'normalizePath', () => { + it( 'returns same value if no query parameters', () => { + const path = '/foo/bar'; + + expect( normalizePath( path ) ).toBe( path ); + } ); + + it( 'returns a stable path', () => { + const abc = normalizePath( '/foo/bar?a=5&b=1&c=2' ); + const bca = normalizePath( '/foo/bar?b=1&c=2&a=5' ); + const bac = normalizePath( '/foo/bar?b=1&a=5&c=2' ); + const acb = normalizePath( '/foo/bar?a=5&c=2&b=1' ); + const cba = normalizePath( '/foo/bar?c=2&b=1&a=5' ); + const cab = normalizePath( '/foo/bar?c=2&a=5&b=1' ); + + expect( abc ).toBe( bca ); + expect( bca ).toBe( bac ); + expect( bac ).toBe( acb ); + expect( acb ).toBe( cba ); + expect( cba ).toBe( cab ); + } ); +} );