Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
# Browsers we support
> 0.5%
Chrome >= 73
ChromeAndroid >= 75
Firefox >= 67
Edge >= 17
IE 11
Safari >= 12.1
iOS >= 11.3
iOS >= 16.7
last 2 versions
not dead
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"version": "node ./scripts/version.js",
"watch": "node ./scripts/watch.js"
},
"dependencies": {
"devDependencies": {
"@ampproject/filesize": "^4.3.0",
"@ampproject/rollup-plugin-closure-compiler": "0.27.0",
"@babel/core": "^7.15.0",
Expand Down
75 changes: 44 additions & 31 deletions packages/history/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,49 @@
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#action
*/
export enum Action {
export type Action =
/**
* A POP indicates a change to an arbitrary index in the history stack, such
* as a back or forward navigation. It does not describe the direction of the
* navigation, only that the current index changed.
*
* Note: This is the default action for newly created history objects.
*/
Pop = "POP",
| "POP"

/**
* A PUSH indicates a new entry being added to the history stack, such as when
* a link is clicked and a new page loads. When this happens, all subsequent
* entries in the stack are lost.
*/
Push = "PUSH",
| "PUSH"

/**
* A REPLACE indicates the entry at the current index in the history stack
* being replaced by a new one.
*/
Replace = "REPLACE",
}
| "REPLACE";

/**
* A URL pathname, beginning with a /.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.pathname
*/
export type Pathname = string;
export type Pathname = `/${string}`;

/**
* A URL search string, beginning with a ?.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.search
*/
export type Search = string;
export type Search = `?${string}` | '';

/**
* A URL fragment identifier, beginning with a #.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.hash
*/
export type Hash = string;
export type Hash = `#${string}` | '';

/**
* An object that is used to associate some arbitrary data with a location, but
Expand Down Expand Up @@ -91,6 +90,17 @@ export interface Path {
hash: Hash;
}

function normalizePathname(path: string): Pathname {
return path.startsWith('/') ? path as Pathname : `/${path}`;
}

function normalizeSearch(s: string): Search {
return s.startsWith('?') ? s as Search : '';
}

function normalizeHash(h: string): Hash {
return h.startsWith('#') ? h as Hash : '';
}
/**
* An entry in a history stack. A location contains information about the
* URL path, as well as possibly some arbitrary state and a key.
Expand Down Expand Up @@ -188,7 +198,7 @@ export type To = string | Partial<Path>;
export interface History {
/**
* The last action that modified the current location. This will always be
* Action.Pop when a history instance is first created. This value is mutable.
* 'POP' when a history instance is first created. This value is mutable.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#history.action
*/
Expand Down Expand Up @@ -373,9 +383,9 @@ export function createBrowserHistory(
return [
state.idx,
readOnly<Location>({
pathname,
search,
hash,
pathname: normalizePathname(pathname),
search: normalizeSearch(search),
hash: normalizeHash(hash),
state: state.usr || null,
key: state.key || "default",
}),
Expand All @@ -388,7 +398,7 @@ export function createBrowserHistory(
blockers.call(blockedPopTx);
blockedPopTx = null;
} else {
let nextAction = Action.Pop;
let nextAction: Action = "POP" as const;
let [nextIndex, nextLocation] = getIndexAndLocation();

if (blockers.length) {
Expand Down Expand Up @@ -429,7 +439,7 @@ export function createBrowserHistory(

window.addEventListener(PopStateEventType, handlePop);

let action = Action.Pop;
let action: Action = "POP";
let [index, location] = getIndexAndLocation();
let listeners = createEvents<Listener>();
let blockers = createEvents<Blocker>();
Expand Down Expand Up @@ -482,7 +492,7 @@ export function createBrowserHistory(
}

function push(to: To, state?: any) {
let nextAction = Action.Push;
let nextAction: Action = "PUSH" as const;
let nextLocation = getNextLocation(to, state);
function retry() {
push(to, state);
Expand All @@ -506,7 +516,7 @@ export function createBrowserHistory(
}

function replace(to: To, state?: any) {
let nextAction = Action.Replace;
let nextAction: Action = "REPLACE";
let nextLocation = getNextLocation(to, state);
function retry() {
replace(to, state);
Expand Down Expand Up @@ -594,7 +604,7 @@ export function createHashHistory(
pathname = "/",
search = "",
hash = "",
} = parsePath(window.location.hash.substr(1));
} = parsePath(window.location.hash.substring(1));
let state = globalHistory.state || {};
return [
state.idx,
Expand All @@ -614,7 +624,7 @@ export function createHashHistory(
blockers.call(blockedPopTx);
blockedPopTx = null;
} else {
let nextAction = Action.Pop;
let nextAction: Action = "POP";
let [nextIndex, nextLocation] = getIndexAndLocation();

if (blockers.length) {
Expand Down Expand Up @@ -666,7 +676,7 @@ export function createHashHistory(
}
});

let action = Action.Pop;
let action: Action = "POP";
let [index, location] = getIndexAndLocation();
let listeners = createEvents<Listener>();
let blockers = createEvents<Blocker>();
Expand Down Expand Up @@ -731,7 +741,7 @@ export function createHashHistory(
}

function push(to: To, state?: any) {
let nextAction = Action.Push;
let nextAction: Action = "PUSH";
let nextLocation = getNextLocation(to, state);
function retry() {
push(to, state);
Expand Down Expand Up @@ -762,7 +772,7 @@ export function createHashHistory(
}

function replace(to: To, state?: any) {
let nextAction = Action.Replace;
let nextAction: Action = "REPLACE";
let nextLocation = getNextLocation(to, state);
function retry() {
replace(to, state);
Expand Down Expand Up @@ -882,7 +892,7 @@ export function createMemoryHistory(
entries.length - 1
);

let action = Action.Pop;
let action: Action = "POP";
let location = entries[index];
let listeners = createEvents<Listener>();
let blockers = createEvents<Blocker>();
Expand Down Expand Up @@ -915,7 +925,7 @@ export function createMemoryHistory(
}

function push(to: To, state?: any) {
let nextAction = Action.Push;
let nextAction: Action = "PUSH";
let nextLocation = getNextLocation(to, state);
function retry() {
push(to, state);
Expand All @@ -936,7 +946,7 @@ export function createMemoryHistory(
}

function replace(to: To, state?: any) {
let nextAction = Action.Replace;
let nextAction: Action = "REPLACE";
let nextLocation = getNextLocation(to, state);
function retry() {
replace(to, state);
Expand All @@ -957,7 +967,7 @@ export function createMemoryHistory(

function go(delta: number) {
let nextIndex = clamp(index + delta, 0, entries.length - 1);
let nextAction = Action.Pop;
let nextAction: Action = "POP";
let nextLocation = entries[nextIndex];
function retry() {
go(delta);
Expand Down Expand Up @@ -1041,7 +1051,7 @@ function createEvents<F extends Function>(): Events<F> {
}

function createKey() {
return Math.random().toString(36).substr(2, 8);
return Math.random().toString(36).substring(2, 8);
}

/**
Expand Down Expand Up @@ -1072,18 +1082,21 @@ export function parsePath(path: string): Partial<Path> {
if (path) {
let hashIndex = path.indexOf("#");
if (hashIndex >= 0) {
parsedPath.hash = path.substr(hashIndex);
path = path.substr(0, hashIndex);
// FIXME: decent triming helper
parsedPath.hash = normalizeHash(path.substring(hashIndex));
path = path.substring(0, hashIndex);
}

let searchIndex = path.indexOf("?");
if (searchIndex >= 0) {
parsedPath.search = path.substr(searchIndex);
path = path.substr(0, searchIndex);
// FIXME: decent triming helper
parsedPath.search = normalizeSearch(path.substring(searchIndex));
path = path.substring(0, searchIndex);
}

if (path) {
parsedPath.pathname = path;
// FIXME:
parsedPath.pathname = normalizePathname(path);
}
}

Expand Down