mirror of
https://github.com/thelounge/thelounge.git
synced 2024-05-17 13:46:36 +02:00
Merge branch 'linkifyOverride'
This commit is contained in:
commit
fb5864ee00
|
@ -1,36 +1,12 @@
|
||||||
import LinkifyIt, {Match} from "linkify-it";
|
import LinkifyIt, {Match} from "linkify-it";
|
||||||
import tlds from "tlds";
|
import tlds from "tlds";
|
||||||
|
|
||||||
export type NoSchemaMatch = Match & {
|
|
||||||
noschema: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LinkPart = {
|
export type LinkPart = {
|
||||||
start: number;
|
start: number;
|
||||||
end: number;
|
end: number;
|
||||||
link: string;
|
link: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkifyIt.prototype.normalize = function normalize(match: NoSchemaMatch) {
|
|
||||||
match.noschema = false;
|
|
||||||
|
|
||||||
if (!match.schema) {
|
|
||||||
match.schema = "http:";
|
|
||||||
match.url = "http://" + match.url;
|
|
||||||
match.noschema = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match.schema === "//") {
|
|
||||||
match.schema = "http:";
|
|
||||||
match.url = "http:" + match.url;
|
|
||||||
match.noschema = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match.schema === "mailto:" && !/^mailto:/i.test(match.url)) {
|
|
||||||
match.url = "mailto:" + match.url;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const linkify = LinkifyIt().tlds(tlds).tlds("onion", true);
|
const linkify = LinkifyIt().tlds(tlds).tlds("onion", true);
|
||||||
|
|
||||||
// Known schemes to detect in text
|
// Known schemes to detect in text
|
||||||
|
@ -73,12 +49,25 @@ linkify.add("web+", {
|
||||||
},
|
},
|
||||||
normalize(match) {
|
normalize(match) {
|
||||||
match.schema = match.text.slice(0, match.text.indexOf(":") + 1);
|
match.schema = match.text.slice(0, match.text.indexOf(":") + 1);
|
||||||
LinkifyIt.prototype.normalize(match); // hand over to the global override
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// we must rewrite protocol less urls to http, else if TL is hosted
|
||||||
|
// on https, this would incorrectly use https for the remote link.
|
||||||
|
// See https://github.com/thelounge/thelounge/issues/2525
|
||||||
|
//
|
||||||
|
// We take the validation logic from linkify and just add our own
|
||||||
|
// normalizer.
|
||||||
|
linkify.add("//", {
|
||||||
|
validate: (linkify as any).__schemas__["//"].validate,
|
||||||
|
normalize(match) {
|
||||||
|
match.schema = ""; // this counts as not having a schema
|
||||||
|
match.url = "http:" + match.url;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function findLinks(text: string) {
|
export function findLinks(text: string) {
|
||||||
const matches = linkify.match(text) as NoSchemaMatch[];
|
const matches = linkify.match(text);
|
||||||
|
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -88,16 +77,16 @@ export function findLinks(text: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findLinksWithSchema(text: string) {
|
export function findLinksWithSchema(text: string) {
|
||||||
const matches = linkify.match(text) as NoSchemaMatch[];
|
const matches = linkify.match(text);
|
||||||
|
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return matches.filter((url) => !url.noschema).map(makeLinkPart);
|
return matches.filter((url) => !!url.schema).map(makeLinkPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeLinkPart(url: NoSchemaMatch): LinkPart {
|
function makeLinkPart(url: Match): LinkPart {
|
||||||
return {
|
return {
|
||||||
start: url.index,
|
start: url.index,
|
||||||
end: url.lastIndex,
|
end: url.lastIndex,
|
||||||
|
|
|
@ -353,6 +353,26 @@ describe("findLinks", () => {
|
||||||
expect(actual).to.deep.equal(expected);
|
expect(actual).to.deep.equal(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should parse mailto links", () => {
|
||||||
|
const input = "mail@example.com mailto:mail@example.org";
|
||||||
|
const expected = [
|
||||||
|
{
|
||||||
|
link: "mailto:mail@example.com",
|
||||||
|
start: 0,
|
||||||
|
end: 16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
link: "mailto:mail@example.org",
|
||||||
|
start: 17,
|
||||||
|
end: 40,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const actual = findLinks(input);
|
||||||
|
|
||||||
|
expect(actual).to.deep.equal(expected);
|
||||||
|
});
|
||||||
|
|
||||||
it("should not return urls with no schema if flag is specified", () => {
|
it("should not return urls with no schema if flag is specified", () => {
|
||||||
const input = "https://example.global //example.com http://example.group example.py";
|
const input = "https://example.global //example.com http://example.group example.py";
|
||||||
const expected = [
|
const expected = [
|
||||||
|
@ -373,6 +393,21 @@ describe("findLinks", () => {
|
||||||
expect(actual).to.deep.equal(expected);
|
expect(actual).to.deep.equal(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should use http for protocol-less URLs", () => {
|
||||||
|
const input = "//example.com";
|
||||||
|
const expected = [
|
||||||
|
{
|
||||||
|
link: "http://example.com",
|
||||||
|
start: 0,
|
||||||
|
end: 13,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const actual = findLinks(input);
|
||||||
|
|
||||||
|
expect(actual).to.deep.equal(expected);
|
||||||
|
});
|
||||||
|
|
||||||
it("should find web+ schema urls", () => {
|
it("should find web+ schema urls", () => {
|
||||||
const input = "web+ap://instance.example/@Example web+whatever://example.com?some=value";
|
const input = "web+ap://instance.example/@Example web+whatever://example.com?some=value";
|
||||||
const expected = [
|
const expected = [
|
||||||
|
|
Loading…
Reference in a new issue