2022-03-21 17:43:24 +13:00
// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"
// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
// import "../vendor/some-package.js"
//
// Alternatively, you can `npm install some-package --prefix assets` and import
// them using a path starting with the package name:
//
// import "some-package"
//
2022-09-08 03:53:36 +12:00
import scrollIntoView from "smooth-scroll-into-view-if-needed" ;
2022-03-21 17:43:24 +13:00
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
2022-09-08 03:53:36 +12:00
import "phoenix_html" ;
2022-03-21 17:43:24 +13:00
// Establish Phoenix Socket and LiveView configuration.
2022-09-08 03:53:36 +12:00
import { Socket } from "phoenix" ;
import { LiveSocket } from "phoenix_live_view" ;
import topbar from "../vendor/topbar" ;
import mermaid from "mermaid" ;
mermaid . init ( ".mermaid" ) ;
2022-03-26 10:17:01 +13:00
2022-09-06 05:47:12 +12:00
function cookiesAreAllowed ( ) {
2022-09-08 03:53:36 +12:00
const consentStatus = document . cookie
. split ( "; " )
. find ( ( row ) => row . startsWith ( "cookieconsent_status=" ) ) ;
2022-09-06 05:47:12 +12:00
return consentStatus === "cookieconsent_status=allow" ;
}
2022-03-26 10:17:01 +13:00
const Hooks = { } ;
2022-09-06 05:29:38 +12:00
let configuredThemeRow ;
2022-09-08 03:53:36 +12:00
if ( cookiesAreAllowed ( ) ) {
configuredThemeRow = document . cookie
. split ( "; " )
. find ( ( row ) => row . startsWith ( "theme=" ) ) ;
2022-09-06 05:29:38 +12:00
}
2022-04-02 11:49:26 +13:00
if ( ! configuredThemeRow ) {
let theme ;
2022-09-08 03:53:36 +12:00
if (
window . matchMedia &&
window . matchMedia ( "(prefers-color-scheme: dark)" ) . matches
) {
2022-09-06 05:29:38 +12:00
setTheme ( "dark" ) ;
2022-04-02 11:49:26 +13:00
} else {
2022-09-06 05:29:38 +12:00
setTheme ( "light" ) ;
2022-04-02 11:49:26 +13:00
}
}
2022-09-08 03:53:36 +12:00
window
. matchMedia ( "(prefers-color-scheme: dark)" )
. addEventListener ( "change" , ( event ) => {
let configuredThemeRow ;
if ( cookiesAreAllowed ( ) ) {
configuredThemeRow = document . cookie
. split ( "; " )
. find ( ( row ) => row . startsWith ( "theme=" ) ) ;
}
2022-04-02 11:49:26 +13:00
2022-09-08 03:53:36 +12:00
if ( ! configuredThemeRow || configuredThemeRow === "theme=system" ) {
setTheme ( "system" ) ;
2022-08-30 16:25:13 +12:00
} else {
2022-09-08 03:53:36 +12:00
if ( configuredThemeRow === "theme=dark" ) {
setTheme ( "dark" ) ;
} else if ( configuredThemeRow === "theme=light" ) {
setTheme ( "light" ) ;
} else {
setTheme ( "system" ) ;
}
2022-08-30 16:25:13 +12:00
}
2022-09-08 03:53:36 +12:00
} ) ;
2022-04-02 11:49:26 +13:00
2022-09-06 05:29:38 +12:00
function setTheme ( theme , set ) {
2022-04-02 11:49:26 +13:00
let setTheme ;
2022-09-08 03:53:36 +12:00
if ( theme == "system" ) {
if (
window . matchMedia &&
window . matchMedia ( "(prefers-color-scheme: dark)" ) . matches
) {
2022-04-02 11:49:26 +13:00
setTheme = "dark" ;
} else {
setTheme = "light" ;
}
2022-08-30 16:25:13 +12:00
} else {
setTheme = theme ;
2022-04-02 11:49:26 +13:00
}
2022-08-30 16:25:13 +12:00
2022-04-02 11:49:26 +13:00
document . documentElement . classList . add ( setTheme ) ;
2022-08-30 16:25:13 +12:00
2022-09-08 03:53:36 +12:00
if ( setTheme === "dark" ) {
2022-04-02 11:49:26 +13:00
document . documentElement . classList . remove ( "light" ) ;
} else {
document . documentElement . classList . remove ( "dark" ) ;
2022-09-08 03:53:36 +12:00
}
2022-04-02 11:49:26 +13:00
2022-09-08 03:53:36 +12:00
if ( set && cookiesAreAllowed ( ) ) {
document . cookie = "theme" + "=" + theme + ";path=/" ;
2022-09-06 05:29:38 +12:00
}
2022-04-02 11:49:26 +13:00
}
2022-03-26 10:17:01 +13:00
Hooks . ColorTheme = {
mounted ( ) {
2022-09-08 03:53:36 +12:00
this . handleEvent ( "set_theme" , ( payload ) => {
setTheme ( payload . theme , true ) ;
} ) ;
} ,
} ;
2022-03-26 10:17:01 +13:00
2022-03-30 05:12:28 +13:00
Hooks . Docs = {
mounted ( ) {
2022-09-08 03:53:36 +12:00
mermaid . init ( ".mermaid" ) ;
} ,
} ;
2022-03-30 05:12:28 +13:00
2022-04-01 09:59:53 +13:00
function onScrollChange ( ) {
const docs = document . getElementById ( "docs-window" ) ;
2022-09-08 03:53:36 +12:00
if ( docs ) {
2022-04-01 09:59:53 +13:00
const scrollTop = docs . scrollTop ;
2022-09-08 03:53:36 +12:00
const topEl = Array . from (
document . getElementsByClassName ( "nav-anchor" )
) . filter ( ( el ) => {
return el . offsetTop + el . clientHeight >= scrollTop ;
2022-04-01 09:59:53 +13:00
} ) [ 0 ] ;
let hash ;
2022-09-08 03:53:36 +12:00
if ( window . location . hash ) {
2022-04-01 09:59:53 +13:00
hash = window . location . hash . substring ( 1 ) ;
}
2022-09-08 03:53:36 +12:00
if ( topEl && topEl . id !== hash ) {
history . replaceState ( null , null , ` # ${ topEl . id } ` ) ;
2022-04-01 09:59:53 +13:00
window . location . hash = topEl . id ;
const newTarget = document . getElementById ( ` right-nav- ${ topEl . id } ` ) ;
2022-09-08 03:53:36 +12:00
Array . from (
document . getElementsByClassName ( "currently-active-nav" )
) . forEach ( ( el ) => {
2022-04-01 09:59:53 +13:00
el . classList . remove ( "currently-active-nav" ) ;
2022-09-08 15:02:18 +12:00
el . classList . remove ( "text-primary-light-600" ) ;
el . classList . remove ( "dark:text-primary-dark-400" ) ;
2022-09-08 03:53:36 +12:00
} ) ;
if ( newTarget ) {
2022-09-08 15:02:18 +12:00
newTarget . classList . add ( "dark:text-primary-dark-400" ) ;
2022-09-08 15:18:18 +12:00
newTarget . classList . add ( "text-primary-light-600" ) ;
2022-09-08 03:53:36 +12:00
newTarget . classList . add ( "currently-active-nav" ) ;
scrollIntoView ( newTarget , { behavior : "smooth" , block : "center" } ) ;
2022-04-01 09:59:53 +13:00
}
}
}
}
function handleHashChange ( clear ) {
if ( window . location . hash ) {
2022-09-08 03:53:36 +12:00
const el = document . getElementById (
"right-nav-" + window . location . hash . substring ( 1 )
) ;
if ( el ) {
2022-04-01 09:59:53 +13:00
if ( clear ) {
2022-09-08 03:53:36 +12:00
Array . from (
document . getElementsByClassName ( "currently-active-nav" )
) . forEach ( ( el ) => {
2022-04-01 09:59:53 +13:00
el . classList . remove ( "currently-active-nav" ) ;
2022-09-08 15:02:18 +12:00
el . classList . remove ( "text-primary-light-600" ) ;
el . classList . remove ( "dark:text-primary-dark-400" ) ;
2022-09-08 03:53:36 +12:00
} ) ;
2022-04-01 09:59:53 +13:00
}
2022-09-08 15:02:18 +12:00
el . classList . add ( "dark:text-primary-dark-400" ) ;
el . classList . add ( "text-primary-light-600" ) ;
2022-09-08 03:53:36 +12:00
el . classList . add ( "currently-active-nav" ) ;
2022-04-01 09:59:53 +13:00
scrollIntoView ( el , {
2022-09-08 03:53:36 +12:00
behavior : "smooth" ,
block : "center" ,
} ) ;
2022-04-01 09:59:53 +13:00
}
}
}
Hooks . RightNav = {
mounted ( ) {
handleHashChange ( false ) ;
const docs = document . getElementById ( "docs-window" ) ;
if ( docs ) {
2022-09-08 03:53:36 +12:00
docs . addEventListener ( "scroll" , ( ) => onScrollChange ( ) ) ;
if ( this . interval ) {
clearInterval ( this . interval ) ;
}
2022-04-01 09:59:53 +13:00
}
} ,
destroyed ( ) {
2022-09-08 03:53:36 +12:00
if ( this . interval ) {
clearInterval ( this . interval ) ;
2022-04-01 09:59:53 +13:00
}
2022-09-08 03:53:36 +12:00
} ,
} ;
2022-04-01 09:59:53 +13:00
2022-09-08 03:53:36 +12:00
let csrfToken = document
. querySelector ( "meta[name='csrf-token']" )
. getAttribute ( "content" ) ;
2022-03-26 10:17:01 +13:00
let liveSocket = new LiveSocket ( "/live" , Socket , {
2022-09-08 03:53:36 +12:00
params : { _csrf _token : csrfToken } ,
2022-03-26 10:17:01 +13:00
hooks : Hooks ,
metadata : {
keydown : ( e ) => {
return {
key : e . key ,
2022-09-08 03:53:36 +12:00
metaKey : e . metaKey ,
} ;
} ,
} ,
2022-03-26 10:17:01 +13:00
} ) ;
2022-03-21 17:43:24 +13:00
2022-03-29 11:05:19 +13:00
// Show progress bar on live navigation and form submits. Only displays if still
// loading after 120 msec
2022-09-08 03:53:36 +12:00
topbar . config ( { barColors : { 0 : "#29d" } , shadowColor : "rgba(0, 0, 0, .3)" } ) ;
2022-03-29 11:05:19 +13:00
let topBarScheduled = undefined ;
window . addEventListener ( "phx:page-loading-start" , ( ) => {
2022-09-08 03:53:36 +12:00
if ( ! topBarScheduled ) {
2022-03-29 11:05:19 +13:00
topBarScheduled = setTimeout ( ( ) => topbar . show ( ) , 120 ) ;
2022-09-08 03:53:36 +12:00
}
2022-03-29 11:05:19 +13:00
} ) ;
window . addEventListener ( "phx:page-loading-stop" , ( ) => {
clearTimeout ( topBarScheduled ) ;
topBarScheduled = undefined ;
topbar . hide ( ) ;
} ) ;
2022-09-08 03:53:36 +12:00
window . addEventListener ( "js:focus" , ( e ) => e . target . focus ( ) ) ;
2022-03-21 17:43:24 +13:00
2022-03-26 16:16:20 +13:00
window . addEventListener ( "phx:js:scroll-to" , ( e ) => {
const target = document . getElementById ( e . detail . id ) ;
2022-03-28 10:26:35 +13:00
const boundary = document . getElementById ( e . detail . boundary _id ) ;
2022-09-08 03:53:36 +12:00
scrollIntoView ( target , {
behavior : "smooth" ,
block : "center" ,
boundary : boundary ,
2022-03-28 10:26:35 +13:00
} ) ;
2022-03-26 16:16:20 +13:00
} ) ;
2022-04-01 19:43:09 +13:00
window . addEventListener ( "phx:sidebar-state" , ( e ) => {
2022-09-08 03:53:36 +12:00
const cookie = Object . keys ( e . detail )
. map ( ( key ) => ` ${ key } : ${ e . detail [ key ] } ` )
. join ( "," ) ;
if ( cookiesAreAllowed ( ) ) {
document . cookie = "sidebar_state" + "=" + cookie + ";path=/" ;
2022-09-06 05:29:38 +12:00
}
2022-09-08 03:53:36 +12:00
} ) ;
2022-04-01 19:43:09 +13:00
2022-04-01 05:36:44 +13:00
let scrolled = false ;
2022-04-01 09:59:53 +13:00
window . addEventListener ( "phx:page-loading-start" , ( ) => {
scrolled = false ;
2022-09-08 03:53:36 +12:00
} ) ;
2022-04-01 09:59:53 +13:00
2022-09-08 03:53:36 +12:00
window . addEventListener ( "phx:page-loading-stop" , ( { detail } ) => {
if ( detail . kind === "initial" && window . location . hash && ! scrolled ) {
2022-04-01 05:36:44 +13:00
let hashEl = document . getElementById ( window . location . hash . substring ( 1 ) ) ;
2022-04-01 09:59:53 +13:00
console . log ( hashEl ) ;
2022-04-01 05:36:44 +13:00
hashEl && hashEl . scrollIntoView ( ) ;
scrolled = true ;
}
topbar . hide ( ) ;
2022-09-08 03:53:36 +12:00
} ) ;
2022-04-01 05:36:44 +13:00
2022-03-28 10:26:35 +13:00
window . addEventListener ( "phx:selected-versions" , ( e ) => {
2022-09-08 03:53:36 +12:00
console . log ( e . detail ) ;
if ( cookiesAreAllowed ( ) ) {
const cookie = Object . keys ( e . detail )
. map ( ( key ) => ` ${ key } : ${ e . detail [ key ] } ` )
. join ( "," ) ;
document . cookie = "selected_versions" + "=" + cookie + ";path=/" ;
2022-09-06 05:29:38 +12:00
}
2022-03-28 10:26:35 +13:00
} ) ;
2022-03-26 16:16:20 +13:00
2022-03-30 17:40:17 +13:00
window . addEventListener ( "phx:selected-types" , ( e ) => {
2022-09-08 03:53:36 +12:00
if ( cookiesAreAllowed ( ) ) {
const cookie = e . detail . types . join ( "," ) ;
document . cookie = "selected_types" + "=" + cookie + ";path=/" ;
2022-09-06 05:29:38 +12:00
}
2022-03-30 17:40:17 +13:00
} ) ;
2022-03-30 18:07:17 +13:00
window . addEventListener ( "keydown" , ( event ) => {
2022-09-08 03:53:36 +12:00
if ( ( event . metaKey || event . ctrlKey ) && event . key === "k" ) {
document . getElementById ( "search-button" ) . click ( ) ;
2022-04-02 08:11:17 +13:00
event . preventDefault ( ) ;
2022-03-30 18:07:17 +13:00
}
2022-09-08 03:53:36 +12:00
} ) ;
2022-03-30 18:07:17 +13:00
window . addEventListener ( "keydown" , ( event ) => {
2022-09-08 03:53:36 +12:00
if ( event . key === "Escape" ) {
document . getElementById ( "close-search" ) . click ( ) ;
2022-04-02 08:11:17 +13:00
event . preventDefault ( ) ;
2022-03-30 18:07:17 +13:00
}
2022-09-08 03:53:36 +12:00
} ) ;
2022-04-02 08:11:17 +13:00
window . addEventListener ( "phx:close-search" , ( event ) => {
2022-09-08 03:53:36 +12:00
document . getElementById ( "close-search" ) . click ( ) ;
2022-04-02 08:11:17 +13:00
event . preventDefault ( ) ;
2022-09-08 03:53:36 +12:00
} ) ;
2022-03-30 18:07:17 +13:00
2022-03-21 17:43:24 +13:00
// connect if there are any LiveViews on the page
2022-09-08 03:53:36 +12:00
liveSocket . connect ( ) ;
2022-03-21 17:43:24 +13:00
// expose liveSocket on window for web console debug logs and latency simulation:
2022-09-08 03:53:36 +12:00
liveSocket . disableDebug ( ) ;
2022-03-21 17:43:24 +13:00
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
2022-09-08 03:53:36 +12:00
window . liveSocket = liveSocket ;
2022-03-21 17:43:24 +13:00
2022-09-08 03:53:36 +12:00
window . addEventListener ( "load" , function ( ) {
2022-09-06 05:29:38 +12:00
window . cookieconsent . initialise ( {
2022-09-08 03:53:36 +12:00
content : {
message :
"Hi, this website uses essential cookies for remembering your explicitly set preferences, if you opt-in. We do not use google analytics, but we do use plausible.io, an ethical google analytics alternative which does not use any cookies and collects no personal data." ,
link : null ,
2022-09-06 05:29:38 +12:00
} ,
2022-09-08 03:53:36 +12:00
type : "opt-in" ,
palette : {
popup : {
background : "#000" ,
2022-09-06 05:29:38 +12:00
} ,
2022-09-08 03:53:36 +12:00
button : {
background : "#f1d600" ,
} ,
} ,
} ) ;
2022-09-06 05:29:38 +12:00
} ) ;
2022-09-08 03:53:36 +12:00
window . addEventListener ( "hashchange" , ( event ) => {
handleHashChange ( true ) ;
} ) ;