-
Notifications
You must be signed in to change notification settings - Fork 50
/
url.dart
114 lines (92 loc) · 3.02 KB
/
url.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import 'package:linkify/linkify.dart';
final _urlRegex = RegExp(
r'^(.*?)((?:https?:\/\/|www\.)[^\s/$.?#].[^\s]*)',
caseSensitive: false,
dotAll: true,
);
final _looseUrlRegex = RegExp(
r'''^(.*?)((https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//="'`]*))''',
caseSensitive: false,
dotAll: true,
);
final _protocolIdentifierRegex = RegExp(
r'^(https?:\/\/)',
caseSensitive: false,
);
class UrlLinkifier extends Linkifier {
const UrlLinkifier();
@override
List<LinkifyElement> parse(elements, options) {
final list = <LinkifyElement>[];
for (var element in elements) {
if (element is TextElement) {
var match = options.looseUrl
? _looseUrlRegex.firstMatch(element.text)
: _urlRegex.firstMatch(element.text);
if (match == null) {
list.add(element);
} else {
final text = element.text.replaceFirst(match.group(0)!, '');
if (match.group(1)?.isNotEmpty == true) {
list.add(TextElement(match.group(1)!));
}
if (match.group(2)?.isNotEmpty == true) {
var originalUrl = match.group(2)!;
var originText = originalUrl;
String? end;
if ((options.excludeLastPeriod) &&
originalUrl[originalUrl.length - 1] == ".") {
end = ".";
originText = originText.substring(0, originText.length - 1);
originalUrl = originalUrl.substring(0, originalUrl.length - 1);
}
var url = originalUrl;
if (!originalUrl.startsWith(_protocolIdentifierRegex)) {
originalUrl = (options.defaultToHttps ? "https://" : "http://") +
originalUrl;
}
if ((options.humanize) || (options.removeWww)) {
if (options.humanize) {
url = url.replaceFirst(RegExp(r'https?://'), '');
}
if (options.removeWww) {
url = url.replaceFirst(RegExp(r'www\.'), '');
}
list.add(UrlElement(
originalUrl,
url,
originText,
));
} else {
list.add(UrlElement(originalUrl, null, originText));
}
if (end != null) {
list.add(TextElement(end));
}
}
if (text.isNotEmpty) {
list.addAll(parse([TextElement(text)], options));
}
}
} else {
list.add(element);
}
}
return list;
}
}
/// Represents an element containing a link
class UrlElement extends LinkableElement {
UrlElement(String url, [String? text, String? originText])
: super(text, url, originText);
@override
String toString() {
return "LinkElement: '$url' ($text)";
}
@override
bool operator ==(other) => equals(other);
@override
int get hashCode => Object.hash(text, originText, url);
@override
bool equals(other) => other is UrlElement && super.equals(other);
}