Skip to content

Commit

Permalink
Improve code with tests and adding check for TLDs
Browse files Browse the repository at this point in the history
  • Loading branch information
getdave committed Jun 6, 2023
1 parent 42fe981 commit b0777c0
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
29 changes: 28 additions & 1 deletion packages/block-editor/src/components/link-control/is-url-like.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,38 @@ export default function isURLLike( val ) {
const protocol = getProtocol( val );
const protocolIsValid = isValidProtocol( protocol );

const mayBeTLD = hasPossibleTLD( val );

const isWWW = val?.startsWith( 'www.' );
const isHTTPProtocol = /^(http|https)/.test( val ) && protocolIsValid;
const isMailTo = val?.startsWith( 'mailto:' ) && protocolIsValid;
const isTel = val?.startsWith( 'tel:' ) && protocolIsValid;
const isInternal = val?.startsWith( '#' ) && isValidFragment( val );

return isHTTPProtocol || isWWW || isMailTo || isTel || isInternal;
return (
isHTTPProtocol || isWWW || isMailTo || isTel || isInternal || mayBeTLD
);
}

/**
* Checks if a given URL has a valid Top-Level Domain (TLD).
*
* @param {string} url - The URL to check.
* @param {number} maxLength - The maximum length of the TLD.
* @return {boolean} Returns true if the URL has a valid TLD, false otherwise.
*/
function hasPossibleTLD( url, maxLength = 6 ) {
// Clean the URL by removing anything after the first occurrence of "?" or "#".
const cleanedURL = url.split( /[?#]/ )[ 0 ];

// Regular expression explanation:
// - (?<=\S) : Positive lookbehind assertion to ensure there is at least one non-whitespace character before the TLD
// - \. : Matches a literal dot (.)
// - [a-zA-Z_]{2,maxLength} : Matches 2 to maxLength letters or underscores, representing the TLD
// - (?:\/|$) : Non-capturing group that matches either a forward slash (/) or the end of the string
const regex = new RegExp(
`(?<=\\S)\\.(?:[a-zA-Z_]{2,${ maxLength }})(?:\\/|$)`
);

return regex.test( cleanedURL );
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,27 @@ describe( 'isURLLike', () => {
it( 'returns true for internal anchor ("hash") links.', () => {
expect( isURLLike( '#someinternallink' ) ).toBe( true );
} );

// use .each to test multiple cases
it.each( [
[ true, 'http://example.com' ],
[ true, 'https://test.co.uk?query=param' ],
[ true, 'ftp://openai.ai?param=value#section' ],
[ true, 'example.com' ],
[ true, 'http://example.com?query=param#section' ],
[ true, 'https://test.co.uk/some/path' ],
[ true, 'ftp://openai.ai/some/path' ],
[ true, 'example.org/some/path' ],
[ true, 'example_test.tld' ],
[ true, 'example_test.com' ],
[ false, 'example' ],
[ false, '.com' ],
[ true, '_test.com' ],
[ true, 'http://example_test.com' ],
] )(
'returns %s when testing against string "%s" for a valid TLD',
( expected, testString ) => {
expect( isURLLike( testString ) ).toBe( expected );
}
);
} );

0 comments on commit b0777c0

Please sign in to comment.