improved Uri display formatting
This commit is contained in:
@@ -47,18 +47,11 @@ extension UriX on Uri {
|
||||
return '';
|
||||
}
|
||||
|
||||
final segments = pathSegments.join('/');
|
||||
final buffer = StringBuffer();
|
||||
|
||||
if (path.startsWith('/')) {
|
||||
buffer.write('/');
|
||||
try {
|
||||
return Uri.decodeComponent(path);
|
||||
} on FormatException {
|
||||
return path;
|
||||
}
|
||||
buffer.write(segments);
|
||||
if (path.length > 1 && path.endsWith('/')) {
|
||||
buffer.write('/');
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
String get displayString {
|
||||
@@ -94,6 +87,10 @@ extension UriStringX on String {
|
||||
if (uri == null || uri.toString() != this) {
|
||||
return this;
|
||||
}
|
||||
return uri.displayString;
|
||||
try {
|
||||
return uri.displayString;
|
||||
} on FormatException {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -21,6 +21,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:weblibre/extensions/uri.dart';
|
||||
import 'package:weblibre/features/geckoview/features/contextmenu/domain/converters/hit_result_converter.dart';
|
||||
|
||||
extension HitResultJson on HitResult {
|
||||
@@ -82,14 +83,15 @@ extension HitResultX on HitResult {
|
||||
const maxTitleLength = 2500;
|
||||
|
||||
return switch (this) {
|
||||
UnknownHitResult(src: final src) => src,
|
||||
ImageSrcHitResult(uri: final uri) => uri,
|
||||
ImageHitResult(src: final src, title: final title) =>
|
||||
title.isEmpty ? (src.length > maxTitleLength ? 'image' : src) : title!,
|
||||
UnknownHitResult(src: final src) => src.uriDisplayString,
|
||||
ImageSrcHitResult(uri: final uri) => uri.uriDisplayString,
|
||||
ImageHitResult(src: final src, title: final title) => title.isEmpty
|
||||
? (src.length > maxTitleLength ? 'image' : src.uriDisplayString)
|
||||
: title!,
|
||||
VideoHitResult(src: final src, title: final title) =>
|
||||
(title.isEmpty) ? src : title!,
|
||||
(title.isEmpty) ? src.uriDisplayString : title!,
|
||||
AudioHitResult(src: final src, title: final title) =>
|
||||
(title.isEmpty) ? src : title!,
|
||||
(title.isEmpty) ? src.uriDisplayString : title!,
|
||||
_ => 'about:blank',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -65,5 +65,34 @@ void main() {
|
||||
'https://example.com/%ZZ?query=%',
|
||||
);
|
||||
});
|
||||
|
||||
test('preserves trailing slash exactly once', () {
|
||||
final uri = Uri.parse('http://x.com/a/b/');
|
||||
|
||||
expect(uri.displayString, 'http://x.com/a/b/');
|
||||
});
|
||||
|
||||
test('decodes Cyrillic Reddit URL with trailing slash', () {
|
||||
final uri = Uri.parse(
|
||||
'https://www.reddit.com/r/KafkaFPS/comments/1sn0j5w/'
|
||||
'%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D1%82%D0%B0%D0%BD%D1%8C%D1%82%D0%B5'
|
||||
'_%D1%81%D0%BE%D0%BF%D1%80%D0%BE%D1%82%D0%B8%D0%B2%D0%BB%D1%8F'
|
||||
'%D1%82%D1%8C%D1%81%D1%8F_%D0%BC%D0%B8%D1%81%D1%82%D0%B5%D1%80'
|
||||
'_%D0%B0%D0%BD%D0%B4%D0%B5%D1%80%D1%81%D0%BE%D0%BD/',
|
||||
);
|
||||
|
||||
expect(
|
||||
uri.displayString,
|
||||
'https://www.reddit.com/r/KafkaFPS/comments/1sn0j5w/'
|
||||
'перестаньте_сопротивляться_мистер_андерсон/',
|
||||
);
|
||||
});
|
||||
|
||||
test('keeps IDN punycode host as-is', () {
|
||||
expect(
|
||||
'https://xn--j1ail.xn--p1ai/'.uriDisplayString,
|
||||
'https://xn--j1ail.xn--p1ai/',
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user