Skip to content

Commit 2d4d23d

Browse files
authored
fix: Added more elaborate url normalization (#2)
Also adds kapeta query params to url - and strips them during normalization
1 parent a293fd2 commit 2d4d23d

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

src/core.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export const EVENT_HISTORY_STATE_CHANGED = 'history-state-changed';
2-
2+
export const QUERY_FRAGMENT = '_kap_fragment';
3+
export const QUERY_BASEPATH = '_kap_basepath';
34

45
function getBasePathForFrame(frame: Element) {
56
const basePath = frame.getAttribute('data-base-path');
@@ -69,9 +70,8 @@ export function replaceStateOnWindow(win: Window, path: string) {
6970
try {
7071
const currentPath = getFullPath(win);
7172
if (!isSamePath(currentPath, path)) {
72-
console.log('Replacing state on window: %s > %s', currentPath, path);
7373
// Only replace if the path has changed
74-
win.history.replaceState({}, '', path);
74+
win.history.replaceState({}, '', normalizePath(path));
7575
win.dispatchEvent(new CustomEvent(EVENT_HISTORY_STATE_CHANGED));
7676
}
7777
} catch (e) {
@@ -128,10 +128,26 @@ function syncLocationToChildFrames() {
128128
*/
129129

130130
function normalizePath(path: string) {
131-
if (path.endsWith('/')) {
132-
return path.substring(0, path.length - 1);
131+
let [pathname, searchpart] = path.split('?');
132+
let [search, hash] = searchpart?.split('#') || [];
133+
134+
if (pathname.endsWith('/')) {
135+
pathname = pathname.substring(0, path.length - 1);
136+
}
137+
let normalized = pathname;
138+
if (search) {
139+
const params = new URLSearchParams(search);
140+
params.delete(QUERY_BASEPATH);
141+
params.delete(QUERY_FRAGMENT);
142+
search = params.toString();
143+
if (search) {
144+
normalized += '?' + params.toString();
145+
}
133146
}
134-
return path;
147+
if (hash) {
148+
normalized += '#' + hash;
149+
}
150+
return normalized;
135151
}
136152

137153
function isSamePath(path1: string, path2: string) {
@@ -218,11 +234,11 @@ export function toFullPath(urlString: string) {
218234
}
219235
const url = new URL(urlString);
220236
let out = url.pathname;
221-
if (url.search) {
222-
out += '?' + url.search;
237+
if (url.search && url.search.length > 1) {
238+
out += url.search;
223239
}
224-
if (url.hash) {
225-
out += '#' + url.hash;
240+
if (url.hash && url.hash.length > 1) {
241+
out += url.hash;
226242
}
227243
return out;
228244
}

src/react-support/FragmentFrame.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { getBasePath, getFullPath, joinPaths, removePathPrefix } from '../core';
2+
import {getBasePath, getFullPath, joinPaths, QUERY_BASEPATH, QUERY_FRAGMENT, removePathPrefix} from '../core';
33

44
export interface FragmentProps extends React.IframeHTMLAttributes<HTMLIFrameElement> {
55
basePath: string;
@@ -9,7 +9,14 @@ export const FragmentFrame = (props: FragmentProps) => {
99
const basePath = joinPaths(getBasePath(), props.basePath);
1010
const mainFullPath = getFullPath();
1111
const localPath = removePathPrefix(mainFullPath, props.topPath);
12-
const src = joinPaths(basePath, localPath);
12+
let src = joinPaths(basePath, localPath);
13+
14+
if (src.indexOf('?') === -1) {
15+
src += '?';
16+
} else {
17+
src += '&';
18+
}
19+
src += `${QUERY_FRAGMENT}=true&${QUERY_BASEPATH}=${encodeURIComponent(basePath)}`;
1320

1421
const copyProps: any = { ...props };
1522
delete copyProps.basePath;

0 commit comments

Comments
 (0)