Skip to content

Commit 6a2f6df

Browse files
authored
Validate URLs before converting text to a link (#66)
1 parent 2cf7f94 commit 6a2f6df

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

src/paste-markdown-link.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function onPaste(event: ClipboardEvent) {
3333
event.stopPropagation()
3434
event.preventDefault()
3535

36-
insertText(field, linkify(selectedText, text))
36+
insertText(field, linkify(selectedText, text.trim()))
3737
}
3838

3939
function hasPlainText(transfer: DataTransfer): boolean {
@@ -55,7 +55,15 @@ function linkify(selectedText: string, text: string): string {
5555
return `[${selectedText}](${text})`
5656
}
5757

58-
const URL_REGEX = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\/?\s*?$/i
5958
function isURL(url: string): boolean {
60-
return URL_REGEX.test(url)
59+
try {
60+
//eslint-disable-next-line no-restricted-syntax
61+
const parsedURL = new URL(url)
62+
return removeTrailingSlash(parsedURL.href).trim() === removeTrailingSlash(url).trim()
63+
} catch {
64+
return false
65+
}
66+
}
67+
function removeTrailingSlash(url: string) {
68+
return url.endsWith('/') ? url.slice(0, url.length - 1) : url
6169
}

test/test.js

+51
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,57 @@ describe('paste-markdown', function () {
5151
assert.equal(textarea.value, 'The examples can be found [here](https://www.github.com/).')
5252
})
5353

54+
it('creates a markdown link for longer urls', function () {
55+
// eslint-disable-next-line i18n-text/no-en
56+
textarea.value = 'The examples can be found here.'
57+
textarea.setSelectionRange(26, 30)
58+
paste(textarea, {'text/plain': 'https://www.github.com/path_to/something-different/too'})
59+
assert.equal(
60+
textarea.value,
61+
'The examples can be found [here](https://www.github.com/path_to/something-different/too).'
62+
)
63+
})
64+
65+
it('creates a markdown link with query string', function () {
66+
// eslint-disable-next-line i18n-text/no-en
67+
textarea.value = 'The examples can be found here.'
68+
textarea.setSelectionRange(26, 30)
69+
paste(textarea, {'text/plain': 'https://www.github.com/path/to/something?query=true'})
70+
assert.equal(
71+
textarea.value,
72+
'The examples can be found [here](https://www.github.com/path/to/something?query=true).'
73+
)
74+
})
75+
76+
it('creates a markdown link with hash params', function () {
77+
// eslint-disable-next-line i18n-text/no-en
78+
textarea.value = 'The examples can be found here.'
79+
textarea.setSelectionRange(26, 30)
80+
paste(textarea, {'text/plain': 'https://www.github.com/path/to/something#section'})
81+
assert.equal(
82+
textarea.value,
83+
'The examples can be found [here](https://www.github.com/path/to/something#section).'
84+
)
85+
})
86+
87+
it('creates a link for http urls', function () {
88+
// eslint-disable-next-line i18n-text/no-en
89+
textarea.value = 'Look over here please'
90+
textarea.setSelectionRange(10, 14)
91+
const url = 'http://someotherdomain.org/another/thing'
92+
paste(textarea, {'text/plain': url})
93+
assert.equal(textarea.value, `Look over [here](${url}) please`)
94+
})
95+
96+
it('creates a link when copied content includes spaces and a newline', () => {
97+
// eslint-disable-next-line i18n-text/no-en
98+
textarea.value = 'Look over here please'
99+
textarea.setSelectionRange(10, 14)
100+
const url = 'http://someotherdomain.org/another/thing \n'
101+
paste(textarea, {'text/plain': url})
102+
assert.equal(textarea.value, `Look over [here](${url.trim()}) please`)
103+
})
104+
54105
it("doesn't paste a markdown URL when pasting over a selected URL", function () {
55106
// eslint-disable-next-line i18n-text/no-en
56107
textarea.value = 'The examples can be found here: https://docs.github.com'

0 commit comments

Comments
 (0)