diff --git a/src/lib/url_util.test.ts b/src/lib/url_util.test.ts index 4da29669..fb675d10 100644 --- a/src/lib/url_util.test.ts +++ b/src/lib/url_util.test.ts @@ -347,6 +347,21 @@ function test_url_graft_path() { function test_url_query_interpolation() { let cases = [ ["http://example.com/%s000", "a/query", "http://example.com/a%2Fquery000"], + [ + "https://%s1.wikipedia.org/wiki/%s2", + "en Tridactyl", + "https://en.wikipedia.org/wiki/Tridactyl", + ], + [ + "https://%s.wikipedia.org/wiki/Tridactyl", + "en", + "https://en.wikipedia.org/wiki/Tridactyl", + ], + [ + "https://%s[1:2].wikipedia.org/wiki/%s[2:]", + "en Main Page", + "https://en.wikipedia.org/wiki/Main%20Page", + ], [ // appended to the path "http://example.com", @@ -384,7 +399,7 @@ function test_url_query_interpolation() { ] for (let [url, qy, exp_res] of cases) { - let modified = UrlUtil.interpolateSearchItem(new URL(url), qy) + let modified = UrlUtil.interpolateSearchItem(url, qy) test(`interpolate ${qy} into ${url} --> ${exp_res}`, () => expect(modified.href).toEqual(exp_res)) @@ -396,7 +411,7 @@ test.each([ ["wiki", "https://example.com/wiki/", "an/article"], ])("convert an interpolated %s URL back to arguments", (engine, pattern, query) => { const searchurls = { [engine]: pattern } - const url = UrlUtil.interpolateSearchItem(new URL(pattern), query).href + const url = UrlUtil.interpolateSearchItem(pattern, query).href expect(UrlUtil.searchUrlToArgs(url, searchurls)).toEqual(`${engine} ${query}`) }) diff --git a/src/lib/url_util.ts b/src/lib/url_util.ts index 1150c365..0993c87e 100644 --- a/src/lib/url_util.ts +++ b/src/lib/url_util.ts @@ -441,14 +441,14 @@ export function searchUrlToArgs( * * The search item is percent encoded before it is inserted. * - * @param urlPattern a URL to interpolate/append a query to + * @param urlPattern a URL template to interpolate/append a query to * @param query a query to interpolate/append into the URL * * @return the URL with the query encoded and inserted at the * relevant point */ -export function interpolateSearchItem(urlPattern: URL, query: string): URL { - const hasInterpolationPoint = urlPattern.href.includes("%s") +export function interpolateSearchItem(urlPattern: string, query: string): URL { + const hasInterpolationPoint = urlPattern.includes("%s") let queryWords = query.split(" ") @@ -456,10 +456,10 @@ export function interpolateSearchItem(urlPattern: URL, query: string): URL { query = encodeURIComponent(query) queryWords = queryWords.map(w => encodeURIComponent(w)) - // replace or append as needed + // Interpolate before parsing so placeholders can appear in the hostname. if (hasInterpolationPoint) { - const resultingURL = new URL( - urlPattern.href + return new URL( + urlPattern .replace(/%s[1-9]\d*/g, function (x) { const index = parseInt(x.slice(2), 10) - 1 if (index >= queryWords.length) { @@ -476,12 +476,11 @@ export function interpolateSearchItem(urlPattern: URL, query: string): URL { ? queryWords.slice(start, l(parseInt(p2, 10))) : queryWords.slice(start) return slice.join(" ") - }), + }) + .replace("%s", query), ) - - return new URL(resultingURL.href.replace("%s", query)) } else { - return new URL(urlPattern.href + query) + return new URL(new URL(urlPattern).href + query) } } diff --git a/src/lib/webext.ts b/src/lib/webext.ts index c038703c..297fba0d 100644 --- a/src/lib/webext.ts +++ b/src/lib/webext.ts @@ -389,7 +389,7 @@ export async function queryAndURLwrangler( const searchurls = config.get("searchurls") const template = expandRecursively(firstWord, searchurls) if (template != firstWord) { - const url = UrlUtil.interpolateSearchItem(new URL(template), rest) + const url = UrlUtil.interpolateSearchItem(template, rest) // firstWord is a searchurl, so let's use that return url.href } @@ -445,7 +445,7 @@ export async function queryAndURLwrangler( if (enginename) { if (searchurls[enginename]) { const url = UrlUtil.interpolateSearchItem( - new URL(searchurls[enginename]), + searchurls[enginename], queryString, ) return url.href