cwtch-ui/lib/third_party/linkify/linkify.dart

145 lines
4.1 KiB
Dart

// Originally from linkify https://github.com/Cretezy/linkify/blob/ba536fa85e7e3a16e580f153616f399458986183/lib/linkify.dart
// Removed options `removeWWW` and `humanize`
//
// MIT License
//
// Copyright (c) 2019 Charles-William Crete
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import 'uri.dart';
export 'uri.dart' show UrlLinkifier, UrlElement;
abstract class LinkifyElement {
final String text;
LinkifyElement(this.text);
@override
bool operator ==(other) => equals(other);
bool equals(other) => other is LinkifyElement && other.text == text;
}
class BoldElement extends LinkifyElement {
BoldElement(String text) : super(text);
}
class ItalicElement extends LinkifyElement {
ItalicElement(String text) : super(text);
}
class SuperElement extends LinkifyElement {
SuperElement(String text) : super(text);
}
class SubElement extends LinkifyElement {
SubElement(String text) : super(text);
}
class StrikeElement extends LinkifyElement {
StrikeElement(String text) : super(text);
}
class CodeElement extends LinkifyElement {
CodeElement(String text) : super(text);
}
class LinkableElement extends LinkifyElement {
final String url;
LinkableElement(String? text, this.url) : super(text ?? url);
@override
bool operator ==(other) => equals(other);
@override
bool equals(other) => other is LinkableElement && super.equals(other) && other.url == url;
}
/// Represents an element containing text
class TextElement extends LinkifyElement {
TextElement(String text) : super(text);
@override
String toString() {
return "TextElement: '$text'";
}
@override
bool operator ==(other) => equals(other);
@override
bool equals(other) => other is TextElement && super.equals(other);
}
abstract class Linkifier {
const Linkifier();
List<LinkifyElement> parse(List<LinkifyElement> elements, LinkifyOptions options);
}
class LinkifyOptions {
/// Enables loose URL parsing (any string with "." is a URL).
final bool looseUrl;
/// When used with [looseUrl], default to `https` instead of `http`.
final bool defaultToHttps;
/// Excludes `.` at end of URLs.
final bool excludeLastPeriod;
final bool messageFormatting;
final bool parseLinks;
const LinkifyOptions({this.looseUrl = false, this.defaultToHttps = false, this.excludeLastPeriod = true, this.messageFormatting = false, this.parseLinks = false});
}
const _urlLinkifier = UrlLinkifier();
const defaultLinkifiers = [_urlLinkifier];
/// Turns [text] into a list of [LinkifyElement]
///
/// Use [humanize] to remove http/https from the start of the URL shown.
/// Will default to `false` (if `null`)
///
/// Uses [linkTypes] to enable some types of links (URL, email).
/// Will default to all (if `null`).
List<LinkifyElement> linkify(
String text, {
LinkifyOptions options = const LinkifyOptions(),
List<Linkifier> linkifiers = defaultLinkifiers,
}) {
var list = <LinkifyElement>[TextElement(text)];
if (text.isEmpty) {
return [];
}
if (linkifiers.isEmpty) {
return list;
}
linkifiers.forEach((linkifier) {
list = linkifier.parse(list, options);
});
return list;
}