fixed where updating the search wouldn't keep the new order of how they are added

pull/11774/head
godzylinux 2 years ago
parent 850d285e40
commit 852205144b

@ -2,27 +2,28 @@ import { make_reactive } from './utils.js';
export const ReactiveURLSearchParams = make_reactive(URLSearchParams, { export const ReactiveURLSearchParams = make_reactive(URLSearchParams, {
write_properties: ['append', 'delete', 'set', 'sort'], write_properties: ['append', 'delete', 'set', 'sort'],
read_properties: ['get', 'has'], read_properties: ['get', 'has', 'getAll'],
interceptors: { interceptors: {
set: (notify_read_properties, value, property, ...params) => { set: (notify_read_properties, value, property, ...params) => {
if (typeof params[0] == 'string' && value.get(params[0]) === params[1]) { if (typeof params[0] == 'string' && value.get(params[0]) === params[1]) {
return false; return false;
} }
notify_read_properties(['get', 'has'], params[0]); notify_read_properties(['get', 'has', 'getAll'], params[0]);
return true; return true;
}, },
append: (notify_read_properties, value, property, ...params) => { append: (notify_read_properties, value, property, ...params) => {
if (typeof params[0] == 'string' && value.get(params[0]) === params[1]) { notify_read_properties(['getAll'], params[0]);
return false;
if (typeof params[0] == 'string' && !value.has(params[0])) {
notify_read_properties(['get', 'has'], params[0]);
} }
notify_read_properties(['get', 'has'], params[0]);
return true; return true;
}, },
delete: (notify_read_properties, value, property, ...params) => { delete: (notify_read_properties, value, property, ...params) => {
if (typeof params[0] == 'string' && !value.has(params[0])) { if (typeof params[0] == 'string' && !value.has(params[0])) {
return false; return false;
} }
notify_read_properties(['get', 'has'], params[0]); notify_read_properties(['get', 'has', 'getAll'], params[0]);
return true; return true;
} }
} }

@ -113,3 +113,39 @@ test('URLSearchParams.get', () => {
cleanup(); cleanup();
}); });
test('URLSearchParams.getAll', () => {
const params = new ReactiveURLSearchParams('a=b&c=d');
const log: any = [];
const cleanup = effect_root(() => {
render_effect(() => {
log.push(params.get('a'));
});
render_effect(() => {
log.push(params.get('c'));
});
render_effect(() => {
log.push(params.get('q'));
});
render_effect(() => {
log.push(params.getAll('a'));
});
render_effect(() => {
log.push(params.getAll('q'));
});
});
flushSync(() => {
// this shouldn't affect params.get(a) because it already exists
params.append('a', 'b1');
});
flushSync(() => {
params.append('q', 'z');
});
assert.deepEqual(log, ['b', 'd', null, ['b'], [], ['b', 'b1'], 'z', ['z']]);
cleanup();
});

@ -1,3 +1,4 @@
import { untrack } from '../index-client.js';
import { ReactiveURLSearchParams } from './url-search-params.js'; import { ReactiveURLSearchParams } from './url-search-params.js';
import { make_reactive } from './utils.js'; import { make_reactive } from './utils.js';
@ -71,21 +72,44 @@ class URLWithReactiveSearchParams extends URL {
} }
if (url_updated) { if (url_updated) {
Array.from(this.searchParams.keys()).forEach((key) => { this.#update_search_params_from_url();
// remove keys that don't exist anymore
if (!super.searchParams.has(key)) {
this.searchParams.delete(key);
}
});
for (const key of super.searchParams.keys()) {
// set/update keys
this.searchParams.set(key, /** @type {string} */ (super.searchParams.get(key)));
}
} else if (search_params_updated) { } else if (search_params_updated) {
// updating url from params
this.search = this.searchParams.toString(); this.search = this.searchParams.toString();
} }
} }
#update_search_params_from_url() {
/**
* keeping track of this is required because we have to keep the order in which they are updated
* @type {string[]}
*/
const keys_with_no_change = [];
// remove keys that don't exist anymore and notify others
for (const [key, value] of Array.from(this.searchParams.entries())) {
if (!super.searchParams.has(key) || value == super.searchParams.get(key)) {
keys_with_no_change.push(key);
untrack(() => {
this.searchParams.delete(key);
});
continue;
}
this.searchParams.delete(key);
}
// set or update keys based on the params
for (const [key, value] of super.searchParams.entries()) {
if (keys_with_no_change.includes(key)) {
untrack(() => {
this.searchParams.set(key, value);
});
continue;
}
this.searchParams.set(key, value);
}
}
/** /**
* @override * @override
*/ */

@ -67,7 +67,6 @@ test('url.searchParams', () => {
'foo: baz', 'foo: baz',
'q: true', 'q: true',
'search: ?q=kit&foo=baz&foo=qux', 'search: ?q=kit&foo=baz&foo=qux',
'foo: baz',
'search: ?q=kit', 'search: ?q=kit',
'foo: null' 'foo: null'
]); ]);

Loading…
Cancel
Save