From 70c3a517876e8a3d6413abe28db9438e3701fe6b Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Mon, 13 Nov 2023 11:39:48 +0100 Subject: [PATCH 1/2] fix(linkify): include trailing slash in URL if present --- .../elements/src/lib/metadata-info/linkify.directive.spec.ts | 4 ++-- libs/ui/elements/src/lib/metadata-info/linkify.directive.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts index 09f9b93ecd..b31630f0c9 100644 --- a/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts +++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts @@ -4,7 +4,7 @@ import { By } from '@angular/platform-browser' import { GnUiLinkifyDirective } from './linkify.directive' @Component({ - template: `
Click this link https://www.example.com
`, + template: `
Click this link https://www.example.com/
`, }) class TestComponent {} @@ -32,7 +32,7 @@ describe('GnUiLinkifyDirective', () => { const anchorElement = debugElement.query(By.css('a')) const href = anchorElement.nativeElement.getAttribute('href') - expect(href).toBe('https://www.example.com') + expect(href).toBe('https://www.example.com/') }) it('should have the target attribute set to "_blank"', () => { diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts index 0ae4289b10..c807d0947d 100644 --- a/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts +++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts @@ -30,7 +30,7 @@ export class GnUiLinkifyDirective implements OnInit { } private linkifyText(text: string): string { - return text.replace(/(\bhttps?:\/\/\S+\b)/g, (match) => { + return text.replace(/(\bhttps?:\/\/\S+\b\/?)/g, (match) => { return `${match} open_in_new` }) From a44eb0fbd1ab76f0f74f6247308d88344e0da0b8 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Tue, 28 Nov 2023 11:26:04 +0100 Subject: [PATCH 2/2] fix(linkify): add tests and improve regexp --- .../metadata-info/linkify.directive.spec.ts | 91 +++++++++++++++---- .../lib/metadata-info/linkify.directive.ts | 2 +- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts index b31630f0c9..1fffa88aa2 100644 --- a/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts +++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts @@ -3,10 +3,61 @@ import { Component, DebugElement } from '@angular/core' import { By } from '@angular/platform-browser' import { GnUiLinkifyDirective } from './linkify.directive' +const testingUrls = [ + ['First link http://bla.org no slash', 'http://bla.org'], + + ['Second link http://bla.org/ with slash', 'http://bla.org/'], + [ + 'Third link https://www.bla.org/hello no slash', + 'https://www.bla.org/hello', + ], + [ + 'Forth link https://www.bla.org/hello/ with slash', + 'https://www.bla.org/hello/', + ], + [ + 'Fifth link https://www.bla.org/hello/file.png file with extension', + 'https://www.bla.org/hello/file.png', + ], + [ + 'Sixth link https://www.bla.org/hello/file.png?aa=bb query parameters', + 'https://www.bla.org/hello/file.png?aa=bb', + ], + [ + 'Seventh link https://www.bla.org/hello/file.png?aa=%20/bb&cc=d query parameters', + 'https://www.bla.org/hello/file.png?aa=%20/bb&cc=d', + ], + [ + 'Eighth link https://www.bla.org/hello/file.png?aa= empty query parameter', + 'https://www.bla.org/hello/file.png?aa=', + ], + [ + 'Nineth link http://foo.com/more_(than)_one_(parens) with parentheses', + 'http://foo.com/more_(than)_one_(parens)', + ], + [ + 'Tenth link http://foo.com/blah_(wikipedia)#cite-1 with anchor', + 'http://foo.com/blah_(wikipedia)#cite-1', + ], + [ + 'Eleventh link http://foo.com/blah_(wikipedia)_blah#cite-1 with anchor', + 'http://foo.com/blah_(wikipedia)_blah#cite-1', + ], + [ + 'Twelveth link http://foo.com/unicode_(✪)_in_parens unicode', + 'http://foo.com/unicode_(✪)_in_parens', + ], + [ + 'Thirteenth link http://foo.com/(something)?after=parens query params', + 'http://foo.com/(something)?after=parens', + ], +] @Component({ - template: `
Click this link https://www.example.com/
`, + template: `
{{ text }}
`, }) -class TestComponent {} +class TestComponent { + text = '' +} describe('GnUiLinkifyDirective', () => { let fixture: ComponentFixture @@ -20,26 +71,32 @@ describe('GnUiLinkifyDirective', () => { fixture = TestBed.createComponent(TestComponent) component = fixture.componentInstance - debugElement = fixture.debugElement.query( - By.directive(GnUiLinkifyDirective) - ) - - fixture.detectChanges() })) - it('should create an anchor element with the correct href', () => { - fixture.detectChanges() - const anchorElement = debugElement.query(By.css('a')) - - const href = anchorElement.nativeElement.getAttribute('href') - expect(href).toBe('https://www.example.com/') + describe('should create an anchor element with the correct href', () => { + test.each(testingUrls)( + 'for %p it should create href %p', + async (input, output) => { + component.text = input + fixture.detectChanges() + await fixture.whenStable() + const href = getAnchorElement().nativeElement.getAttribute('href') + expect(href).toBe(output) + } + ) }) - it('should have the target attribute set to "_blank"', () => { + it('should have the target attribute set to "_blank"', async () => { + component.text = 'Click this link https://www.example.com/' fixture.detectChanges() - const anchorElement = debugElement.query(By.css('a')) - - const target = anchorElement.nativeElement.getAttribute('target') + await fixture.whenStable() + const target = getAnchorElement().nativeElement.getAttribute('target') expect(target).toBe('_blank') }) + function getAnchorElement() { + debugElement = fixture.debugElement.query( + By.directive(GnUiLinkifyDirective) + ) + return debugElement.query(By.css('a')) + } }) diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts index c807d0947d..6f226ce041 100644 --- a/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts +++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts @@ -30,7 +30,7 @@ export class GnUiLinkifyDirective implements OnInit { } private linkifyText(text: string): string { - return text.replace(/(\bhttps?:\/\/\S+\b\/?)/g, (match) => { + return text.replace(/(\bhttps?:\/\/\S+\b[=)/]?)/g, (match) => { return `${match} open_in_new` })