making URL aware of SvelteURLSearchParams changes so they are in sync

pull/12285/head
FoHoOV 2 years ago
parent 1bfe90707d
commit 78dd49a0a2

@ -3,9 +3,14 @@ import { get } from '../internal/client/runtime.js';
import { increment } from './utils.js';
export const REPLACE = Symbol();
export const onChange = Symbol();
export class SvelteURLSearchParams extends URLSearchParams {
#version = source(0);
/**
* @type {((command: "set" | "append" | "delete" | "sort", ...args: any[])=>void ) | null}
*/
[onChange] = null;
/**
* @param {URLSearchParams} params
@ -28,8 +33,10 @@ export class SvelteURLSearchParams extends URLSearchParams {
* @returns {void}
*/
append(name, value) {
var res = super.append(name, value);
increment(this.#version);
return super.append(name, value);
this[onChange]?.('append', name, value);
return res;
}
/**
@ -42,6 +49,7 @@ export class SvelteURLSearchParams extends URLSearchParams {
var res = super.delete(name, value);
if (has_value) {
increment(this.#version);
this[onChange]?.('delete', name, value);
}
return res;
}
@ -91,12 +99,14 @@ export class SvelteURLSearchParams extends URLSearchParams {
// if you set `foo` to 1, then foo=3 gets deleted whilst `has("foo", "1")` returns true
if (value_before_change !== super.getAll(name).join('')) {
increment(this.#version);
this[onChange]?.('set', name, value);
}
}
sort() {
var res = super.sort();
increment(this.#version);
this[onChange]?.('sort');
return res;
}

@ -1,6 +1,6 @@
import { source, set } from '../internal/client/reactivity/sources.js';
import { get } from '../internal/client/runtime.js';
import { REPLACE, SvelteURLSearchParams } from './url-search-params.js';
import { onChange, REPLACE, SvelteURLSearchParams } from './url-search-params.js';
export class SvelteURL extends URL {
#protocol = source(super.protocol);
@ -20,6 +20,11 @@ export class SvelteURL extends URL {
url = new URL(url, base);
super(url);
this.#searchParams[REPLACE](url.searchParams);
this.#searchParams[onChange] = (command, ...args) => {
// by doing this, we sync SvelteSearchParams with internal implementation of URL.searchParams
// @ts-ignore
super.searchParams[command](...args);
};
}
get hash() {

@ -4,7 +4,7 @@ import { SvelteURL } from './url.js';
import { assert, test } from 'vitest';
test('url.hash', () => {
const url = new SvelteURL('http://google.com');
const url = new SvelteURL('https://svelte.dev');
const log: any = [];
const cleanup = effect_root(() => {
@ -18,7 +18,7 @@ test('url.hash', () => {
});
flushSync(() => {
url.href = 'http://google.com/a/b/c#def';
url.href = 'https://svelte.dev/a/b/c#def';
});
flushSync(() => {
@ -31,6 +31,44 @@ test('url.hash', () => {
cleanup();
});
test('url.href', () => {
const url = new SvelteURL('https://svelte.dev?foo=bar&t=123');
const log: any = [];
const cleanup = effect_root(() => {
render_effect(() => {
log.push(url.href);
});
});
flushSync(() => {
url.search = '?q=kit&foo=baz';
});
flushSync(() => {
// changes from searchParams should be synced to URL instance as well
url.searchParams.append('foo', 'qux');
});
flushSync(() => {
url.searchParams.delete('foo');
});
flushSync(() => {
url.searchParams.set('love', 'svelte5');
});
assert.deepEqual(log, [
'https://svelte.dev/?foo=bar&t=123',
'https://svelte.dev/?q=kit&foo=baz',
'https://svelte.dev/?q=kit&foo=baz&foo=qux',
'https://svelte.dev/?q=kit',
'https://svelte.dev/?q=kit&love=svelte5'
]);
cleanup();
});
test('url.searchParams', () => {
const url = new SvelteURL('https://svelte.dev?foo=bar&t=123');
const log: any = [];
@ -76,3 +114,7 @@ test('url.searchParams', () => {
cleanup();
});
test('URL.instanceOf', () => {
assert.equal(new SvelteURL('https://svelte.dev') instanceof URL, true);
});

@ -30,9 +30,9 @@ export default defineConfig({
dir: '.',
reporters: ['dot'],
include: [
'packages/svelte/**/*.test.ts'
// 'packages/svelte/tests/*/test.ts',
// 'packages/svelte/tests/runtime-browser/test-ssr.ts'
'packages/svelte/**/*.test.ts',
'packages/svelte/tests/*/test.ts',
'packages/svelte/tests/runtime-browser/test-ssr.ts'
],
exclude: [...configDefaults.exclude, '**/samples/**'],
coverage: {

Loading…
Cancel
Save