-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
url: make WHATWG URL properties spec compliant #10408
url: make WHATWG URL properties spec compliant #10408
Conversation
cccd70d
to
f5e0fff
Compare
Looks like github doesn't handle whitespace diffs very well :/ I believe only the EDIT: now the |
EDIT: turns out we can add |
Also /cc @targos @TimothyGu |
Can you post some benchmark results to make sure that the performance stays the same? |
f5e0fff
to
3f9f513
Compare
@TimothyGu Sure. Added those benchmarks to this PR too.
|
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 wouldn't worry about conflicts too much at this point. We can get it in later.
this[context].query = query; | ||
this[context].fragment = fragment; | ||
this[context].host = host; | ||
this[searchParams] = new URLSearchParams(query); |
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.
The searchParams
attribute is declared with [SameObject]
. When the href
setter is invoked, the underlying header list should be replaced, but not the URLSearchParams object itself.
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.
Thanks for spotting this. Fixed and added tests. Could be in conflict with https://github.com/nodejs/node/pull/10399/files#diff-7fa9474fccb31c3ccef5d728fbd5248bL557 for reusing part of the URLSearchParams constructor though, should be easy to rebase.
94e2134
to
cca5017
Compare
Ran the
|
@@ -105,7 +105,11 @@ function parse(input, base) { | |||
this[context].query = query; | |||
this[context].fragment = fragment; | |||
this[context].host = host; | |||
this[searchParams] = new URLSearchParams(query); | |||
if (this[searchParams]) { // invoked from href setter | |||
initSearchParams(this[searchParams], query); |
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.
So initSearchParams
strips a leading question mark, if one exists. But is it possible for query
contain a legitimate leading ?
at this point?
I'd rather just make a parseSearchParams
function, while moving the stringification and question mark stripping to where those are needed.
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 am not very sure about the possibility of the leading ?
. If we do need to make it a precondition, then we probably need to add a comment in node_url.cc
?
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.
Actually, after looking at node_url.cc, it's not possible for there to be a question mark here, which means that these following lines are not needed for this case:
init = String(init);
if (init[0] === '?') init = init.slice(1);
As a result of that, please move these lines from initSearchParams
back to URLSearchParams
's constructor.
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've moved them back. The commits are there for review, may need to squash them before rebase.
init = String(init); | ||
if (init[0] === '?') init = init.slice(1); | ||
this[searchParams] = querystring.parse(init); | ||
initSearchParams(this, init); |
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.
Yeah, I'd much prefer keeping the String()
and .slice
here, as they are such in the spec.
I'd like to take a bit more time to review this before it lands... unfortunately I won't have time until later next week after the holiday. |
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.
No more comments feom me. Thanks!
Could you squash these commits together in the form you think they could land in? That would make it a bit easier to review this. :) (I think the added benchmark doesn’t need to be squashed together with the rest.) |
d03e1a6
to
d1546d1
Compare
@addaleax OK, I've squashed them into two commits. https://github.com/nodejs/node/pull/10408/files?w=1 should be easier to review with the whitespace changes ignored. |
d1546d1
to
b417c9d
Compare
@@ -85,34 +85,40 @@ class TupleOrigin { | |||
} | |||
} | |||
|
|||
// Resued by URL constructor and |
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.
typo: Reused
? (This comment can also probably fit into a single line)
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.
Thanks for spotting this :)
writable: true, | ||
enumerable: true, | ||
configurable: true, | ||
value: function(options) { |
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.
nit: I’d suggest naming this function (i.e. function toString(options)
), otherwise V8 would infer its name as value
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.
So the linter yelled at me when I do this...
168:5 error Function name
toString
should match property namevalue
func-name-matching
maybe cc/ @Trott ?
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.
You can disable the func-name-matching
for that one line with a comment.
configurable: true,
// eslint-disable-next-line func-name-matching
value: function toString(options) {
There's also // eslint-disable-line func-name-matching
but since that has to be appended to the offending line, it often results in a line over 80 characters long, which violates a different lint rule. :-D
FWIW, this came up on the ESLint issue tracker two months ago but hasn't moved much since then. Doesn't look like there was consensus on whether something should be done or not. eslint/eslint#7423
/cc @not-an-aardvark
'username', 'password', 'host', 'hostname', 'port', | ||
'pathname', 'search', 'searchParams', 'hash']; | ||
|
||
assert.deepStrictEqual(props, expected); |
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 wonder: Is there a chance the ordering of the properties changes? Would we want to catch that or do we want to .sort()
these?
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.
According to https://heycam.github.io/webidl/#idl-interfaces I think the order doesn't really matter at the moment, although FF and Chrome do keep the enumeration order the same as the spec. Maybe this one can be left as-is until the spec changes?
* Set exposed attributes of the interface enumerable and configurable, as required by the spec. See: https://heycam.github.io/webidl/#es-attributes * Make sure `URL#searchParams` returns `[[SameObject]]` * Add the missing `URL#href` setter * Reorder the properties to match https://url.spec.whatwg.org/#api * Add tests for the ECMAScript property attributes Fixes: nodejs#10376
b417c9d
to
126d6e7
Compare
Ping, I've updated the commits. |
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.
LGTM with a minor nit
'use strict'; | ||
|
||
var common = require('../common.js'); | ||
var URL = require('url').URL; |
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.
These can be const
. The main reason for keeping var
in other benchmarks is for compatibility with older versions of Node.js, but since the WHATWG stuff wasn't introduced until v7, it's perfectly fine to use the newer conventions here.
* Set exposed attributes of the interface enumerable and configurable, as required by the spec. See: https://heycam.github.io/webidl/#es-attributes * Make sure `URL#searchParams` returns `[[SameObject]]` * Add the missing `URL#href` setter * Reorder the properties to match https://url.spec.whatwg.org/#api * Add tests for the ECMAScript property attributes PR-URL: #10408 Fixes: #10376 Reviewed-By: James M Snell <jasnell@gmail.com>
Landed in b7fadf0 and 508d976 |
* Set exposed attributes of the interface enumerable and configurable, as required by the spec. See: https://heycam.github.io/webidl/#es-attributes * Make sure `URL#searchParams` returns `[[SameObject]]` * Add the missing `URL#href` setter * Reorder the properties to match https://url.spec.whatwg.org/#api * Add tests for the ECMAScript property attributes PR-URL: #10408 Fixes: #10376 Reviewed-By: James M Snell <jasnell@gmail.com>
* Set exposed attributes of the interface enumerable and configurable, as required by the spec. See: https://heycam.github.io/webidl/#es-attributes * Make sure `URL#searchParams` returns `[[SameObject]]` * Add the missing `URL#href` setter * Reorder the properties to match https://url.spec.whatwg.org/#api * Add tests for the ECMAScript property attributes PR-URL: #10408 Fixes: #10376 Reviewed-By: James M Snell <jasnell@gmail.com>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
url, test
Description of change
enumerable
and
configurable
, as required by the spec.See: https://heycam.github.io/webidl/#es-attributes
URL#href
setterURL#searchParams
return the[SameObject]
Fixes: #10376
Possible conflicts: #10317, #10399, those two don't touch
internal/url.js
that much so should be easy to resolve with rebase.A few TODOs that I think should go into other PR(s), and are possibly in confict with this one:
TupleOrigin#toString
should haveunicode = true
as default (or just get rid of the argument)URL#toString
probably don't need the arguments. Those are not tested ATM anyway(see the test coverage) (conflicts with this PR).URL.originFor
,URL.domainToASCII
andURL.domainToUnicode
should be moved torequire('URL')
(conflicts with this PR)(Remove nonstandard URL.originFor #10374, Remove removed-from-spec URL.domainToASCII/domainToUnicode #10375).cc/ @jasnell