Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export functions based on return type #43

Merged
merged 2 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 27 additions & 27 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,16 @@ export interface Options {
*/
readonly attributes?: HTMLAttributes;

/**
The format of the generated content.

`'string'` will return it as a flat string like `'Visit <a href="https://example.com">https://example.com</a>'`.

`'dom'` will return it as a `DocumentFragment` ready to be appended in a DOM safely, like `DocumentFragment(TextNode('Visit '), HTMLAnchorElement('https://example.com'))`. This type only works in the browser.
*/
readonly type?: 'string' | 'dom';

/**
Set a custom HTML value for the link.

Default: The URL.

@example
```
import linkifyUrls from 'linkify-urls';
import {linkifyUrlsToHtml} from 'linkify-urls';

linkifyUrls('See https://sindresorhus.com/foo', {
linkifyUrlsToHtml('See https://sindresorhus.com/foo', {
value: url => new URL(url).pathname
});
//=> 'See <a href="https://sindresorhus.com/foo">/foo</a>'
Expand All @@ -34,20 +25,18 @@ export interface Options {

}

export interface TypeDomOptions extends Options {
readonly type: 'dom';
}

/**
Linkify URLs in a string.
Linkify URLs in a string, returns an HTML string.

@param string - A string with URLs to linkify.

@returns An HTML string like `'Visit <a href="https://example.com">https://example.com</a>'`.

@example
```
import linkifyUrls from 'linkify-urls';
import {linkifyUrlsToHtml} from 'linkify-urls';

linkifyUrls('See https://sindresorhus.com', {
linkifyUrlsToHtml('See https://sindresorhus.com', {
attributes: {
class: 'unicorn',
one: 1,
Expand All @@ -56,24 +45,35 @@ linkifyUrls('See https://sindresorhus.com', {
}
});
//=> 'See <a href="https://sindresorhus.com" class="unicorn" one="1" foo multiple="a b">https://sindresorhus.com</a>'
```
*/
export function linkifyUrlsToHtml(
string: string,
options?: Options
): string;

// In the browser
const fragment = linkifyUrls('See https://sindresorhus.com', {
type: 'dom',
/**
Linkify URLs in a string, returns a `DocumentFragment`.

@param string - A string with URLs to linkify.

@returns a `DocumentFragment` ready to be appended in a DOM safely, like `DocumentFragment(TextNode('Visit '), HTMLAnchorElement('https://example.com'))`. This type only works in the browser.

@example
```
import {linkifyUrlsToDom} from 'linkify-urls';

const fragment = linkifyUrlsToDom('See https://sindresorhus.com', {
attributes: {
class: 'unicorn',
}
});
document.body.appendChild(fragment);
```
*/
export default function linkifyUrls(
string: string,
options: TypeDomOptions
): DocumentFragment;
export default function linkifyUrls(
export function linkifyUrlsToDom(
string: string,
options?: Options
): string;
): DocumentFragment;

export {HTMLAttributes} from 'create-html-element';
34 changes: 10 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import createHtmlElement from 'create-html-element';
const urlRegex = () => (/((?<!\+)https?:\/\/(?:www\.)?(?:[-\w.]+?[.@][a-zA-Z\d]{2,}|localhost)(?:[-\w.:%+~#*$!?&/=@]*?(?:,(?!\s))*?)*)/g);

// Get `<a>` element as string
const linkify = (href, options) => createHtmlElement({
const linkify = (href, options = {}) => createHtmlElement({
name: 'a',
attributes: {
href: '',
Expand All @@ -23,12 +23,16 @@ const isTruncated = (url, peek) =>
url.endsWith('...') // `...` is a matched by the URL regex
|| peek.startsWith('…'); // `…` can follow the match

const getAsString = (string, options) => string.replace(urlRegex(), (url, _, offset) =>
(isTruncated(url, string.charAt(offset + url.length)))
? url // Don't linkify truncated URLs
: linkify(url, options));
export function linkifyUrlsToHtml(string, options) {
const replacer = (url, _, offset) =>
isTruncated(url, string.charAt(offset + url.length))
? url // Don't linkify truncated URLs
: linkify(url, options);

const getAsDocumentFragment = (string, options) => {
return string.replace(urlRegex(), replacer);
}

export function linkifyUrlsToDom(string, options) {
const fragment = document.createDocumentFragment();
const parts = string.split(urlRegex());

Expand All @@ -42,22 +46,4 @@ const getAsDocumentFragment = (string, options) => {
}

return fragment;
};

export default function linkifyUrls(string, options) {
options = {
attributes: {},
type: 'string',
...options,
};

if (options.type === 'string') {
return getAsString(string, options);
}

if (options.type === 'dom') {
return getAsDocumentFragment(string, options);
}

throw new TypeError('The type option must be either `dom` or `string`');
}
15 changes: 6 additions & 9 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {expectType} from 'tsd';
import linkifyUrls from './index.js';
import {linkifyUrlsToHtml, linkifyUrlsToDom} from './index.js';

expectType<string>(
linkifyUrls('See https://sindresorhus.com', {
linkifyUrlsToHtml('See https://sindresorhus.com', {
attributes: {
class: 'unicorn',
one: 1,
Expand All @@ -12,26 +12,23 @@ expectType<string>(
}),
);
expectType<string>(
linkifyUrls('See https://sindresorhus.com', {
linkifyUrlsToHtml('See https://sindresorhus.com', {
value: 'foo',
}),
);
expectType<string>(
linkifyUrls('See https://sindresorhus.com/foo', {
linkifyUrlsToHtml('See https://sindresorhus.com/foo', {
value: url => {
expectType<string>(url);
return url;
},
}),
);
expectType<string>(
linkifyUrls('See https://sindresorhus.com/foo', {
type: 'string',
}),
linkifyUrlsToHtml('See https://sindresorhus.com/foo'),
);

const fragment = linkifyUrls('See https://sindresorhus.com', {
type: 'dom',
const fragment = linkifyUrlsToDom('See https://sindresorhus.com', {
attributes: {
class: 'unicorn',
},
Expand Down
35 changes: 17 additions & 18 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ npm install linkify-urls
## Usage

```js
import linkifyUrls from 'linkify-urls';
import {linkifyUrlsToHtml, linkifyUrlsToDom} from 'linkify-urls';

linkifyUrls('See https://sindresorhus.com', {
linkifyUrlsToHtml('See https://sindresorhus.com', {
attributes: {
class: 'unicorn',
one: 1,
Expand All @@ -28,8 +28,7 @@ linkifyUrls('See https://sindresorhus.com', {


// In the browser
const fragment = linkifyUrls('See https://sindresorhus.com', {
type: 'dom',
const fragment = linkifyUrlsToDom('See https://sindresorhus.com', {
attributes: {
class: 'unicorn',
}
Expand All @@ -39,7 +38,9 @@ document.body.appendChild(fragment);

## API

### linkifyUrls(string, options?)
### linkifyUrlsToHtml(string, options?)

Returns an HTML string like `'Visit <a href="https://example.com">https://example.com</a>'`.

#### string

Expand All @@ -57,18 +58,6 @@ Type: `object`

HTML attributes to add to the link.

##### type

Type: `string`\
Values: `'string' | 'dom'`\
Default: `'string'`

The format of the generated content.

`'string'` will return it as a flat string like `'Visit <a href="https://example.com">https://example.com</a>'`.

`'dom'` will return it as a `DocumentFragment` ready to be appended in a DOM safely, like `DocumentFragment(TextNode('Visit '), HTMLAnchorElement('https://example.com'))`. This type only works in the browser.

##### value

Type: `string | Function`\
Expand All @@ -79,12 +68,22 @@ Set a custom HTML value for the link.
If it's a function, it will receive the URL as a string:

```js
linkifyUrls('See https://sindresorhus.com/foo', {
linkifyUrlsToHtml('See https://sindresorhus.com/foo', {
value: url => new URL(url).pathname
});
//=> 'See <a href="https://sindresorhus.com/foo">/foo</a>'
```

### linkifyUrlsToDom(string, options?)

Returns a `DocumentFragment` ready to be appended in a DOM safely, like `DocumentFragment(TextNode('Visit '), HTMLAnchorElement('https://example.com'))`.

This type only works in the browser.

#### options

See [options](#options) above.

## Browser compatibility

Version 3 of this package uses [negative lookbehind regex syntax](https://kangax.github.io/compat-table/es2016plus/#test-RegExp_Lookbehind_Assertions). Stay on version 2 if you need to support browsers that doesn't support this feature.
Expand Down
Loading
Loading