1 | 'use strict';
|
2 |
|
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 |
|
204 |
|
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 |
|
216 |
|
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 |
|
225 |
|
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 |
|
245 |
|
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 |
|
257 |
|
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 |
|
270 |
|
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 |
|
285 |
|
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 |
|
310 |
|
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 |
|
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 |
|
330 | keys: function keys() {
|
331 | return new URLSearchParamsIterator(this, 'keys');
|
332 | },
|
333 |
|
334 | values: function values() {
|
335 | return new URLSearchParamsIterator(this, 'values');
|
336 | },
|
337 |
|
338 | entries: function entries() {
|
339 | return new URLSearchParamsIterator(this, 'entries');
|
340 | }
|
341 | }, { enumerable: true });
|
342 |
|
343 |
|
344 | defineBuiltIn(URLSearchParamsPrototype, ITERATOR, URLSearchParamsPrototype.entries, { name: 'entries' });
|
345 |
|
346 |
|
347 |
|
348 | defineBuiltIn(URLSearchParamsPrototype, 'toString', function toString() {
|
349 | return getInternalParamsState(this).serialize();
|
350 | }, { enumerable: true });
|
351 |
|
352 |
|
353 |
|
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 |
|
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 | };
|