Module Html5_history

A quick overview of HTML5-History.

   Primitives
   ----------
   The primitives the browser provides to you are:

   - A stack of "history entries", which are tuples [(state, uri)] (strictly speaking
     they're three-tuples, but MDN says the "title" is completely ignored)
   - A function pushState that adds a new item to the stack with the given [(state, uri)]
   - A function replaceState that replaces the current top of stack with [(state, uri)]
   - A way of getting the current state and URI, particularly useful on initial page
     load.
   - An event you can listen to, popState, which fires whenever the user uses the
     browser's back/forwards button to move between two history states that were created
     by the same "page".

   When using pushState or replaceState, the string in the address bar immediately
   changes to be [uri] without a page navigation/load (the URI must be of the same origin
   as the current URI).

   MDN says the "state" can be "anything that can be serialised" (with some size limit,
   see [push_or_replace]); here we bin-prot your OCaml value and store the string (along
   with its bin-shape), so you needn't worry about that.

   See more here: https://developer.mozilla.org/en-US/docs/Web/API/History.

   Note that these primitives allow you to:

   1. add an entry to the history stack (with a URI and/or state blob inside it), without
   causing a page load
   2. handle the back button without a page load happening
   3. change the string in the address bar without causing a page load; in fact without
   the addition of a new entry on the history stack if you wish
   4. change the state blob inside the current history stack entry without adding a new
   entry or changing the string in the address bar

   For an example of why you might want to do (4), have a look at the comment by
   [History_state] below ("you may like to put more information in your [History_state.t]
   ...").
module type Payload = sig ... end

We let you store a "payload" in each of the history entries. This works by bin-protting your value, and storing it alongside the bin-shape hash. When a history state is popped, we deserialise it only if the shape matches; otherwise you get None.

type _ t
val init_exn : ?log_s:(Core.Sexp.t -> unit) -> (module Payload with type t = 'p) -> 'p t

You can only call one of the "init" functions (here or in Opinionated), and moreover only once; this module is inherantly global.

module Entry : sig ... end
val popstate_bus : 'p t -> ('p Entry.t -> unit, Core.read) Bus.t
val current : 'p t -> 'p Entry.t

When calling push or replace, you can replace the uri by passing the optional argument uri; if ommitted it will be unchanged.

Note that the uri you pass here can be relative, and it will be resolved relative to the current uri. However, the uri you get back out of an _ Entry.t is _not_ relative; you won't necessarily get out the string you put in. I recommend you construct a uri with at most path and query in it.

These functions will raise in the case of uri syntax errors. The _browser_ may throw an exception if it doesn't like your uri or state, for example if the uri is not of the same origin, or the state is excessively large (multiple megabytes in Chrome, 640k in Firefox).

val push_or_replace : 'p t -> [ `Push | `Replace ] -> ?uri:Uri.t -> 'p -> unit
val push : 'p t -> ?uri:Uri.t -> 'p -> unit
val replace : 'p t -> ?uri:Uri.t -> 'p -> unit
module Opinionated : sig ... end

This module provides a more opinionated way to use html5-history; it's a thin wrapper over the above.

val uri_to_html5_history_string : Uri.t -> string

Strips all but path, query, and fragment. Ensures a leading / on empty path. Mostly for testing but you can use it if you'd really like