Skip to content

Commit

Permalink
[linkifyjs] re-write definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Oct 5, 2019
1 parent be146d8 commit f4627ee
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 389 deletions.
26 changes: 23 additions & 3 deletions types/linkifyjs/element.d.ts
@@ -1,4 +1,24 @@
import { LinkifyOptions } from "./index";
import { Options as CommonOptions, LinkEntityType } from './index';

export function linkifyElement(element: HTMLElement, options?: LinkifyOptions, doc?: HTMLDocument): HTMLElement;
export default linkifyElement;
export interface Options extends CommonOptions {
/**
* Add event listeners to newly created link elements.
* Takes a hash where each key is an standard event name and the value is an event handler.
*
* Also accepts a function that takes the unformatted href and the link type (e.g., 'url', 'email', etc.) and returns the hash.
*
* @default null
*/
events?: Partial<GlobalEventHandlers> | ((href: string, type: LinkEntityType) => Partial<GlobalEventHandlers>);

/**
* Prevent linkify from trying to parse links in the specified tags.
*
* This is useful when running linkify on arbitrary HTML.
*
* @default []
*/
ignoreTags?: string[];
}

export default function linkifyElement(element: HTMLElement, options?: Options, doc?: HTMLDocument): HTMLElement;
26 changes: 23 additions & 3 deletions types/linkifyjs/html.d.ts
@@ -1,4 +1,24 @@
import { LinkifyOptions } from "./index";
import { Options as CommonOptions, LinkEntityType } from './index';

export function linkifyHtml(input: string, options?: LinkifyOptions): string;
export default linkifyHtml;
export interface Options extends CommonOptions {
/**
* Add event listeners to newly created link elements.
* Takes a hash where each key is an standard event name and the value is an event handler.
*
* Also accepts a function that takes the unformatted href and the link type (e.g., 'url', 'email', etc.) and returns the hash.
*
* @default null
*/
events?: Partial<GlobalEventHandlers> | ((href: string, type: LinkEntityType) => Partial<GlobalEventHandlers>);

/**
* Prevent linkify from trying to parse links in the specified tags.
*
* This is useful when running linkify on arbitrary HTML.
*
* @default []
*/
ignoreTags?: string[];
}

export default function linkifyHtml(input: string, options?: Options): string;
204 changes: 92 additions & 112 deletions types/linkifyjs/index.d.ts
@@ -1,43 +1,76 @@
// Type definitions for linkifyjs 2.1
// Project: https://github.com/SoapBox/linkifyjs#readme
// Definitions by: Sean Zhu <https://github.com/szhu>
// Definitions by: Gareth Jones <https://github.com/g-rath>
// Sean Zhu <https://github.com/szhu>
// Ovidiu Bute <https://github.com/ovidiubute>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8

import * as React from "react";
export type LinkEntityType =
| 'url'
| 'email'
| 'hashtag'
| 'mention'
;

export type PossiblyFuncOfHrefAndType<T> =
| T
| ((href: string, type: string) => T);
export interface FindResultHash {
/**
* The type of entity found.
*/
type: LinkEntityType;
/**
* The original entity substring.
*/
value: string;
/**
* Should be the value of this links `href` attribute.
*/
href: string;
}

// There's always a possibility that values at a string key can always be
// undefined; i.e., if the key does not exist.
export type PossiblyByType<T> = T | { [type: string]: T | undefined };
/**
* Finds all links in the given string.
*
* Returns a list of links where each element is a hash.
*
* @param str Search string.
* @param [type] only find links of the given type.
*/
export function find(str: string, type?: LinkEntityType): FindResultHash[];

export type EventHandler = (e: HTMLElement) => void;
/**
* Is the given string a link? Not to be used for strict validation.
*
* @param str the `string` to test.
* @param type returns `true` only if the link is of the given type.
*
* @see https://soapbox.github.io/linkifyjs/docs/caveats.html
*/
export function test(str: string, type?: LinkEntityType): boolean;

export interface LinkifyOptions {
/**
* Internal method used to perform lexicographical analysis on the given string,
* and output the resulting token array.
*
* @param str
*
* @return
*/
export function tokenize(str: string): Array<{ v: Array<{ v: string }> }>;

export interface Options {
/**
* attributes
* - Type: Object | Function (String href, String type)
* - Default: null
*
* Object of attributes to add to each new link. Note: the class and target
* attributes have dedicated options.
*
* Also accepts a function that takes the unformatted href, the link type
* (e.g., 'url', 'email', etc.) and returns the object.
*
* @default null
*/
attributes?: PossiblyFuncOfHrefAndType<
React.AnchorHTMLAttributes<HTMLAnchorElement>
> | null;
attributes?: Record<string, string> | ((href: string, type: LinkEntityType) => Record<string, string>) | null;

/**
* className
* - Type: String | Function (String href, String type) | Object
* - Default: 'linkified' (may be removed in future releases)
*
* class attribute to use for newly created links.
*
* Accepts a function that takes the unformatted href value and link type
Expand All @@ -46,129 +79,73 @@ export interface LinkifyOptions {
* Accepts an object where each key is the link type and each value is the
* string or function to use for that type.
*/
className?: PossiblyByType<PossiblyFuncOfHrefAndType<string | undefined>>;
className?: string | Partial<Record<LinkEntityType, string | ((href: string) => string)>> | ((href: string, type: LinkEntityType) => string);

/**
* defaultProtocol
* - Type: String
* - Default: 'http'
* - Values: 'http', 'https', 'ftp', 'ftps', etc.
*
* Protocol that should be used in href attributes for URLs without a
* protocol (e.g., github.com).
*/
defaultProtocol?: string;

/**
* events
* - *element, jquery interfaces only*
* - Type: Object | Function (String href, String type) | Object
* - Default: null
*
* Add event listeners to newly created link elements. Takes a hash where
* each key is an standard event name and the value is an event handler.
*
* Also accepts a function that takes the unformatted href and the link type
* (e.g., 'url', 'email', etc.) and returns the hash.
*
* For React, specify events in the attributes option as standard React
* events.
*
* See the React Event docs and the linkify-react event docs
* @default 'http'
*/
events?: PossiblyFuncOfHrefAndType<{
[eventName: string]: EventHandler;
}> | null;
defaultProtocol?: 'http' | 'https' | 'ftp' | 'ftps' | string;

/**
* format
* - Type: Function (String value, String type) | Object
* - Default: null
*
* Format the text displayed by a linkified entity. e.g., truncate a long
* URL.
* Format the text displayed by a linkified entity. e.g., truncate a long URL.
*
* Accepts an object where each key is the link type (e.g., 'url', 'email',
* etc.) and each value is the formatting function to use for that type.
* Accepts an object where each key is the link type (e.g., 'url', 'email', etc.),
* and each value is the formatting function to use for that type.
*
* NOTE: According to the linkifyjs implementation, `format` can be just a
* string, but this is not mentioned in the docs, so we exclude it.
* @default null
*/
format?: PossiblyByType<(value: string, type: string) => string>;
//
format?: ((value: string, type: LinkEntityType) => string) | Partial<Record<LinkEntityType, (value: string) => string>> | null;

/**
* formatHref
* - Type: Function (String href, String type) | Object
* - Default: null
*
* Similar to format, except the result of this function will be used as the
* href attribute of the new link.
*
* This is useful when finding hashtags, where you don’t necessarily want
* the default to be a link to a named anchor.
* This is useful when finding hashtags, where you don’t necessarily
* want the default to be a link to a named anchor.
*
* Accepts an object where each key is the link type (e.g., 'url', 'email',
* etc.) and each value is the formatting function to use for that type.
* Accepts an object where each key is the link type (e.g., 'url', 'email', etc.),
* and each value is the formatting function to use for that type.
*
* NOTE: According to the linkifyjs implementation, `formatHref` can be just
* a string, but this is not mentioned in the docs, so we exclude it.
* @default null
*/
formatHref?: PossiblyByType<(href: string, type: string) => string>;
formatHref?: ((href: string, type: LinkEntityType) => string) | Partial<Record<LinkEntityType, (href: string) => string>> | null;

/**
* ignoreTags
* - *element, html, and jquery interfaces only*
* - Type: Array
* - Default: []
*
* Prevent linkify from trying to parse links in the specified tags. This is
* useful when running linkify on arbitrary HTML.
*/
ignoreTags?: string[];

/**
* nl2br
* - Type: Boolean
* - Default: false
*
* If true, \n line breaks will automatically be converted to <br> tags.
* If `true`, \n line breaks will automatically be converted to `<br>` tags.
*
* @default false
*/
nl2br?: boolean;

/**
* tagName
* - Type: String | Function (String href, String type) | Object
* - Default: a
* The tag name to use for each link.
* For cases where you can’t use anchor tags.
*
* The tag name to use for each link. For cases where you can’t use anchor
* tags.
* Accepts a function that takes the unformatted href,
* the link type (e.g., 'url', 'email', etc.) and returns the tag name.
*
* Accepts a function that takes the unformatted href, the link type (e.g.,
* 'url', 'email', etc.) and returns the tag name.
* Accepts an object where each key is the link type,
* and each value is the tag name to use for that type.
*
* Accepts an object where each key is the link type and each value is the
* tag name to use for that type.
* @default a
*/
tagName?: PossiblyByType<PossiblyFuncOfHrefAndType<string>>;
tagName?: string | ((href: string, type: LinkEntityType) => string) | Partial<Record<LinkEntityType, string>>;

/**
* target
* - Type: String | Function (String href, String type) | Object
* - Default: '_blank' for URLs, null for everything else
*
* target attribute for generated link.
*
* Accepts a function that takes the unformatted href, the link type (e.g.,
* 'url', 'email', etc.) and returns the target
* Accepts a function that takes the unformatted href,
* the link type (e.g., 'url', 'email', etc.) and returns the target
*
* Accepts an object where each key is the link type and each value is the
* target to use for that type.
* Accepts an object where each key is the link type,
* and each value is the target to use for that type.
*
* @default { url: '_blank' }
*/
target?: PossiblyByType<
PossiblyFuncOfHrefAndType<string | null | undefined>
>;
target?: string | ((href: string, type: LinkEntityType) => string) | Partial<Record<LinkEntityType, string | null>>;

/**
* validate
Expand All @@ -177,12 +154,15 @@ export interface LinkifyOptions {
*
* If option resolves to false, the given value will not show up as a link.
*
* Accepts a function that takes a discovered link and the link type (e.g.,
* 'url', 'email', etc.) and returns true if the link should be converted
* into an anchor tag, and false otherwise.
* Accepts a function that takes a discovered link,
* and the link type (e.g., 'url', 'email', etc.),
* and returns true if the link should be converted into an anchor tag,
* and false otherwise.
*
* Accepts an object where each key is the link type and each value is the
* the validation option to use for that type
*
* @default null
*/
validate?: PossiblyByType<PossiblyFuncOfHrefAndType<boolean>>;
validate?: boolean | ((href: string, type: LinkEntityType) => boolean) | Partial<Record<LinkEntityType, ((href: string) => boolean)>> | null;
}
61 changes: 61 additions & 0 deletions types/linkifyjs/linkifyjs-tests.ts
@@ -0,0 +1,61 @@
import * as Linkify from 'linkifyjs';

Linkify.find(); // $ExpectError
Linkify.find(1); // $ExpectError
Linkify.find('my string', 1); // $ExpectError
Linkify.find('my string'); // $ExpectType FindResultHash[]
Linkify.find('my string', 'email'); // $ExpectType FindResultHash[]
Linkify.find('my string', 'hashtag'); // $ExpectType FindResultHash[]
Linkify.find('my string', 'my type'); // $ExpectError

Linkify.test(); // $ExpectError
Linkify.test(1); // $ExpectError
Linkify.test('my string', 1); // $ExpectError
Linkify.test('my string'); // $ExpectType boolean
Linkify.test('my string', 'email'); // $ExpectType boolean
Linkify.test('my string', 'hashtag'); // $ExpectType boolean
Linkify.test('my string', 'my type'); // $ExpectError

Linkify.tokenize(); // $ExpectError
Linkify.tokenize(1); // $ExpectError
Linkify.tokenize('my string'); // $ExpectType { v: { v: string; }[]; }[]

let options: Linkify.Options;

options = {}; // $ExpectType {}
options = { attributes: null }; // $ExpectType { attributes: null; }
options = { attributes: 'hello-world' }; // $ExpectError
options = { attributes: { attr: 'hello-world' } }; // $ExpectType { attributes: { attr: string; }; }
options = { attributes: href => ({}) }; // $ExpectType { attributes: (href: string) => {}; }

options = { className: null }; // $ExpectError
options = { className: 'new-link--url' }; // $ExpectType { className: string; }
options = { className: (href, type) => `new-link-${type}` }; // $ExpectType { className: (href: string, type: LinkEntityType) => string; }
options = { className: { sunshine: v => v } }; // $ExpectError
options = { className: { email: () => 'new-link--email' } }; // $ExpectType { className: { email: () => string; }; }

options = { defaultProtocol: null }; // $ExpectError
options = { defaultProtocol: 1 }; // $ExpectError
options = { defaultProtocol: 'http' }; // $ExpectType { defaultProtocol: string; }
options = { defaultProtocol: 'ftp' }; // $ExpectType { defaultProtocol: string; }

options = { format: null }; // $ExpectType { format: null; }
options = { format: value => value }; // $ExpectType { format: (value: string) => string; }
options = { format: { sunshine: v => v } }; // $ExpectError
options = { format: { email: () => 'sunshine' } }; // $ExpectType { format: { email: () => string; }; }

options = { formatHref: null }; // $ExpectType { formatHref: null; }
options = { formatHref: href => href }; // $ExpectType { formatHref: (href: string) => string; }
options = { formatHref: { sunshine: v => v } }; // $ExpectError
options = { formatHref: { email: () => 'sunshine' } }; // $ExpectType { formatHref: { email: () => string; }; }

options = { nl2br: 1 }; // $ExpectError
options = { nl2br: true }; // $ExpectType { nl2br: true; }

options = { tagName: null }; // $ExpectError
options = { tagName: 'span' }; // $ExpectType { tagName: string; }

options = { target: null }; // $ExpectError
options = { target: '_parent' }; // $ExpectType { target: string; }

options = { validate: null }; // $ExpectType { validate: null; }

0 comments on commit f4627ee

Please sign in to comment.