in lib/src/util.dart [171:228]
Uri? relativizeUri(Uri? uri, Uri? baseUri) {
if (baseUri == null) return uri;
assert(baseUri.isAbsolute);
if (uri!.hasQuery || uri.hasFragment) {
uri = Uri(
scheme: uri.scheme,
userInfo: uri.hasAuthority ? uri.userInfo : null,
host: uri.hasAuthority ? uri.host : null,
port: uri.hasAuthority ? uri.port : null,
path: uri.path);
}
// Already relative. We assume the caller knows what they are doing.
if (!uri.isAbsolute) return uri;
if (baseUri.scheme != uri.scheme) {
return uri;
}
// If authority differs, we could remove the scheme, but it's not worth it.
if (uri.hasAuthority != baseUri.hasAuthority) return uri;
if (uri.hasAuthority) {
if (uri.userInfo != baseUri.userInfo ||
uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
uri.port != baseUri.port) {
return uri;
}
}
baseUri = baseUri.normalizePath();
var base = [...baseUri.pathSegments];
if (base.isNotEmpty) base.removeLast();
uri = uri.normalizePath();
var target = [...uri.pathSegments];
if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
var index = 0;
while (index < base.length && index < target.length) {
if (base[index] != target[index]) {
break;
}
index++;
}
if (index == base.length) {
if (index == target.length) {
return Uri(path: './');
}
return Uri(path: target.skip(index).join('/'));
} else if (index > 0) {
var buffer = StringBuffer();
for (var n = base.length - index; n > 0; --n) {
buffer.write('../');
}
buffer.writeAll(target.skip(index), '/');
return Uri(path: buffer.toString());
} else {
return uri;
}
}