[d24f17c] | 1 | 'use strict';
|
---|
| 2 | // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`
|
---|
| 3 | require('../modules/es.array.iterator');
|
---|
| 4 | var $ = require('../internals/export');
|
---|
| 5 | var global = require('../internals/global');
|
---|
| 6 | var safeGetBuiltIn = require('../internals/safe-get-built-in');
|
---|
| 7 | var call = require('../internals/function-call');
|
---|
| 8 | var uncurryThis = require('../internals/function-uncurry-this');
|
---|
| 9 | var DESCRIPTORS = require('../internals/descriptors');
|
---|
| 10 | var USE_NATIVE_URL = require('../internals/url-constructor-detection');
|
---|
| 11 | var defineBuiltIn = require('../internals/define-built-in');
|
---|
| 12 | var defineBuiltInAccessor = require('../internals/define-built-in-accessor');
|
---|
| 13 | var defineBuiltIns = require('../internals/define-built-ins');
|
---|
| 14 | var setToStringTag = require('../internals/set-to-string-tag');
|
---|
| 15 | var createIteratorConstructor = require('../internals/iterator-create-constructor');
|
---|
| 16 | var InternalStateModule = require('../internals/internal-state');
|
---|
| 17 | var anInstance = require('../internals/an-instance');
|
---|
| 18 | var isCallable = require('../internals/is-callable');
|
---|
| 19 | var hasOwn = require('../internals/has-own-property');
|
---|
| 20 | var bind = require('../internals/function-bind-context');
|
---|
| 21 | var classof = require('../internals/classof');
|
---|
| 22 | var anObject = require('../internals/an-object');
|
---|
| 23 | var isObject = require('../internals/is-object');
|
---|
| 24 | var $toString = require('../internals/to-string');
|
---|
| 25 | var create = require('../internals/object-create');
|
---|
| 26 | var createPropertyDescriptor = require('../internals/create-property-descriptor');
|
---|
| 27 | var getIterator = require('../internals/get-iterator');
|
---|
| 28 | var getIteratorMethod = require('../internals/get-iterator-method');
|
---|
| 29 | var createIterResultObject = require('../internals/create-iter-result-object');
|
---|
| 30 | var validateArgumentsLength = require('../internals/validate-arguments-length');
|
---|
| 31 | var wellKnownSymbol = require('../internals/well-known-symbol');
|
---|
| 32 | var arraySort = require('../internals/array-sort');
|
---|
| 33 |
|
---|
| 34 | var ITERATOR = wellKnownSymbol('iterator');
|
---|
| 35 | var URL_SEARCH_PARAMS = 'URLSearchParams';
|
---|
| 36 | var URL_SEARCH_PARAMS_ITERATOR = URL_SEARCH_PARAMS + 'Iterator';
|
---|
| 37 | var setInternalState = InternalStateModule.set;
|
---|
| 38 | var getInternalParamsState = InternalStateModule.getterFor(URL_SEARCH_PARAMS);
|
---|
| 39 | var getInternalIteratorState = InternalStateModule.getterFor(URL_SEARCH_PARAMS_ITERATOR);
|
---|
| 40 |
|
---|
| 41 | var nativeFetch = safeGetBuiltIn('fetch');
|
---|
| 42 | var NativeRequest = safeGetBuiltIn('Request');
|
---|
| 43 | var Headers = safeGetBuiltIn('Headers');
|
---|
| 44 | var RequestPrototype = NativeRequest && NativeRequest.prototype;
|
---|
| 45 | var HeadersPrototype = Headers && Headers.prototype;
|
---|
| 46 | var RegExp = global.RegExp;
|
---|
| 47 | var TypeError = global.TypeError;
|
---|
| 48 | var decodeURIComponent = global.decodeURIComponent;
|
---|
| 49 | var encodeURIComponent = global.encodeURIComponent;
|
---|
| 50 | var charAt = uncurryThis(''.charAt);
|
---|
| 51 | var join = uncurryThis([].join);
|
---|
| 52 | var push = uncurryThis([].push);
|
---|
| 53 | var replace = uncurryThis(''.replace);
|
---|
| 54 | var shift = uncurryThis([].shift);
|
---|
| 55 | var splice = uncurryThis([].splice);
|
---|
| 56 | var split = uncurryThis(''.split);
|
---|
| 57 | var stringSlice = uncurryThis(''.slice);
|
---|
| 58 |
|
---|
| 59 | var plus = /\+/g;
|
---|
| 60 | var sequences = Array(4);
|
---|
| 61 |
|
---|
| 62 | var percentSequence = function (bytes) {
|
---|
| 63 | return sequences[bytes - 1] || (sequences[bytes - 1] = RegExp('((?:%[\\da-f]{2}){' + bytes + '})', 'gi'));
|
---|
| 64 | };
|
---|
| 65 |
|
---|
| 66 | var percentDecode = function (sequence) {
|
---|
| 67 | try {
|
---|
| 68 | return decodeURIComponent(sequence);
|
---|
| 69 | } catch (error) {
|
---|
| 70 | return sequence;
|
---|
| 71 | }
|
---|
| 72 | };
|
---|
| 73 |
|
---|
| 74 | var deserialize = function (it) {
|
---|
| 75 | var result = replace(it, plus, ' ');
|
---|
| 76 | var bytes = 4;
|
---|
| 77 | try {
|
---|
| 78 | return decodeURIComponent(result);
|
---|
| 79 | } catch (error) {
|
---|
| 80 | while (bytes) {
|
---|
| 81 | result = replace(result, percentSequence(bytes--), percentDecode);
|
---|
| 82 | }
|
---|
| 83 | return result;
|
---|
| 84 | }
|
---|
| 85 | };
|
---|
| 86 |
|
---|
| 87 | var find = /[!'()~]|%20/g;
|
---|
| 88 |
|
---|
| 89 | var replacements = {
|
---|
| 90 | '!': '%21',
|
---|
| 91 | "'": '%27',
|
---|
| 92 | '(': '%28',
|
---|
| 93 | ')': '%29',
|
---|
| 94 | '~': '%7E',
|
---|
| 95 | '%20': '+'
|
---|
| 96 | };
|
---|
| 97 |
|
---|
| 98 | var replacer = function (match) {
|
---|
| 99 | return replacements[match];
|
---|
| 100 | };
|
---|
| 101 |
|
---|
| 102 | var serialize = function (it) {
|
---|
| 103 | return replace(encodeURIComponent(it), find, replacer);
|
---|
| 104 | };
|
---|
| 105 |
|
---|
| 106 | var URLSearchParamsIterator = createIteratorConstructor(function Iterator(params, kind) {
|
---|
| 107 | setInternalState(this, {
|
---|
| 108 | type: URL_SEARCH_PARAMS_ITERATOR,
|
---|
| 109 | target: getInternalParamsState(params).entries,
|
---|
| 110 | index: 0,
|
---|
| 111 | kind: kind
|
---|
| 112 | });
|
---|
| 113 | }, URL_SEARCH_PARAMS, function next() {
|
---|
| 114 | var state = getInternalIteratorState(this);
|
---|
| 115 | var target = state.target;
|
---|
| 116 | var index = state.index++;
|
---|
| 117 | if (!target || index >= target.length) {
|
---|
| 118 | state.target = undefined;
|
---|
| 119 | return createIterResultObject(undefined, true);
|
---|
| 120 | }
|
---|
| 121 | var entry = target[index];
|
---|
| 122 | switch (state.kind) {
|
---|
| 123 | case 'keys': return createIterResultObject(entry.key, false);
|
---|
| 124 | case 'values': return createIterResultObject(entry.value, false);
|
---|
| 125 | } return createIterResultObject([entry.key, entry.value], false);
|
---|
| 126 | }, true);
|
---|
| 127 |
|
---|
| 128 | var URLSearchParamsState = function (init) {
|
---|
| 129 | this.entries = [];
|
---|
| 130 | this.url = null;
|
---|
| 131 |
|
---|
| 132 | if (init !== undefined) {
|
---|
| 133 | if (isObject(init)) this.parseObject(init);
|
---|
| 134 | else this.parseQuery(typeof init == 'string' ? charAt(init, 0) === '?' ? stringSlice(init, 1) : init : $toString(init));
|
---|
| 135 | }
|
---|
| 136 | };
|
---|
| 137 |
|
---|
| 138 | URLSearchParamsState.prototype = {
|
---|
| 139 | type: URL_SEARCH_PARAMS,
|
---|
| 140 | bindURL: function (url) {
|
---|
| 141 | this.url = url;
|
---|
| 142 | this.update();
|
---|
| 143 | },
|
---|
| 144 | parseObject: function (object) {
|
---|
| 145 | var entries = this.entries;
|
---|
| 146 | var iteratorMethod = getIteratorMethod(object);
|
---|
| 147 | var iterator, next, step, entryIterator, entryNext, first, second;
|
---|
| 148 |
|
---|
| 149 | if (iteratorMethod) {
|
---|
| 150 | iterator = getIterator(object, iteratorMethod);
|
---|
| 151 | next = iterator.next;
|
---|
| 152 | while (!(step = call(next, iterator)).done) {
|
---|
| 153 | entryIterator = getIterator(anObject(step.value));
|
---|
| 154 | entryNext = entryIterator.next;
|
---|
| 155 | if (
|
---|
| 156 | (first = call(entryNext, entryIterator)).done ||
|
---|
| 157 | (second = call(entryNext, entryIterator)).done ||
|
---|
| 158 | !call(entryNext, entryIterator).done
|
---|
| 159 | ) throw new TypeError('Expected sequence with length 2');
|
---|
| 160 | push(entries, { key: $toString(first.value), value: $toString(second.value) });
|
---|
| 161 | }
|
---|
| 162 | } else for (var key in object) if (hasOwn(object, key)) {
|
---|
| 163 | push(entries, { key: key, value: $toString(object[key]) });
|
---|
| 164 | }
|
---|
| 165 | },
|
---|
| 166 | parseQuery: function (query) {
|
---|
| 167 | if (query) {
|
---|
| 168 | var entries = this.entries;
|
---|
| 169 | var attributes = split(query, '&');
|
---|
| 170 | var index = 0;
|
---|
| 171 | var attribute, entry;
|
---|
| 172 | while (index < attributes.length) {
|
---|
| 173 | attribute = attributes[index++];
|
---|
| 174 | if (attribute.length) {
|
---|
| 175 | entry = split(attribute, '=');
|
---|
| 176 | push(entries, {
|
---|
| 177 | key: deserialize(shift(entry)),
|
---|
| 178 | value: deserialize(join(entry, '='))
|
---|
| 179 | });
|
---|
| 180 | }
|
---|
| 181 | }
|
---|
| 182 | }
|
---|
| 183 | },
|
---|
| 184 | serialize: function () {
|
---|
| 185 | var entries = this.entries;
|
---|
| 186 | var result = [];
|
---|
| 187 | var index = 0;
|
---|
| 188 | var entry;
|
---|
| 189 | while (index < entries.length) {
|
---|
| 190 | entry = entries[index++];
|
---|
| 191 | push(result, serialize(entry.key) + '=' + serialize(entry.value));
|
---|
| 192 | } return join(result, '&');
|
---|
| 193 | },
|
---|
| 194 | update: function () {
|
---|
| 195 | this.entries.length = 0;
|
---|
| 196 | this.parseQuery(this.url.query);
|
---|
| 197 | },
|
---|
| 198 | updateURL: function () {
|
---|
| 199 | if (this.url) this.url.update();
|
---|
| 200 | }
|
---|
| 201 | };
|
---|
| 202 |
|
---|
| 203 | // `URLSearchParams` constructor
|
---|
| 204 | // https://url.spec.whatwg.org/#interface-urlsearchparams
|
---|
| 205 | var URLSearchParamsConstructor = function URLSearchParams(/* init */) {
|
---|
| 206 | anInstance(this, URLSearchParamsPrototype);
|
---|
| 207 | var init = arguments.length > 0 ? arguments[0] : undefined;
|
---|
| 208 | var state = setInternalState(this, new URLSearchParamsState(init));
|
---|
| 209 | if (!DESCRIPTORS) this.size = state.entries.length;
|
---|
| 210 | };
|
---|
| 211 |
|
---|
| 212 | var URLSearchParamsPrototype = URLSearchParamsConstructor.prototype;
|
---|
| 213 |
|
---|
| 214 | defineBuiltIns(URLSearchParamsPrototype, {
|
---|
| 215 | // `URLSearchParams.prototype.append` method
|
---|
| 216 | // https://url.spec.whatwg.org/#dom-urlsearchparams-append
|
---|
| 217 | append: function append(name, value) {
|
---|
| 218 | var state = getInternalParamsState(this);
|
---|
| 219 | validateArgumentsLength(arguments.length, 2);
|
---|
| 220 | push(state.entries, { key: $toString(name), value: $toString(value) });
|
---|
| 221 | if (!DESCRIPTORS) this.length++;
|
---|
| 222 | state.updateURL();
|
---|
| 223 | },
|
---|
| 224 | // `URLSearchParams.prototype.delete` method
|
---|
| 225 | // https://url.spec.whatwg.org/#dom-urlsearchparams-delete
|
---|
| 226 | 'delete': function (name /* , value */) {
|
---|
| 227 | var state = getInternalParamsState(this);
|
---|
| 228 | var length = validateArgumentsLength(arguments.length, 1);
|
---|
| 229 | var entries = state.entries;
|
---|
| 230 | var key = $toString(name);
|
---|
| 231 | var $value = length < 2 ? undefined : arguments[1];
|
---|
| 232 | var value = $value === undefined ? $value : $toString($value);
|
---|
| 233 | var index = 0;
|
---|
| 234 | while (index < entries.length) {
|
---|
| 235 | var entry = entries[index];
|
---|
| 236 | if (entry.key === key && (value === undefined || entry.value === value)) {
|
---|
| 237 | splice(entries, index, 1);
|
---|
| 238 | if (value !== undefined) break;
|
---|
| 239 | } else index++;
|
---|
| 240 | }
|
---|
| 241 | if (!DESCRIPTORS) this.size = entries.length;
|
---|
| 242 | state.updateURL();
|
---|
| 243 | },
|
---|
| 244 | // `URLSearchParams.prototype.get` method
|
---|
| 245 | // https://url.spec.whatwg.org/#dom-urlsearchparams-get
|
---|
| 246 | get: function get(name) {
|
---|
| 247 | var entries = getInternalParamsState(this).entries;
|
---|
| 248 | validateArgumentsLength(arguments.length, 1);
|
---|
| 249 | var key = $toString(name);
|
---|
| 250 | var index = 0;
|
---|
| 251 | for (; index < entries.length; index++) {
|
---|
| 252 | if (entries[index].key === key) return entries[index].value;
|
---|
| 253 | }
|
---|
| 254 | return null;
|
---|
| 255 | },
|
---|
| 256 | // `URLSearchParams.prototype.getAll` method
|
---|
| 257 | // https://url.spec.whatwg.org/#dom-urlsearchparams-getall
|
---|
| 258 | getAll: function getAll(name) {
|
---|
| 259 | var entries = getInternalParamsState(this).entries;
|
---|
| 260 | validateArgumentsLength(arguments.length, 1);
|
---|
| 261 | var key = $toString(name);
|
---|
| 262 | var result = [];
|
---|
| 263 | var index = 0;
|
---|
| 264 | for (; index < entries.length; index++) {
|
---|
| 265 | if (entries[index].key === key) push(result, entries[index].value);
|
---|
| 266 | }
|
---|
| 267 | return result;
|
---|
| 268 | },
|
---|
| 269 | // `URLSearchParams.prototype.has` method
|
---|
| 270 | // https://url.spec.whatwg.org/#dom-urlsearchparams-has
|
---|
| 271 | has: function has(name /* , value */) {
|
---|
| 272 | var entries = getInternalParamsState(this).entries;
|
---|
| 273 | var length = validateArgumentsLength(arguments.length, 1);
|
---|
| 274 | var key = $toString(name);
|
---|
| 275 | var $value = length < 2 ? undefined : arguments[1];
|
---|
| 276 | var value = $value === undefined ? $value : $toString($value);
|
---|
| 277 | var index = 0;
|
---|
| 278 | while (index < entries.length) {
|
---|
| 279 | var entry = entries[index++];
|
---|
| 280 | if (entry.key === key && (value === undefined || entry.value === value)) return true;
|
---|
| 281 | }
|
---|
| 282 | return false;
|
---|
| 283 | },
|
---|
| 284 | // `URLSearchParams.prototype.set` method
|
---|
| 285 | // https://url.spec.whatwg.org/#dom-urlsearchparams-set
|
---|
| 286 | set: function set(name, value) {
|
---|
| 287 | var state = getInternalParamsState(this);
|
---|
| 288 | validateArgumentsLength(arguments.length, 1);
|
---|
| 289 | var entries = state.entries;
|
---|
| 290 | var found = false;
|
---|
| 291 | var key = $toString(name);
|
---|
| 292 | var val = $toString(value);
|
---|
| 293 | var index = 0;
|
---|
| 294 | var entry;
|
---|
| 295 | for (; index < entries.length; index++) {
|
---|
| 296 | entry = entries[index];
|
---|
| 297 | if (entry.key === key) {
|
---|
| 298 | if (found) splice(entries, index--, 1);
|
---|
| 299 | else {
|
---|
| 300 | found = true;
|
---|
| 301 | entry.value = val;
|
---|
| 302 | }
|
---|
| 303 | }
|
---|
| 304 | }
|
---|
| 305 | if (!found) push(entries, { key: key, value: val });
|
---|
| 306 | if (!DESCRIPTORS) this.size = entries.length;
|
---|
| 307 | state.updateURL();
|
---|
| 308 | },
|
---|
| 309 | // `URLSearchParams.prototype.sort` method
|
---|
| 310 | // https://url.spec.whatwg.org/#dom-urlsearchparams-sort
|
---|
| 311 | sort: function sort() {
|
---|
| 312 | var state = getInternalParamsState(this);
|
---|
| 313 | arraySort(state.entries, function (a, b) {
|
---|
| 314 | return a.key > b.key ? 1 : -1;
|
---|
| 315 | });
|
---|
| 316 | state.updateURL();
|
---|
| 317 | },
|
---|
| 318 | // `URLSearchParams.prototype.forEach` method
|
---|
| 319 | forEach: function forEach(callback /* , thisArg */) {
|
---|
| 320 | var entries = getInternalParamsState(this).entries;
|
---|
| 321 | var boundFunction = bind(callback, arguments.length > 1 ? arguments[1] : undefined);
|
---|
| 322 | var index = 0;
|
---|
| 323 | var entry;
|
---|
| 324 | while (index < entries.length) {
|
---|
| 325 | entry = entries[index++];
|
---|
| 326 | boundFunction(entry.value, entry.key, this);
|
---|
| 327 | }
|
---|
| 328 | },
|
---|
| 329 | // `URLSearchParams.prototype.keys` method
|
---|
| 330 | keys: function keys() {
|
---|
| 331 | return new URLSearchParamsIterator(this, 'keys');
|
---|
| 332 | },
|
---|
| 333 | // `URLSearchParams.prototype.values` method
|
---|
| 334 | values: function values() {
|
---|
| 335 | return new URLSearchParamsIterator(this, 'values');
|
---|
| 336 | },
|
---|
| 337 | // `URLSearchParams.prototype.entries` method
|
---|
| 338 | entries: function entries() {
|
---|
| 339 | return new URLSearchParamsIterator(this, 'entries');
|
---|
| 340 | }
|
---|
| 341 | }, { enumerable: true });
|
---|
| 342 |
|
---|
| 343 | // `URLSearchParams.prototype[@@iterator]` method
|
---|
| 344 | defineBuiltIn(URLSearchParamsPrototype, ITERATOR, URLSearchParamsPrototype.entries, { name: 'entries' });
|
---|
| 345 |
|
---|
| 346 | // `URLSearchParams.prototype.toString` method
|
---|
| 347 | // https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior
|
---|
| 348 | defineBuiltIn(URLSearchParamsPrototype, 'toString', function toString() {
|
---|
| 349 | return getInternalParamsState(this).serialize();
|
---|
| 350 | }, { enumerable: true });
|
---|
| 351 |
|
---|
| 352 | // `URLSearchParams.prototype.size` getter
|
---|
| 353 | // https://github.com/whatwg/url/pull/734
|
---|
| 354 | if (DESCRIPTORS) defineBuiltInAccessor(URLSearchParamsPrototype, 'size', {
|
---|
| 355 | get: function size() {
|
---|
| 356 | return getInternalParamsState(this).entries.length;
|
---|
| 357 | },
|
---|
| 358 | configurable: true,
|
---|
| 359 | enumerable: true
|
---|
| 360 | });
|
---|
| 361 |
|
---|
| 362 | setToStringTag(URLSearchParamsConstructor, URL_SEARCH_PARAMS);
|
---|
| 363 |
|
---|
| 364 | $({ global: true, constructor: true, forced: !USE_NATIVE_URL }, {
|
---|
| 365 | URLSearchParams: URLSearchParamsConstructor
|
---|
| 366 | });
|
---|
| 367 |
|
---|
| 368 | // Wrap `fetch` and `Request` for correct work with polyfilled `URLSearchParams`
|
---|
| 369 | if (!USE_NATIVE_URL && isCallable(Headers)) {
|
---|
| 370 | var headersHas = uncurryThis(HeadersPrototype.has);
|
---|
| 371 | var headersSet = uncurryThis(HeadersPrototype.set);
|
---|
| 372 |
|
---|
| 373 | var wrapRequestOptions = function (init) {
|
---|
| 374 | if (isObject(init)) {
|
---|
| 375 | var body = init.body;
|
---|
| 376 | var headers;
|
---|
| 377 | if (classof(body) === URL_SEARCH_PARAMS) {
|
---|
| 378 | headers = init.headers ? new Headers(init.headers) : new Headers();
|
---|
| 379 | if (!headersHas(headers, 'content-type')) {
|
---|
| 380 | headersSet(headers, 'content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
|
---|
| 381 | }
|
---|
| 382 | return create(init, {
|
---|
| 383 | body: createPropertyDescriptor(0, $toString(body)),
|
---|
| 384 | headers: createPropertyDescriptor(0, headers)
|
---|
| 385 | });
|
---|
| 386 | }
|
---|
| 387 | } return init;
|
---|
| 388 | };
|
---|
| 389 |
|
---|
| 390 | if (isCallable(nativeFetch)) {
|
---|
| 391 | $({ global: true, enumerable: true, dontCallGetSet: true, forced: true }, {
|
---|
| 392 | fetch: function fetch(input /* , init */) {
|
---|
| 393 | return nativeFetch(input, arguments.length > 1 ? wrapRequestOptions(arguments[1]) : {});
|
---|
| 394 | }
|
---|
| 395 | });
|
---|
| 396 | }
|
---|
| 397 |
|
---|
| 398 | if (isCallable(NativeRequest)) {
|
---|
| 399 | var RequestConstructor = function Request(input /* , init */) {
|
---|
| 400 | anInstance(this, RequestPrototype);
|
---|
| 401 | return new NativeRequest(input, arguments.length > 1 ? wrapRequestOptions(arguments[1]) : {});
|
---|
| 402 | };
|
---|
| 403 |
|
---|
| 404 | RequestPrototype.constructor = RequestConstructor;
|
---|
| 405 | RequestConstructor.prototype = RequestPrototype;
|
---|
| 406 |
|
---|
| 407 | $({ global: true, constructor: true, dontCallGetSet: true, forced: true }, {
|
---|
| 408 | Request: RequestConstructor
|
---|
| 409 | });
|
---|
| 410 | }
|
---|
| 411 | }
|
---|
| 412 |
|
---|
| 413 | module.exports = {
|
---|
| 414 | URLSearchParams: URLSearchParamsConstructor,
|
---|
| 415 | getState: getInternalParamsState
|
---|
| 416 | };
|
---|