No way to detect root and document-relative urls
Hi!
Thanks for great library!
let uri = new URI("/example/");
uri.is("relative");
tells whether uri is relative or not. However, there is no way to distinguish those two urls:
let rootRelative = new URI("/example/");
let documentRelative = new URI("example/");
Both will be relative, while sometimes it is neccessary to determinate exactly which type of relative urls it is: root-relative or document-relative.
good point. Are you up for a PR to extend .is() by relative-path and absolute-path? (that would keep backward-compatibility by maintaining relative meaning relative-host)
I can try, for sure, though code looks a bit complicated for me. To be honest, I didn't get what all those relative-path, absolute-path and relative-host means :)
I guess we can simply add two additional checks:
uri.is("rootRelative");
uri.is("documentRelative");
and code will be like this?
...
+ URI.root_relative_expression = /^\//;
...
p.is = function(what) {
var ip = false;
var ip4 = false;
var ip6 = false;
var name = false;
var sld = false;
var idn = false;
var punycode = false;
var relative = !this._parts.urn;
if (this._parts.hostname) {
relative = false;
+ rootRelative = relative && URI.root_relative_expression.test(this._parts.path);
+ documentRelative = relative && !rootRelative;
ip4 = URI.ip4_expression.test(this._parts.hostname);
ip6 = URI.ip6_expression.test(this._parts.hostname);
ip = ip4 || ip6;
name = !ip;
sld = name && SLD && SLD.has(this._parts.hostname);
idn = name && URI.idn_expression.test(this._parts.hostname);
punycode = name && URI.punycode_expression.test(this._parts.hostname);
}
switch (what.toLowerCase()) {
case 'relative':
return relative;
case 'absolute':
return !relative;
+ case 'rootRelative':
+ return rootRelative;
+
+ case 'documentRelative':
+ return documentRelative;
...
To be honest, I didn't get what all those relative-path, absolute-path and relative-host means :)
well, how did you get to the terms rootRelative and documentRelative?
relative = false; + rootRelative = relative && URI.root_relative_expression.test(this._parts.path); + documentRelative = relative && !rootRelative;
that can't work since relative is always false. Maybe you'd like to do these tests if this._parts.hostname is not set instead? While your RegExp is not wrong, a simple string comparison would suffice (this._parts.path.slice(0, 1) !== '/'). You should also declare and initialize the variables (var rootRelative = false;).
well, how did you get to the terms rootRelative and documentRelative?
There is no true standard about it, and it is quite hard to find how to name it properly.
However, most people tend to call them root-relative and document-relative paths because of Adobe Dreamweaver and its documentation.
I found root-relative and document-relative terms to be quite self-explaining and didn't find better terms so far.
that can't work since relative is always false. Maybe you'd like to do these tests if this._parts.hostname is not set instead? While your RegExp is not wrong, a simple string comparison would suffice (this._parts.path.slice(0, 1) !== '/'). You should also declare and initialize the variables (var rootRelative = false;).
That was just quick take on, I didn't even test it. Just wanted to ensure that I properly understood how it should be handled.
that can't work since relative is always false. Maybe you'd like to do these tests if this._parts.hostname is not set instead?
Ah, I didn't get it from the beginning. So, !this._parts.hostname means that is relative, right?
While your RegExp is not wrong, a simple string comparison would suffice (this._parts.path.slice(0, 1) !== '/')
Sure, I just saw that all expressions stored in those methods, that way I tried to make it in same way, for consistency sake. Would such deviation be ok?
However, most people tend to call them root-relative and document-relative paths because of Adobe Dreamweaver and its documentation.
They seem to be calling that "site root-relative", but I'm not sure that makes it any better :D I'll accept the terminology.
Ah, I didn't get it from the beginning. So,
!this._parts.hostnamemeans that is relative, right?
It means that there is no hostname and that naturally makes the path independent of a host. URI calls this "relative". If there is a hostname, URI considers the URL "absolute" even if the protocol is relative (://).
Sure, I just saw that all expressions stored in those methods, that way I tried to make it in same way, for consistency sake. Would such deviation be ok?
Deviation from what? I'd go with this._parts.path.slice(0, 1) !== '/'
Ok, I've got it. I will try to prepare PR.
Also, can you clarify, should it be
uri.is("rootRelative");
uri.is("documentRelative");
or
uri.is("root-relative");
uri.is("document-relative");
or
uri.is("root_relative");
uri.is("document_relative");
From current code examples it's hard to tell which one should it be.
Also, I wonder — why this method is used here at all?
It feels like following approach is more "JavaScript-way". and it involves slightly less typing:
uri.isRelative()
uri.isAbsolute()
uri.isIp()
uri.isIdn()
Looks even cleaner.
Deviation from what? I'd go with this._parts.path.slice(0, 1) !== '/'
In your code in all instances, where string matching involved used expressions, and expressions declared on URI object. That's made sort of uniform approach:

Sudden use of slice here makes it a bit different way. Just wanted to ensure that it's ok.
I'd go with "kebab-case":
uri.is("root-relative");
uri.is("document-relative");
Also, I wonder — why this method
isused here at all?
to not bloat the prototype too much.