Skip to content

Commit

Permalink
URL: Enhance the way long URLs are handled in filterURLForDisplay (#2…
Browse files Browse the repository at this point in the history
…7530)

* Remove css ellipsis.

* Add unit tests for truncating url.

* Add argument to truncate url.

* Update changelog.
  • Loading branch information
hsingyuc authored Dec 22, 2020
1 parent 98c9d38 commit f2f89ed
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { ViewerSlot } from './viewer-slot';

export default function LinkPreview( { value, onEditClick } ) {
const displayURL =
( value && filterURLForDisplay( safeDecodeURI( value.url ) ) ) || '';
( value && filterURLForDisplay( safeDecodeURI( value.url ), 16 ) ) ||
'';

return (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ $block-editor-link-control-number-of-actions: 1;
.block-editor-link-control__search-item-title {
max-width: 230px;
overflow: hidden;
text-overflow: ellipsis;
}

.block-editor-link-control__search-item-title {
Expand Down
4 changes: 4 additions & 0 deletions packages/url/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### New Feature

- Add optional argument `maxLength` for truncating URL in `filterURLForDisplay`

## 2.16.0 (2020-06-15)

### New Feature
Expand Down
2 changes: 2 additions & 0 deletions packages/url/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ _Usage_

```js
const displayUrl = filterURLForDisplay( 'https://www.wordpress.org/gutenberg/' ); // wordpress.org/gutenberg
const imageUrl = filterURLForDisplay( 'https://www.wordpress.org/wp-content/uploads/img.png', 20 ); // …ent/uploads/img.png
```

_Parameters_

- _url_ `string`: Original URL.
- _maxLength_ `(number|null)`: URL length.

_Returns_

Expand Down
39 changes: 35 additions & 4 deletions packages/url/src/filter-url-for-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,53 @@
* Returns a URL for display.
*
* @param {string} url Original URL.
* @param {number|null} maxLength URL length.
*
* @example
* ```js
* const displayUrl = filterURLForDisplay( 'https://www.wordpress.org/gutenberg/' ); // wordpress.org/gutenberg
* const imageUrl = filterURLForDisplay( 'https://www.wordpress.org/wp-content/uploads/img.png', 20 ); // …ent/uploads/img.png
* ```
*
* @return {string} Displayed URL.
*/
export function filterURLForDisplay( url ) {
export function filterURLForDisplay( url, maxLength = null ) {
// Remove protocol and www prefixes.
const filteredURL = url.replace( /^(?:https?:)\/\/(?:www\.)?/, '' );
let filteredURL = url.replace( /^(?:https?:)\/\/(?:www\.)?/, '' );

// Ends with / and only has that single slash, strip it.
if ( filteredURL.match( /^[^\/]+\/$/ ) ) {
return filteredURL.replace( '/', '' );
filteredURL = filteredURL.replace( '/', '' );
}

return filteredURL;
const mediaRegexp = /([\w|:])*\.(?:jpg|jpeg|gif|png|svg)/;

if (
! maxLength ||
filteredURL.length <= maxLength ||
! filteredURL.match( mediaRegexp )
) {
return filteredURL;
}

// If the file is not greater than max length, return last portion of URL.
filteredURL = filteredURL.split( '?' )[ 0 ];
const urlPieces = filteredURL.split( '/' );
const file = urlPieces[ urlPieces.length - 1 ];
if ( file.length <= maxLength ) {
return '…' + filteredURL.slice( -maxLength );
}

// If the file is greater than max length, truncate the file.
const index = file.lastIndexOf( '.' );
const [ fileName, extension ] = [
file.slice( 0, index ),
file.slice( index + 1 ),
];
const truncatedFile = fileName.slice( -3 ) + '.' + extension;
return (
file.slice( 0, maxLength - truncatedFile.length - 1 ) +
'…' +
truncatedFile
);
}
48 changes: 48 additions & 0 deletions packages/url/src/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,54 @@ describe( 'filterURLForDisplay', () => {
const url = filterURLForDisplay( 'http://www.wordpress.org/something' );
expect( url ).toBe( 'wordpress.org/something' );
} );
it( 'should preserve the original url if no argument max length', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/wp-content/uploads/myimage.jpg'
);
expect( url ).toBe( 'wordpress.org/wp-content/uploads/myimage.jpg' );
} );
it( 'should preserve the original url if the url is short enough', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/ig.jpg',
20
);
expect( url ).toBe( 'wordpress.org/ig.jpg' );
} );
it( 'should return ellipsis, upper level pieces url, and filename when the url is long enough but filename is short enough', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/wp-content/uploads/myimage.jpg',
20
);
expect( url ).toBe( '…/uploads/myimage.jpg' );
} );
it( 'should return filename split by ellipsis plus three characters when filename is long enough', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/wp-content/uploads/superlongtitlewithextension.jpeg',
20
);
expect( url ).toBe( 'superlongti…ion.jpeg' );
} );
it( 'should remove query arguments', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/wp-content/uploads/myimage.jpeg?query_args=a',
20
);
expect( url ).toBe( '…uploads/myimage.jpeg' );
} );
it( 'should preserve the original url when it is not a file', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/wp-content/url/',
20
);
expect( url ).toBe( 'wordpress.org/wp-content/url/' );
} );
it( 'should return file split by ellipsis when the file name has multiple periods', () => {
const url = filterURLForDisplay(
'http://www.wordpress.org/wp-content/uploads/filename.2020.12.20.png',
20
);
expect( url ).toBe( 'filename.202….20.png' );
} );
} );

describe( 'cleanForSlug', () => {
Expand Down

0 comments on commit f2f89ed

Please sign in to comment.