fix: Support URLs with hyphenated domain names - Updated URL regex pattern to include hyphens in domain names - Added test cases for hyphenated domains - Updated example app with hyphenated domain examples - Fixes #22

This commit is contained in:
loqmanali 2025-04-12 10:47:20 +07:00 committed by JohnE
parent ea9faf279b
commit 43cb1b79cd
3 changed files with 25 additions and 14 deletions

View File

@ -3,24 +3,28 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:linkfy_text/linkfy_text.dart';
void main() {
runApp(MyApp());
runApp(const MyApp());
}
final k = GlobalKey<ScaffoldMessengerState>();
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'linkfy_text Demo',
scaffoldMessengerKey: k,
debugShowCheckedModeBanner: false,
home: App(),
home: const App(),
);
}
}
class App extends StatefulWidget {
const App({super.key});
@override
_AppState createState() => _AppState();
}
@ -31,7 +35,8 @@ class _AppState extends State<App> {
final List<Map<String, dynamic>> texts = [
{
"text": "O1. This text contains a url: https://flutter.dev",
"text":
"O1. Testing hyphenated domains: https://my-website.com and http://sub-domain.example-site.com",
"types": null
},
{
@ -52,7 +57,7 @@ class _AppState extends State<App> {
},
{
"text":
"O6. My website url: https://hello.com/GOOGLE search using: www.google.com, social media is facebook.com, additional link https://example.com/method?param=fullstackoverflow.dev, hashtag #trending & mention @dev.user +18009999999",
"O6. Testing complex URLs: https://my-complex-domain.com/path?param=value and https://sub-domain.my-site.com/test",
"types": [
LinkType.phone,
LinkType.email,
@ -66,7 +71,7 @@ class _AppState extends State<App> {
void showSnackbar(String msg) {
k.currentState!.removeCurrentSnackBar();
k.currentState!.showSnackBar(SnackBar(
content: Text("$msg", style: textStyle),
content: Text(msg, style: textStyle),
behavior: SnackBarBehavior.floating,
));
}
@ -90,13 +95,13 @@ class _AppState extends State<App> {
),
for (var i = 0; i < texts.length; i++)
Padding(
padding: EdgeInsets.only(top: 14),
padding: const EdgeInsets.only(top: 14),
child: LinkifyText(
texts[i]['text'],
textAlign: TextAlign.left,
linkTypes: texts[i]['types'],
textStyle: textStyle,
customLinkStyles: {
customLinkStyles: const {
LinkType.email: TextStyle(color: Colors.blue),
LinkType.hashTag: TextStyle(color: Colors.green),
LinkType.userTag: TextStyle(color: Colors.deepPurple),

View File

@ -4,11 +4,13 @@ import 'package:linkfy_text/src/enum.dart';
// url regex that accept https, http, www
String urlRegExp =
r'[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)';
r'((https?://)?(www\.)?[a-zA-Z0-9@:%._\+~#=-]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))';
String hashtagRegExp = r'#[a-zA-Z\u00C0-\u01B4\w_\u1EA0-\u1EF9!$%^&]{1,}(?=\s|$)';
String hashtagRegExp =
r'#[a-zA-Z\u00C0-\u01B4\w_\u1EA0-\u1EF9!$%^&]{1,}(?=\s|$)';
String userTagRegExp = r'@[a-zA-Z\u00C0-\u01B4\w_\u1EA0-\u1EF9!$%^&]{1,}(?=\s|$)';
String userTagRegExp =
r'@[a-zA-Z\u00C0-\u01B4\w_\u1EA0-\u1EF9!$%^&]{1,}(?=\s|$)';
String phoneRegExp =
r'\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*';
String emailRegExp =
@ -49,7 +51,6 @@ RegExp constructRegExpFromLinkType(List<LinkType> types) {
? buffer.write("($phoneRegExp)")
: buffer.write("($phoneRegExp)|");
break;
default:
}
}
return RegExp(buffer.toString());

View File

@ -29,6 +29,10 @@ void main() {
"https://domain.com/Google?param=",
"https://domain.com/Google?param=helloworld",
"https://sub.domain.com/Google?param=helloworld#hash",
"https://my-domain.com",
"http://my-awesome-website.com",
"www.my-site-with-hyphens.com",
"https://sub-domain.example.com"
];
const hashtags = [
@ -67,7 +71,8 @@ void main() {
test("Should match all urls", () {
for (final url in urls) {
expect(RegExp(urlRegExp).hasMatch(url), isTrue);
expect(RegExp(urlRegExp).hasMatch(url), isTrue,
reason: "Failed to match URL: $url");
expect(getMatchedType(url), equals(LinkType.url));
}
});