diff --git a/package-lock.json b/package-lock.json index e9c6933af1844b..75e9ef7fe93768 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18276,7 +18276,7 @@ "version": "file:packages/url", "requires": { "@babel/runtime": "^7.16.0", - "lodash": "^4.17.21" + "remove-accents": "^0.4.2" } }, "@wordpress/viewport": { @@ -52225,6 +52225,11 @@ "resolved": "https://registry.npmjs.org/rememo/-/rememo-4.0.0.tgz", "integrity": "sha512-6BAfg1Dqg6UteZBEH9k6EHHersM86/EcBOMtJV+h+xEn1GC3H+gAgJWpexWYAamAxD0qXNmIt50iS/zuZKnQag==" }, + "remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", diff --git a/packages/url/package.json b/packages/url/package.json index f6461729b74589..516cd0bcb446fa 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -28,7 +28,7 @@ "sideEffects": false, "dependencies": { "@babel/runtime": "^7.16.0", - "lodash": "^4.17.21" + "remove-accents": "^0.4.2" }, "publishConfig": { "access": "public" diff --git a/packages/url/src/clean-for-slug.js b/packages/url/src/clean-for-slug.js index 5773b70ed92929..49bc367e7e57d7 100644 --- a/packages/url/src/clean-for-slug.js +++ b/packages/url/src/clean-for-slug.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { deburr, trim } from 'lodash'; +import removeAccents from 'remove-accents'; /** * Performs some basic cleanup of a string for use as a post slug. @@ -23,11 +23,15 @@ export function cleanForSlug( string ) { if ( ! string ) { return ''; } - return trim( - deburr( string ) + return ( + removeAccents( string ) + // Convert each group of whitespace, periods, and forward slashes to a hyphen. .replace( /[\s\./]+/g, '-' ) + // Remove anything that's not a letter, number, underscore or hyphen. .replace( /[^\p{L}\p{N}_-]+/gu, '' ) - .toLowerCase(), - '-' + // Convert to lowercase + .toLowerCase() + // Remove any remaining leading or trailing hyphens. + .replace( /(^-+)|(-+$)/g, '' ) ); } diff --git a/packages/url/src/test/index.js b/packages/url/src/test/index.js index 83370e74d67f8e..4eab5bbd96dc8f 100644 --- a/packages/url/src/test/index.js +++ b/packages/url/src/test/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { every } from 'lodash'; - /** * Internal dependencies */ @@ -44,35 +39,37 @@ describe( 'isURL', () => { } ); describe( 'isEmail', () => { - it( 'returns true when given things that look like an email', () => { - const emails = [ - 'simple@wordpress.org', - 'very.common@wordpress.org', - 'disposable.style.email.with+symbol@wordpress.org', - 'other.email-with-hyphen@wordpress.org', - 'fully-qualified-domain@wordpress.org', - 'user.name+tag+sorting@wordpress.org', - 'x@wordpress.org', - 'wordpress-indeed@strange-wordpress.org', - 'wordpress@s.wordpress', - ]; - - expect( every( emails, isEmail ) ).toBe( true ); - } ); - - it( "returns false when given things that don't look like an email", () => { - const emails = [ - 'Abc.wordpress.org', - 'A@b@c@wordpress.org', - 'a"b(c)d,e:f;gi[jk]l@wordpress.org', - 'just"not"right@wordpress.org', - 'this is"notallowed@wordpress.org', - 'this still"not\\allowed@wordpress.org', - '1234567890123456789012345678901234567890123456789012345678901234+x@wordpress.org', - ]; - - expect( every( emails, isEmail ) ).toBe( false ); - } ); + it.each( [ + 'simple@wordpress.org', + 'very.common@wordpress.org', + 'disposable.style.email.with+symbol@wordpress.org', + 'other.email-with-hyphen@wordpress.org', + 'fully-qualified-domain@wordpress.org', + 'user.name+tag+sorting@wordpress.org', + 'x@wordpress.org', + 'wordpress-indeed@strange-wordpress.org', + 'wordpress@s.wordpress', + '1234567890123456789012345678901234567890123456789012345678901234+x@wordpress.org', + ] )( + 'returns true when given things that look like an email: %s', + ( email ) => { + expect( isEmail( email ) ).toBe( true ); + } + ); + + it.each( [ + 'Abc.wordpress.org', + 'A@b@c@wordpress.org', + 'a"b(c)d,e:f;gi[jk]l@wordpress.org', + 'just"not"right@wordpress.org', + 'this is"notallowed@wordpress.org', + 'this still"not\\allowed@wordpress.org', + ] )( + "returns false when given things that don't look like an email: %s", + ( email ) => { + expect( isEmail( email ) ).toBe( false ); + } + ); } ); describe( 'getProtocol', () => { @@ -1001,6 +998,12 @@ describe( 'cleanForSlug', () => { expect( cleanForSlug( '안녕하세요 ' ) ).toBe( '안녕하세요' ); expect( cleanForSlug( '繁体字 ' ) ).toBe( '繁体字' ); } ); + + it( 'Should trim multiple leading and trailing dashes', () => { + expect( cleanForSlug( ' -Is th@t Déjà_vu- ' ) ).toBe( + 'is-tht-deja_vu' + ); + } ); } ); describe( 'normalizePath', () => {