Skip to content

Commit

Permalink
add value argument of URLSearchParams.prototype.{ has, delete }
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Jun 6, 2023
1 parent e17f473 commit 6813aba
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 26 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -24,6 +24,7 @@
- The methods renamed to end with `Symbol`, [May 2023 TC39 meeting](https://github.com/babel/proposals/issues/88#issuecomment-1548219580):
- `Symbol.isRegistered` -> `Symbol.isRegisteredSymbol`
- `Symbol.isWellKnown` -> `Symbol.isWellKnownSymbol`
- Added `value` argument of `URLSearchParams.prototype.{ has, delete }`, [url/735](https://github.com/whatwg/url/pull/735)
- Fixed some cases of increasing buffer size in `ArrayBuffer.prototype.{ transfer, transferToFixedLength }` polyfills
- Fixed awaiting async `AsyncDisposableStack.prototype.adopt` callback, [#1258](https://github.com/zloirock/core-js/issues/1258)
- Compat data improvements:
Expand All @@ -32,6 +33,7 @@
- Methods from the [change `Array` by copy proposal](https://github.com/tc39/proposal-change-array-by-copy) marked as supported from FF115
- [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) marked as supported from FF115
- [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse) marked as supported from FF115
- `value` argument of `URLSearchParams.prototype.{ has, delete }` marked as supported from [NodeJS 20.2.0](https://github.com/nodejs/node/pull/47885) and FF115
- Added Deno 1.34 compat data mapping
- Added Electron 26 compat data mapping
- Added Samsung Internet 22 compat data mapping
Expand Down
21 changes: 13 additions & 8 deletions README.md
Expand Up @@ -3239,7 +3239,7 @@ queueMicrotask(() => console.log('called as microtask'));
```
#### `URL` and `URLSearchParams`[⬆](#index)
[`URL` standard](https://url.spec.whatwg.org/) implementation. Modules [`web.url`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.js), [`web.url.can-parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.can-parse.js), [`web.url.to-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.to-json.js), [`web.url-search-params`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.js), [`web.url-search-params.size`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.size.js).
[`URL` standard](https://url.spec.whatwg.org/) implementation. Modules [`web.url`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.js), [`web.url.can-parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.can-parse.js), [`web.url.to-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.to-json.js), [`web.url-search-params`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.js), [`web.url-search-params.delete`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.delete.js), [`web.url-search-params.has`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.has.js), [`web.url-search-params.size`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.size.js).
```js
class URL {
constructor(url: string, base?: string);
Expand All @@ -3263,10 +3263,10 @@ class URL {
class URLSearchParams {
constructor(params?: string | Iterable<[key, value]> | Object);
append(name: string, value: string): void;
delete(name: string): void;
delete(name: string, value?: string): void;
get(name: string): string | void;
getAll(name: string): Array<string>;
has(name: string): boolean;
has(name: string, value?: string): boolean;
set(name: string, value: string): void;
sort(): void;
toString(): string;
Expand All @@ -3286,7 +3286,7 @@ core-js(-pure)/stable|actual|full/url/can-parse
core-js/stable|actual|full/url/to-json
core-js(-pure)/stable|actual|full/url-search-params
```
[*Examples*](https://tinyurl.com/2ovt23zn):
[*Examples*](https://tinyurl.com/2j35uor6):
```js
URL.canParse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); // => true
URL.canParse('https'); // => false
Expand Down Expand Up @@ -3322,16 +3322,21 @@ const params = new URLSearchParams('?a=1&b=2&a=3');

params.append('c', 4);
params.append('a', 2);
params.delete('a', 1);
params.sort();

console.log(params.size); // => 5
console.log(params.size); // => 4

for (let [key, value] of params) {
console.log(key); // => 'a', 'a', 'a', 'b', 'c'
console.log(value); // => '1', '3', '2', '2', '4'
console.log(key); // => 'a', 'a', 'b', 'c'
console.log(value); // => '3', '2', '2', '4'
}

console.log(params.toString()); // => 'a=1&a=3&a=2&b=2&c=4'
console.log(params.has('a')); // => true
console.log(params.has('a', 3)); // => true
console.log(params.has('a', 4)); // => false

console.log(params.toString()); // => 'a=3&a=2&b=2&c=4'
```
##### Caveats when using `URL` and `URLSearchParams`:[⬆](#index)
Expand Down
8 changes: 8 additions & 0 deletions packages/core-js-compat/src/data.mjs
Expand Up @@ -2509,6 +2509,14 @@ export const data = {
node: '10.0',
safari: '14.0',
},
'web.url-search-params.delete': {
firefox: '115',
node: '20.2.0',
},
'web.url-search-params.has': {
firefox: '115',
node: '20.2.0',
},
'web.url-search-params.size': {
chrome: '113',
deno: '1.32',
Expand Down
2 changes: 2 additions & 0 deletions packages/core-js-compat/src/modules-by-versions.mjs
Expand Up @@ -210,5 +210,7 @@ export default {
'esnext.promise.with-resolvers',
'esnext.symbol.is-registered-symbol',
'esnext.symbol.is-well-known-symbol',
'web.url-search-params.delete',
'web.url-search-params.has',
],
};
30 changes: 19 additions & 11 deletions packages/core-js/modules/web.url-search-params.constructor.js
Expand Up @@ -214,32 +214,37 @@ defineBuiltIns(URLSearchParamsPrototype, {
// `URLSearchParams.prototype.append` method
// https://url.spec.whatwg.org/#dom-urlsearchparams-append
append: function append(name, value) {
validateArgumentsLength(arguments.length, 2);
var state = getInternalParamsState(this);
validateArgumentsLength(arguments.length, 2);
push(state.entries, { key: $toString(name), value: $toString(value) });
if (!DESCRIPTORS) this.length++;
state.updateURL();
},
// `URLSearchParams.prototype.delete` method
// https://url.spec.whatwg.org/#dom-urlsearchparams-delete
'delete': function (name) {
validateArgumentsLength(arguments.length, 1);
'delete': function (name /* , value */) {
var state = getInternalParamsState(this);
var length = validateArgumentsLength(arguments.length, 1);
var entries = state.entries;
var key = $toString(name);
var $value = length < 2 ? undefined : arguments[1];
var value = $value === undefined ? $value : $toString($value);
var index = 0;
while (index < entries.length) {
if (entries[index].key === key) splice(entries, index, 1);
else index++;
var entry = entries[index];
if (entry.key === key && (value === undefined || entry.value === value)) {
splice(entries, index, 1);
if (value !== undefined) break;
} else index++;
}
if (!DESCRIPTORS) this.length = entries.length;
state.updateURL();
},
// `URLSearchParams.prototype.get` method
// https://url.spec.whatwg.org/#dom-urlsearchparams-get
get: function get(name) {
validateArgumentsLength(arguments.length, 1);
var entries = getInternalParamsState(this).entries;
validateArgumentsLength(arguments.length, 1);
var key = $toString(name);
var index = 0;
for (; index < entries.length; index++) {
Expand All @@ -250,8 +255,8 @@ defineBuiltIns(URLSearchParamsPrototype, {
// `URLSearchParams.prototype.getAll` method
// https://url.spec.whatwg.org/#dom-urlsearchparams-getall
getAll: function getAll(name) {
validateArgumentsLength(arguments.length, 1);
var entries = getInternalParamsState(this).entries;
validateArgumentsLength(arguments.length, 1);
var key = $toString(name);
var result = [];
var index = 0;
Expand All @@ -262,21 +267,24 @@ defineBuiltIns(URLSearchParamsPrototype, {
},
// `URLSearchParams.prototype.has` method
// https://url.spec.whatwg.org/#dom-urlsearchparams-has
has: function has(name) {
validateArgumentsLength(arguments.length, 1);
has: function has(name /* , value */) {
var entries = getInternalParamsState(this).entries;
var length = validateArgumentsLength(arguments.length, 1);
var key = $toString(name);
var $value = length < 2 ? undefined : arguments[1];
var value = $value === undefined ? $value : $toString($value);
var index = 0;
while (index < entries.length) {
if (entries[index++].key === key) return true;
var entry = entries[index++];
if (entry.key === key && (value === undefined || entry.value === value)) return true;
}
return false;
},
// `URLSearchParams.prototype.set` method
// https://url.spec.whatwg.org/#dom-urlsearchparams-set
set: function set(name, value) {
validateArgumentsLength(arguments.length, 1);
var state = getInternalParamsState(this);
validateArgumentsLength(arguments.length, 1);
var entries = state.entries;
var found = false;
var key = $toString(name);
Expand Down
41 changes: 41 additions & 0 deletions packages/core-js/modules/web.url-search-params.delete.js
@@ -0,0 +1,41 @@
'use strict';
var getBuiltIn = require('../internals/get-built-in');
var defineBuiltIn = require('../internals/define-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var toString = require('../internals/to-string');
var validateArgumentsLength = require('../internals/validate-arguments-length');

var URLSearchParams = getBuiltIn('URLSearchParams');
var URLSearchParamsPrototype = URLSearchParams.prototype;
var append = uncurryThis(URLSearchParamsPrototype.append);
var $delete = uncurryThis(URLSearchParamsPrototype['delete']);
var forEach = uncurryThis(URLSearchParamsPrototype.forEach);
var push = uncurryThis([].push);
var params = new URLSearchParams('a=1&a=2');

params['delete']('a', 1);

if (params + '' !== 'a=2') {
defineBuiltIn(URLSearchParamsPrototype, 'delete', function (name /* , value */) {
var length = arguments.length;
var $value = length < 2 ? undefined : arguments[1];
if (length && $value === undefined) return $delete(this, name);
var entries = [];
forEach(this, function (v, k) { // also validates `this`
push(entries, { key: k, value: v });
});
validateArgumentsLength(length, 1);
var key = toString(name);
var value = toString($value);
var index = 0;
var entriesLength = entries.length;
while (index < entriesLength) {
$delete(this, entries[index++].key);
}
index = 0;
while (index < entriesLength) {
var entry = entries[index++];
if (!(entry.key === key && entry.value === value)) append(this, entry.key, entry.value);
}
}, { enumerable: true, unsafe: true });
}
27 changes: 27 additions & 0 deletions packages/core-js/modules/web.url-search-params.has.js
@@ -0,0 +1,27 @@
'use strict';
var getBuiltIn = require('../internals/get-built-in');
var defineBuiltIn = require('../internals/define-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var toString = require('../internals/to-string');
var validateArgumentsLength = require('../internals/validate-arguments-length');

var URLSearchParams = getBuiltIn('URLSearchParams');
var URLSearchParamsPrototype = URLSearchParams.prototype;
var getAll = uncurryThis(URLSearchParamsPrototype.getAll);
var $has = uncurryThis(URLSearchParamsPrototype.has);
var params = new URLSearchParams('a=1');

if (params.has('a', 2)) {
defineBuiltIn(URLSearchParamsPrototype, 'has', function has(name /* , value */) {
var length = arguments.length;
var $value = length < 2 ? undefined : arguments[1];
if (length && $value === undefined) return $has(this, name);
var values = getAll(this, name); // also validates `this`
validateArgumentsLength(length, 1);
var value = toString($value);
var index = 0;
while (index < values.length) {
if (values[index++] === value) return true;
} return false;
}, { enumerable: true, unsafe: true });
}
6 changes: 1 addition & 5 deletions packages/core-js/proposals/url.js
@@ -1,6 +1,2 @@
// https://github.com/jasnell/proposal-url
require('../modules/web.url');
require('../modules/web.url.can-parse');
require('../modules/web.url.to-json');
require('../modules/web.url-search-params');
require('../modules/web.url-search-params.size');
require('../web/url');
2 changes: 2 additions & 0 deletions packages/core-js/web/index.js
Expand Up @@ -14,6 +14,8 @@ require('../modules/web.url');
require('../modules/web.url.can-parse');
require('../modules/web.url.to-json');
require('../modules/web.url-search-params');
require('../modules/web.url-search-params.delete');
require('../modules/web.url-search-params.has');
require('../modules/web.url-search-params.size');
var path = require('../internals/path');

Expand Down
2 changes: 2 additions & 0 deletions packages/core-js/web/url-search-params.js
@@ -1,4 +1,6 @@
require('../modules/web.url-search-params');
require('../modules/web.url-search-params.delete');
require('../modules/web.url-search-params.has');
require('../modules/web.url-search-params.size');
var path = require('../internals/path');

Expand Down
3 changes: 1 addition & 2 deletions packages/core-js/web/url.js
@@ -1,8 +1,7 @@
require('./url-search-params');
require('../modules/web.url');
require('../modules/web.url.can-parse');
require('../modules/web.url.to-json');
require('../modules/web.url-search-params');
require('../modules/web.url-search-params.size');
var path = require('../internals/path');

module.exports = path.URL;
9 changes: 9 additions & 0 deletions tests/compat/tests.js
Expand Up @@ -1956,6 +1956,15 @@ GLOBAL.tests = {
return URL.prototype.toJSON;
}],
'web.url-search-params.constructor': URL_AND_URL_SEARCH_PARAMS_SUPPORT,
'web.url-search-params.delete': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () {
var params = new URLSearchParams('a=1&a=2');
params['delete']('a', 1);
return params + '' === 'a=2';
}],
'web.url-search-params.has': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () {
var params = new URLSearchParams('a=1');
return params.has('a', 1) && !params.has('a', 2);
}],
'web.url-search-params.size': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () {
return 'size' in URLSearchParams.prototype;
}]
Expand Down
21 changes: 21 additions & 0 deletions tests/unit-global/web.url-search-params.js
Expand Up @@ -231,6 +231,18 @@ QUnit.test('URLSearchParams#delete', assert => {
params.delete('first');
assert.false(params.has('first'), 'search params object has no "first" name');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
params.delete('a', 2);
assert.same(String(params), 'a=1&a=null&a=3&b=4');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
params.delete('a', null);
assert.same(String(params), 'a=1&a=2&a=3&b=4');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
params.delete('a', undefined);
assert.same(String(params), 'b=4');

if (DESCRIPTORS) {
let url = new URL('http://example.com/?param1&param2');
url.searchParams.delete('param1');
Expand Down Expand Up @@ -380,6 +392,15 @@ QUnit.test('URLSearchParams#has', assert => {
params.delete('first');
assert.false(params.has('first'), 'search params object has no name "first"');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
assert.true(params.has('a', 2));
assert.true(params.has('a', null));
assert.false(params.has('a', 4));
assert.true(params.has('b', 4));
assert.false(params.has('b', null));
assert.true(params.has('b', undefined));
assert.false(params.has('c', undefined));

assert.throws(() => {
return new URLSearchParams('').has();
}, 'throws w/o arguments');
Expand Down
21 changes: 21 additions & 0 deletions tests/unit-pure/web.url-search-params.js
Expand Up @@ -230,6 +230,18 @@ QUnit.test('URLSearchParams#delete', assert => {
params.delete('first');
assert.false(params.has('first'), 'search params object has no "first" name');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
params.delete('a', 2);
assert.same(String(params), 'a=1&a=null&a=3&b=4');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
params.delete('a', null);
assert.same(String(params), 'a=1&a=2&a=3&b=4');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
params.delete('a', undefined);
assert.same(String(params), 'b=4');

if (DESCRIPTORS) {
let url = new URL('http://example.com/?param1&param2');
url.searchParams.delete('param1');
Expand Down Expand Up @@ -373,6 +385,15 @@ QUnit.test('URLSearchParams#has', assert => {
params.delete('first');
assert.false(params.has('first'), 'search params object has no name "first"');

params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4');
assert.true(params.has('a', 2));
assert.true(params.has('a', null));
assert.false(params.has('a', 4));
assert.true(params.has('b', 4));
assert.false(params.has('b', null));
assert.true(params.has('b', undefined));
assert.false(params.has('c', undefined));

assert.throws(() => {
return new URLSearchParams('').has();
}, 'throws w/o arguments');
Expand Down

0 comments on commit 6813aba

Please sign in to comment.