-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Conversation
@@ -389,6 +389,18 @@ Url.prototype.format = function() { | |||
host = false, | |||
query = ''; | |||
|
|||
if (this.path) { | |||
var qm = this.path.indexOf('?'); | |||
pathname = pathname || (function(idx, path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we handle it without creating closure?
Removed closure function 🌸 |
query = this.path.slice(qm); | ||
pathname = pathname || this.path.slice(0, qm); | ||
} else { | ||
pathname = pathname || this.path; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If path is given:
- if it contains "?...", that replaces the current
query
- if it does not contain "?...", the current
query
is used - if
search
is given, it always wins - if
hash
is given, it always wins
I suppose my confusion is: for some attributes, the more specific attribute "wins" versus the more general attribute, while in the "path" case, the less specific version wins:
query is more specific than search is more specific than path -> search wins
pathname is more specific than path -> path wins
hash is more specific than path -> hash wins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pathname is more specific than path -> path wins
hash is more specific than path -> hash wins
hey @chrisdickinson they are not consistent because you say:
the less specific version wins
i guess in hash line, it should be "path wins"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and for given pseudocode by last last comment, in path
case, we should only touch one of query
or search
, because in path
they are overlapped, so i choose query
, search
will be reassigned next code, so i propose the program will be:
- if it contains "?...", than replaces the current
query
- if it doesn't, the current
query
is used of course includedsearch
- if it contains "#...", then replaces the current
hash
- if it doesn't, the current
hash
is used
query is more specific than search is more specific than path -> search wins
from my above statement, i guess we shouldn't touch search
any more, just follow the step 1.
@chrisdickinson how do you think about my idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. I think we should try to mirror how host
(vs. hostname
+ port
) operates with path
-- that is:
If path
is given, it is assumed to include search
/query
and pathname
. If those are not present in path
, and path
is given, then they will be omitted from the output of format
.
So:
// we're matching this behavior: (port is omitted from "host" but "host" overrides port)
assert.equal(url.format({host: 'some.host.com', hostname: 'example.com', port: 8080}), '//some.host.com');
assert.equal(url.format({hostname: 'example.com', port: 8080}), '//example.com:8080');
// "auth" is not considered part of "host"
assert.equal(url.format({auth: 'a:b', host: 'some.host.com', hostname: 'example.com', port: 8080}), '//a:[email protected]');
assert.equal(url.format({auth: 'a:b', hostname: 'example.com', port: 8080}), '//a:[email protected]:8080');
// "path" does not include "hash", but does include "search" and "pathname"
assert.equal(url.parse('http://example.com/path/to/thing?q=1#hash').path, '/path/to/thing?q=1')
// "path" overrides pathname
assert.equal(url.format({host: "example.com", path: "/path/to/thing?q=1", pathname: "/anythingelse"}), '//example.com/path/to/thing?q=1')
// "path" overrides search/query
assert.equal(url.format({host: "example.com", path: "/path/to/thing?q=1", search: "?p=2"}), '//example.com/path/to/thing?q=1')
// "path" overrides search/query even if not given in "path"
assert.equal(url.format({host: "example.com", path: "/path/to/thing", search: "?p=2"}), '//example.com/path/to/thing')
// similarly, "path" overrides "pathname" even if not given:
assert.equal(url.format({host: "example.com", path: "?p=2", pathname: "/anything"}), '//example.com?p=2')
to illustrate:
+-----------------------------------------------------------------------------------+
| href |
+----------+--+-----------+--------------------+-----------------------------+------+
| protocol |* | auth | host | path | hash |
| | | +-------------+------+----------+------------------+ |
| | | | hostname | port | pathname | search | |
| | | | | | +-+----------------+ |
| | | | | | | | query | |
" http: // user:[email protected]:65535 /path/name ? search=1&continues#hash "
| | | | | | | | | |
+----------+--+-----------+-------------+------+----------+-+----------------+------+
(all spaces in the "" line should be ignored -- they're purely for formatting)
*: given by "slashes" key
Setting a key at the higher level should cause url.format
to ignore all keys at a "lower" level, whether or not that lower key is present in the text of the higher level key (even though "port" may not be present in "host", setting "host" ignores all values for "port").
ah, gotcha, i was just getting it backwards!!! |
search = '?' + query; | ||
pathname = this.path.slice(0, qm); | ||
} else { | ||
pathname = this.path; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's one last case to check here -- path
is present, but has no ?...
, so the output url should have no ?...
-- i.e., the query
, search
, and pathname
keys are ignored if path
is given.
@chrisdickinson reset |
query: {foo: 'bar'} | ||
}, | ||
|
||
// path vs. search, search wins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should probably read "path wins" here and on line 1154 now -- but I can fix that up on merge.
This is great. Thanks! LGTM /cc @indutny, if nobody has any qualms, I'll merge this tomorrow evening. |
- pathname vs. path, pathname wins - pathname with query/search - path vs. query, query wins - path vs. search, search wins
Fixed comments now |
ping @chrisdickinson 🎅 |
struggle for pinging @chrisdickinson (This PR should has such a long delay?) |
Ack! Sorry this took so long for me to pick up again. Looking now. |
this adds support for a "path" field that overrides "query", "search", and "pathname" if given. Fixes: #8722 PR-URL: #8755 Reviewed-by: Chris Dickinson <[email protected]>
Thanks for your patience! Merged in d312b6d. |
this adds support for a "path" field that overrides "query", "search", and "pathname" if given. Fixes: nodejs/node-v0.x-archive#8722 PR-URL: nodejs/node-v0.x-archive#8755 Reviewed-by: Chris Dickinson <[email protected]>
np 🍒 |
This patch attempts to close this issue #8722:
jshint
in test-url.jsR=@indutny, @chrisdickinson 🍒