Closed Bug 1763648 Opened 3 years ago Closed 3 years ago

Setting URL.pathname on non-special URL clears URL.searchParams

Categories

(Core :: DOM: Core & HTML, defect)

Firefox 99
defect

Tracking

()

RESOLVED DUPLICATE of bug 1374505

People

(Reporter: flying-sheep, Unassigned)

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0

Steps to reproduce:

I have this function:

function broken(queryUrl) {
  const url = new URL(queryUrl, 'x:/')
  url.pathname = `${url.pathname}/stats`
  for (const p of ['limit', 'offset', 'order', 'columns']) url.searchParams.delete(p)
  return url.toString().substring(2) // 'x:/foo?...' -> '/foo?...'
}

And call it like this: broken('/foo?bar=baz&limit=100')

Actual results:

The function returns '/foo', unless I step into it with the devtools debugger and have a watch on url.toString(), then it returns the expected result:

Expected results:

The function should have returned '/foo?bar=baz', just like the one below:

function works(queryUrl) {
  const url = new URL(queryUrl, 'x:/')
  const path = `${url.pathname}/stats`
  const search = new URLSearchParams(url.search)
  for (const p of ['limit', 'offset', 'order', 'columns']) search.delete(p)
  return `${path}${search.toString().length > 0 ? `?${search}` : ''}`
}

Correction: It returns '/foo/stats' and should have returned '/foo/stats?bar=baz', just like the second function does.

Attached file searchparams.html

I turned the code here into a simple test case that alerts with the results of the two functions.

I tried this in Firefox Nightly, and the release versions of Chrome and Safari.

Firefox: "broken: /foo/stats; works: /foo/stats?bar=baz"
Chrome: "broken: /foo?bar=baz; works: /foo/stats?bar=baz"
Safari: "broken: /foo/stats?bar=baz; works: /foo/stats?bar=baz"

Note that Chrome also does not return the value expected by the reporter, but it returns a different value.

Anne, what should the behavior of this be? The fact that it apparently returns the expected value if the debugger is involved suggests this might be some weird bindings implementation issue, but it would be good to know what the behavior is expected to be.

Severity: -- → S3
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(annevk)

The problem isn't URL.searchParams.delete, it's that setting URL.pathname on a URL that has 'x://' as the scheme clears the searchParams:

const http = new URL("http://a.com/foo?bar=baz&limit=100");
http.pathname = http.pathname;
console.log(Array.from(http.searchParams.keys()));

const x = new URL("x://foo?bar=baz&limit=100");
x.pathname = x.pathname;
console.log(Array.from(x.searchParams.keys()));

logs ["bar", "limit"] and [] in Firefox.

Note that URL.searchParams is cached in Firefox, so if you access it before setting pathname then it'll have the right values, because we don't update the contents when setting pathname (because that shouldn't affect the query).

Summary: URL.searchParams.delete clears URL query → Setting URL.pathname on non-special URL clears URL.searchParams
Status: NEW → RESOLVED
Closed: 3 years ago
Flags: needinfo?(annevk)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: