Skip to content
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

Add URL and URLSearchParams #454

Merged
merged 36 commits into from
Dec 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c3df18d
initial `URL` and `URLSearchParams` commit
zloirock Nov 12, 2018
6f641b2
some improvements
zloirock Nov 14, 2018
d931ae2
some improvements
zloirock Nov 27, 2018
9ad48f8
change the way of base URL handling and error handling on href initia…
zloirock Nov 27, 2018
f01cf75
add support of domain names in Unicode
zloirock Nov 27, 2018
64bb664
add parsing of IP addresses
zloirock Nov 28, 2018
4c00aa9
improve host parsing
zloirock Nov 29, 2018
cafe98a
improve url parsing
zloirock Nov 30, 2018
747c0eb
rewrite URL parser by the spec
zloirock Dec 2, 2018
d700435
some stylistic changes, add blob origin
zloirock Dec 3, 2018
9c3eb14
some stylistic changes
zloirock Dec 6, 2018
c80ffb6
remove leading and trailing spaces in all required cases
zloirock Dec 6, 2018
25bc427
some fixes of interaction of URL and URLSearchParams
zloirock Dec 6, 2018
0436543
use correct percent-encode sets
zloirock Dec 6, 2018
0cf8ebf
some fixes in url parsing and some stylistic changes
zloirock Dec 7, 2018
752a5bd
add some more tests
zloirock Dec 7, 2018
0555eea
add some more tests
zloirock Dec 7, 2018
c7593dd
fix unicode support in url
zloirock Dec 7, 2018
0800445
add some more tests
zloirock Dec 8, 2018
bf5d042
fix ipv6 parsing
zloirock Dec 8, 2018
52681b3
port number is removed if empty is the new value
zloirock Dec 8, 2018
863fa09
add web platform url setters tests
zloirock Dec 8, 2018
1f21781
add web platform url parsing tests
zloirock Dec 8, 2018
c914228
add web platform toASCII conversion tests
zloirock Dec 8, 2018
e8829bb
fix compression of ipv6
zloirock Dec 9, 2018
0d60ef8
fix forbidden host code points for opaque hosts
zloirock Dec 9, 2018
a115002
fix ipv4 validation
zloirock Dec 9, 2018
a5aecdc
fix compressed ipv6 serialization
zloirock Dec 9, 2018
f961a2a
use direct conversion to string in setters
zloirock Dec 10, 2018
aa79f2c
fix some special cases of query parsing
zloirock Dec 10, 2018
f8eb546
add some comments to tests
zloirock Dec 10, 2018
b712649
some stylistic changes
zloirock Dec 10, 2018
2468e61
update readme
zloirock Dec 11, 2018
147beac
replace MS Edge URL which fails in too many cases
zloirock Dec 11, 2018
ddd81c1
add comments about failing some tests in Chrome 66-
zloirock Dec 11, 2018
828178c
use URL polyfill in Chrome 62-
zloirock Dec 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ module.exports = {
'tests/helpers/**',
'tests/pure/**',
'tests/tests/**',
'tests/wpt-url-resources/**',
],
parserOptions: {
sourceType: 'module',
Expand Down
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,36 @@
- `Symbol.patternMatch` ([for stage 1 pattern matching proposal](https://github.com/tc39/proposal-pattern-matching))
- `Symbol.dispose` ([for stage 1 `using` statement proposal](https://github.com/tc39/proposal-using-statement))
- `Promise.allSettled` ([stage 1 proposal](https://github.com/jasonwilliams/proposal-promise-allSettled))
- `.forEach` method to iterable DOM collections ([#329](https://github.com/zloirock/core-js/issues/329))
- `URL` and `URLSearchParam` [from `URL` standard](https://url.spec.whatwg.org/), also [stage 0 proposal to ECMAScript](https://github.com/jasnell/proposal-url)
- `URL`
- `URL#href`
- `URL#origin`
- `URL#protocol`
- `URL#username`
- `URL#password`
- `URL#host`
- `URL#hostname`
- `URL#port`
- `URL#pathname`
- `URL#search`
- `URL#searchParams`
- `URL#hash`
- `URL#toString`
- `URL#toJSON`
- `URLSearchParams`
- `URLSearchParams#append`
- `URLSearchParams#delete`
- `URLSearchParams#get`
- `URLSearchParams#getAll`
- `URLSearchParams#has`
- `URLSearchParams#set`
- `URLSearchParams#sort`
- `URLSearchParams#toString`
- `URLSearchParams#keys`
- `URLSearchParams#values`
- `URLSearchParams#entries`
- `URLSearchParams#@@iterator`
- `.forEach` method on iterable DOM collections ([#329](https://github.com/zloirock/core-js/issues/329))
- Improve existing features:
- Add triggering unhandled `Promise` rejection events (instead of only global handlers), [#205](https://github.com/zloirock/core-js/issues/205).
- Add support of `@@isConcatSpreadable` to `Array#concat`.
Expand Down
146 changes: 122 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ Promise.resolve(32).then(x => console.log(x)); // => 32
- [stage 0 proposals](#stage-0-proposals)
- [pre-stage 0 proposals](#pre-stage-0-proposals)
- [Web standards](#web-standards)
- [setTimeout / setInterval](#settimeout--setinterval)
- [setImmediate](#setimmediate)
- [queueMicrotask](#queuemicrotask)
- [`setTimeout` and `setInterval`](#settimeout-and-setinterval)
- [`setImmediate`](#setimmediate)
- [`queueMicrotask`](#queuemicrotask)
- [`URL` and `URLSearchParams`](#url-and-urlsearchparams)
- [iterable DOM collections](#iterable-dom-collections)
- [Iteration helpers](#iteration-helpers)
- [Missing polyfills](#missing-polyfills)
Expand Down Expand Up @@ -561,7 +562,7 @@ class RegExp {
@@replace(string: string, replaceValue: Function | string): string;
@@search(string: string): number;
@@split(string: string, limit: number): Array<string>;
get flags: string; // IE9+
readonly attribute flags: string; // IE9+
}
```
[*CommonJS entry points:*](#commonjs)
Expand Down Expand Up @@ -916,7 +917,7 @@ Modules [`es.symbol`](https://github.com/zloirock/core-js/blob/master/packages/c
```js
class Symbol {
constructor(description?): symbol;
get description: string | void;
readonly attribute description: string | void;
static asyncIterator: @@asyncIterator;
static hasInstance: @@hasInstance;
static isConcatSpreadable: @@isConcatSpreadable;
Expand Down Expand Up @@ -1058,7 +1059,7 @@ class Map {
keys(): Iterator<key>;
entries(): Iterator<[key, value]>;
@@iterator(): Iterator<[key, value]>;
get size: number;
readonly attribute size: number;
}
```
[*CommonJS entry points:*](#commonjs)
Expand Down Expand Up @@ -1112,7 +1113,7 @@ class Set {
keys(): Iterator<value>;
entries(): Iterator<[value, value]>;
@@iterator(): Iterator<value>;
get size: number;
readonly attribute size: number;
}
```
[*CommonJS entry points:*](#commonjs)
Expand Down Expand Up @@ -1228,7 +1229,7 @@ Modules [`es.array-buffer.constructor`](https://github.com/zloirock/core-js/blob
class ArrayBuffer {
constructor(length: any): ArrayBuffer;
slice(start: any, end: any): ArrayBuffer;
get byteLength: number;
readonly attribute byteLength: number;
static isView(arg: any): boolean;
}

Expand All @@ -1250,9 +1251,9 @@ class DataView {
setUint32(offset: any, value: any, littleEndian?: boolean = false): void;
setFloat32(offset: any, value: any, littleEndian?: boolean = false): void;
setFloat64(offset: any, value: any, littleEndian?: boolean = false): void;
get buffer: ArrayBuffer;
get byteLength: number;
get byteOffset: number;
readonly attribute buffer: ArrayBuffer;
readonly attribute byteLength: number;
readonly attribute byteOffset: number;
}

class [
Expand Down Expand Up @@ -1295,10 +1296,10 @@ class [
keys(): Iterator<index>;
entries(): Iterator<[index, value]>;
@@iterator(): Iterator<value>;
get buffer: ArrayBuffer;
get byteLength: number;
get byteOffset: number;
get length: number;
readonly attribute buffer: ArrayBuffer;
readonly attribute byteLength: number;
readonly attribute byteOffset: number;
readonly attribute length: number;
BYTES_PER_ELEMENT: number;
static from(items: Iterable | ArrayLike, mapFn?: (value: any, index: number) => any, thisArg?: any): %TypedArray%;
static of(...args: Array<mixed>): %TypedArray%;
Expand Down Expand Up @@ -1590,7 +1591,7 @@ core-js(-pure)/features/set/union
[*Examples*](https://goo.gl/YjaxTN):
```js
new Set([1, 2, 3]).union([3, 4, 5]); // => Set {1, 2, 3, 4, 5}
new Set([1, 2, 3]).intersection([3, 4, 5]); // => Set {3}
new Set([1, 2, 3]).intersection([3, 4, 5]); // => Set {3}
new Set([1, 2, 3]).difference([3, 4, 5]); // => Set {1, 2}
new Set([1, 2, 3]).symmetricDifference([3, 4, 5]); // => Set {1, 2, 4, 5}
```
Expand All @@ -1603,9 +1604,8 @@ core-js(-pure)/stage/1
* Getting last item from `Array` [proposal](https://github.com/keithamus/proposal-array-last) - modules [`esnext.array.last-item`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.last-item.js) and [`esnext.array.last-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.last-index.js)
```js
class Array {
get lastItem: value;
set lastItem(value);
get lastIndex: uint;
attribute lastItem: any;
readonly attribute lastIndex: uint;
}
```
[*CommonJS entry points:*](#commonjs)
Expand Down Expand Up @@ -1815,7 +1815,7 @@ class Observable {
@@observable(): this;
static of(...items: Aray<mixed>): Observable;
static from(x: Observable | Iterable): Observable;
static get @@species: this;
static readonly attribute @@species: this;
}

class Symbol {
Expand Down Expand Up @@ -1956,6 +1956,7 @@ core-js(-pure)/features/symbol/dispose
```js
core-js(-pure)/stage/0
```
* `URL` [proposal](https://github.com/jasnell/proposal-url), see more info [in web standards namespace](#url-and-urlsearchparams)
* `String#at` [proposal](https://github.com/mathiasbynens/String.prototype.at) - module [`esnext.string.at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.string.at.js)
```js
class String {
Expand Down Expand Up @@ -2037,7 +2038,7 @@ Reflect.getOwnMetadata('foo', object); // => 'bar'
```js
core-js(-pure)/web
```
#### setTimeout / setInterval
#### `setTimeout` and `setInterval`
Module [`web.timers`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.timers.js). Additional arguments fix for IE9-.
```js
function setTimeout(callback: any, time: any, ...args: Array<mixed>): number;
Expand All @@ -2055,7 +2056,7 @@ setTimeout(log.bind(null, 42), 1000);
// After:
setTimeout(log, 1000, 42);
```
#### setImmediate
#### `setImmediate`
Module [`web.immediate`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.immediate.js). [`setImmediate` proposal](https://developer.mozilla.org/en-US/docs/Web/API/Window.setImmediate) polyfill.
```js
function setImmediate(callback: any, ...args: Array<mixed>): number;
Expand All @@ -2077,7 +2078,8 @@ clearImmediate(setImmediate(() => {
console.log('Message will not be displayed');
}));
```
#### queueMicrotask

#### `queueMicrotask`
[Spec](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask), module [`web.queue-microtask`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.queue-microtask.js)
```js
function queueMicrotask(fn: Function): void;
Expand All @@ -2092,6 +2094,102 @@ core-js(-pure)/features/queue-microtask
queueMicrotask(() => console.log('called as microtask'));
```

#### `URL` and `URLSearchParams`
[`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.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.sort`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.sort.js).
```js
class URL {
constructor(url: string, base?: string);
attribute href: string;
readonly attribute origin: string;
attribute protocol: string;
attribute username: string;
attribute password: string;
attribute host: string;
attribute hostname: string;
attribute port: string;
attribute pathname: string;
attribute search: string;
readonly attribute searchParams: URLSearchParams;
attribute hash: string;
toJSON(): string;
toString(): string;
}

class URLSearchParams {
constructor(params?: string | Iterable<[key, value]> | Object);
append(name: string, value: string): void;
delete(name: string): void;
get(name: string): string | void;
getAll(name: string): Array<string>;
has(name: string): boolean;
set(name: string, value: string): void;
sort(): void;
toString(): string;
forEach(callbackfn: (value: any, index: number, target: any) => void, thisArg: any): void;
entries(): Iterator<[key, value]>;
keys(): Iterator<key>;
values(): Iterator<value>;
@@iterator(): Iterator<[key, value]>;
}
```
[*CommonJS entry points:*](#commonjs)
```js
core-js/proposals/url
core-js(-pure)/web/url
core-js(-pure)/web/url-search-params
core-js(-pure)/features/url
core-js/features/url/to-json
core-js(-pure)/features/url-search-params
core-js/features/url-search-params/sort
```
[*Examples*](https://goo.gl/kksjwV):
```js
const url = new URL('http://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment');

console.log(url.href); // => 'http://login:password@example.com:8080/foo/bar?a=1&b=2#fragment'
console.log(url.origin); // => 'http://example.com:8080'
console.log(url.protocol); // => 'http:'
console.log(url.username); // => 'login'
console.log(url.password); // => 'password'
console.log(url.host); // => 'example.com:8080'
console.log(url.hostname); // => 'example.com'
console.log(url.port); // => '8080'
console.log(url.pathname); // => '/foo/bar'
console.log(url.search); // => '?a=1&b=2&a=3'
console.log(url.hash); // => '#fragment'
console.log(url.toJSON()); // => 'http://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment'
console.log(url.toString()); // => 'http://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment'

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

url.pathname = '';
url.searchParams.append('c', 3);

console.log(url.search); // => '?a=1&b=2&c=3'
console.log(url.href); // => 'http://login:password@example.com:8080/?a=1&a=3&b=2&c=4#fragment'

const params = new URLSearchParams('?a=1&b=2&a=3');

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

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

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

##### Caveats when using `URL` and `URLSearchParams`:
- IE8- does not supports setters, so they does not work on `URL` instances. However, `URL` constructor can be used for basic `URL` parsing.
- Legacy encodings in a search query are not supported. Also, `core-js` implementation has some other encoding-related issues.
- `URL` implementations from all of popular browsers have much more problems than `core-js`, however, replacing all of them does not looks like a good idea. You can customize aggressiveness of polyfill [by your requirements](#configurable-level-of-aggressiveness).

#### Iterable DOM collections
Some DOM collections should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass). That means they should have `forEach`, `keys`, `values`, `entries` and `@@iterator` methods for iteration. So add them. Modules [`web.dom-collections.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-collections.iterator.js) and [`web.dom-collections.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-collections.for-each.js).
```js
Expand Down Expand Up @@ -2130,8 +2228,8 @@ class [
}

class [DOMTokenList, NodeList] {
entries(): Iterator<[key, value]>;
forEach(callbackfn: (value: any, index: number, target: any) => void, thisArg: any): void;
entries(): Iterator<[key, value]>;
keys(): Iterator<key>;
values(): Iterator<value>;
@@iterator(): Iterator<value>;
Expand Down
4 changes: 4 additions & 0 deletions packages/core-js-builder/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ module.exports = {
'web.immediate',
'web.queue-microtask',
'web.timers',
'web.url',
'web.url.to-json',
'web.url-search-params',
'web.url-search-params.sort',
],
/* eslint-disable prefer-template */
banner: '/**\n' +
Expand Down
8 changes: 4 additions & 4 deletions packages/core-js-pure/override/internals/redefine-all.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
var hide = require('../internals/hide');
var redefine = require('../internals/redefine');

module.exports = function (target, src, safe) {
module.exports = function (target, src, options) {
for (var key in src) {
if (safe && target[key]) target[key] = src[key];
else hide(target, key, src[key]);
if (options && options.unsafe && target[key]) target[key] = src[key];
else redefine(target, key, src[key], options);
} return target;
};
7 changes: 6 additions & 1 deletion packages/core-js-pure/override/internals/redefine.js
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
module.exports = require('../internals/hide');
var hide = require('../internals/hide');

module.exports = function (target, key, value, options) {
if (options && options.enumerable) target[key] = value;
else hide(target, key, value);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
1 change: 1 addition & 0 deletions packages/core-js-pure/override/modules/web.url.to-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
4 changes: 4 additions & 0 deletions packages/core-js/features/url-search-params/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require('../../modules/web.url-search-params');
require('../../modules/web.url-search-params.sort');

module.exports = require('../../internals/path').URLSearchParams;
1 change: 1 addition & 0 deletions packages/core-js/features/url-search-params/sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('../../modules/web.url-search-params.sort');
6 changes: 6 additions & 0 deletions packages/core-js/features/url/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require('../../modules/web.url');
require('../../modules/web.url.to-json');
require('../../modules/web.url-search-params');
require('../../modules/web.url-search-params.sort');

module.exports = require('../../internals/path').URL;
1 change: 1 addition & 0 deletions packages/core-js/features/url/to-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('../../modules/web.url.to-json');
4 changes: 4 additions & 0 deletions packages/core-js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,8 @@ require('./modules/web.dom-collections.iterator');
require('./modules/web.immediate');
require('./modules/web.queue-microtask');
require('./modules/web.timers');
require('./modules/web.url');
require('./modules/web.url.to-json');
require('./modules/web.url-search-params');
require('./modules/web.url-search-params.sort');
module.exports = require('./internals/path');
Loading