diff --git a/src/util/urlHelpers.js b/src/util/urlHelpers.js index c21875ebb5..61e5d94349 100644 --- a/src/util/urlHelpers.js +++ b/src/util/urlHelpers.js @@ -5,13 +5,55 @@ const { LatLng, LatLngBounds } = sdkTypes; export const LISTING_PAGE_PENDING_APPROVAL_VARIANT = 'pending-approval'; -export const createSlug = str => - encodeURIComponent( - str - .toLowerCase() - .split(' ') - .join('-') +// slug creation form random texts +// From Gist thread: https://gist.github.com/mathewbyrne/1280286 +export const createSlug = str => { + let text = str + .toString() + .toLowerCase() + .trim(); + + const sets = [ + { to: 'a', from: '[ÀÁÂÃÄÅÆĀĂĄẠẢẤẦẨẪẬẮẰẲẴẶ]' }, + { to: 'c', from: '[ÇĆĈČ]' }, + { to: 'd', from: '[ÐĎĐÞ]' }, + { to: 'e', from: '[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]' }, + { to: 'g', from: '[ĜĞĢǴ]' }, + { to: 'h', from: '[ĤḦ]' }, + { to: 'i', from: '[ÌÍÎÏĨĪĮİỈỊ]' }, + { to: 'j', from: '[Ĵ]' }, + { to: 'ij', from: '[IJ]' }, + { to: 'k', from: '[Ķ]' }, + { to: 'l', from: '[ĹĻĽŁ]' }, + { to: 'm', from: '[Ḿ]' }, + { to: 'n', from: '[ÑŃŅŇ]' }, + { to: 'o', from: '[ÒÓÔÕÖØŌŎŐỌỎỐỒỔỖỘỚỜỞỠỢǪǬƠ]' }, + { to: 'oe', from: '[Œ]' }, + { to: 'p', from: '[ṕ]' }, + { to: 'r', from: '[ŔŖŘ]' }, + { to: 's', from: '[ߌŜŞŠ]' }, + { to: 't', from: '[ŢŤ]' }, + { to: 'u', from: '[ÙÚÛÜŨŪŬŮŰŲỤỦỨỪỬỮỰƯ]' }, + { to: 'w', from: '[ẂŴẀẄ]' }, + { to: 'x', from: '[ẍ]' }, + { to: 'y', from: '[ÝŶŸỲỴỶỸ]' }, + { to: 'z', from: '[ŹŻŽ]' }, + { to: '-', from: "[·/_,:;']" }, + ]; + + sets.forEach(set => { + text = text.replace(new RegExp(set.from, 'gi'), set.to); + }); + + return encodeURIComponent( + text + .replace(/\s+/g, '-') // Replace spaces with - + .replace(/[^\w-]+/g, '') // Remove all non-word chars + .replace(/--+/g, '-') // Replace multiple - with single - + .replace(/^-+/, '') // Trim - from start of text + .replace(/-+$/, '') // Trim - from end of text ); +}; /** * Parse float from a string diff --git a/src/util/urlHelpers.test.js b/src/util/urlHelpers.test.js index e6b2b94f22..bf8d456843 100644 --- a/src/util/urlHelpers.test.js +++ b/src/util/urlHelpers.test.js @@ -1,5 +1,6 @@ import { types as sdkTypes } from './sdkLoader'; import { + createSlug, parseFloatNum, encodeLatLng, decodeLatLng, @@ -15,6 +16,28 @@ const SPACE = encodeURIComponent(' '); const COMMA = encodeURIComponent(','); describe('urlHelpers', () => { + describe('parseFloatNum()', () => { + it('handles empty string (returns "")', () => { + expect(createSlug('')).toEqual(''); + }); + + it('handles space characters', () => { + expect(createSlug('ice hockey tournament')).toEqual('ice-hockey-tournament'); + }); + + it('handles special characters', () => { + expect(createSlug('ice hockey!%/@$€ for the win')).toEqual('ice-hockey-for-the-win'); + }); + + it('handles multiple "-"', () => { + expect(createSlug('testing ---- dashes')).toEqual('testing-dashes'); + }); + + it('handles umlauts', () => { + expect(createSlug('jääkiekko / pesäpallo')).toEqual('jaakiekko-pesapallo'); + }); + }); + describe('parseFloatNum()', () => { it('handles empty value', () => { expect(parseFloatNum('')).toBeNull();