diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 4091c474..1515c7f2 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -128,3 +128,12 @@ export const createElementFromConstructor = ( : doc.createElement(htmlConstructorTags[tag] || tag); } }; + +export const isValidUrl = (url: any): boolean => { + try { + new URL(url); + return true; + } catch (_) { + return false; + } +} diff --git a/src/lib/web-worker/worker-anchor.ts b/src/lib/web-worker/worker-anchor.ts index 548c174c..337ff510 100644 --- a/src/lib/web-worker/worker-anchor.ts +++ b/src/lib/web-worker/worker-anchor.ts @@ -1,5 +1,5 @@ import { commaSplit } from './worker-constants'; -import { definePrototypePropertyDescriptor } from '../utils'; +import { definePrototypePropertyDescriptor, isValidUrl } from '../utils'; import { getInstanceStateValue, setInstanceStateValue } from './worker-state'; import { getter, setter } from './worker-proxy'; import { resolveToUrl } from './worker-exec'; @@ -24,10 +24,20 @@ export const patchHTMLAnchorElement = (WorkerHTMLAnchorElement: any, env: WebWor }, set(this: any, value) { - let href = getInstanceStateValue(this, StateProp.url); - let url: any = resolveToUrl(env, href); - - url[anchorProp] = new URL(value + '', url.href); + let url; + + if (anchorProp === 'href') { + if (isValidUrl(value)) { + url = new URL(value); + } else { + const baseHref = env.$location$.href + url = resolveToUrl(env, baseHref); + url.href = new URL(value + '', url.href); + } + } else { + url = resolveToUrl(env, this.href); + url[anchorProp] = value; + } setInstanceStateValue(this, StateProp.url, url.href); diff --git a/tests/platform/anchor/anchor.spec.ts b/tests/platform/anchor/anchor.spec.ts index 3d61f18d..901c3964 100644 --- a/tests/platform/anchor/anchor.spec.ts +++ b/tests/platform/anchor/anchor.spec.ts @@ -30,4 +30,22 @@ test('anchor', async ({ page }) => { await page.waitForSelector('.testSetHref'); const testSetHref = page.locator('#testSetHref'); await expect(testSetHref).toHaveText('/pathname'); + + await page.waitForSelector('.testSetHref2'); + const testSetHref2 = page.locator('#testSetHref2'); + const desiredLocalUrl = new URL(page.url()); + desiredLocalUrl.pathname = '/local-pathname' + await expect(testSetHref2).toHaveText(desiredLocalUrl.toString()); + + await page.waitForSelector('.testGetSearch'); + const testGetSearch = page.locator('#testGetSearch'); + await expect(testGetSearch).toHaveText('?a=42&b=23'); + const testGetSearchHref = page.locator('#testGetSearchHref'); + await expect(testGetSearchHref).toHaveText('https://builder.io/?a=42&b=23'); + + await page.waitForSelector('.testSetSearch'); + const testSetSearch = page.locator('#testSetSearch'); + await expect(testSetSearch).toHaveText('?x=1&y=2'); + const testSetSearchHref = page.locator('#testSetSearchHref'); + await expect(testSetSearchHref).toHaveText('https://builder.io/?x=1&y=2'); }); diff --git a/tests/platform/anchor/index.html b/tests/platform/anchor/index.html index 94adeb8d..d804d7d5 100644 --- a/tests/platform/anchor/index.html +++ b/tests/platform/anchor/index.html @@ -75,7 +75,7 @@