boltjs-preview
Version:
The modern web framework to build comprehensive web apps with native speeds
194 lines (177 loc) • 6.6 kB
JavaScript
//the router implimentation for BoltUI
//This router can be used to make main-page as well as
//sub-router calls easily.
/**
*
* @param {*} root_url
* @param {...any} urlNodes
* @returns HTMLElement
*
* The Router function takes a root url on which it will show
* the views that are passed using Url function
*
* This Router must be used with Navigator function, since this
* Router supports only SSR Routing ( full reload )
*/
export function Router(root_url, ...urlNodes) {
//this is useful for many purposes
//the URLNodes are the functions that possess the URL data
//return whatever the current url is.
var routerElement = document.createElement("div")
let currentPath = window.location.pathname
//update the path during initialization
urlNodes.forEach(node => {
if ( currentPath == `${root_url}${node.url}` ) {
if ( window.history.state ) {
routerElement.replaceChildren(node.callBack(...window.history.state.data))
} else {
routerElement.replaceChildren(node.callBack())
}
}
})
//let's also add some event Listners in Case we
//want to listen to back track events
function CallBack() {
//now do the same thing
urlNodes.forEach(node => {
if ( window.location.pathname == `${root_url}${node.url}` ) {
if ( window.history.state ) {
routerElement.replaceChildren(node.callBack(...window.history.state.data))
} else {
routerElement.replaceChildren(node.callBack())
}
}
})
}
window.addEventListener("popstate", CallBack)
//now remove the event listner, when not in Need, because
//ofcourse why would you even need when the component is out of scope
routerElement._bolt_remove_api = () => {
window.removeEventListener("popstate", CallBack)
}
return routerElement
}
//this can be said to be some sort of Higher Order Function
/**
*
* @param {*} base_url
* @param {*} callback
* @returns RouterMetaData
*
* The URL function takes a base url and a callback and returns
* some meta data to be used by the Router function to route
* the content as required.
*
* This function should not be used directly since it does not
* returns any document object, and should be used by Router
* or some equivalent function that can handle meta functions or HOCs
*/
export function Url(base_url, callback) {
//the element to be called
return {
url: base_url,
callBack: callback
}
}
//this function is used to Navigate to custom urls
/**
*
* @param {*} base_url
* @param {...any} data
*
* The Navigation function to be used to navigate between
* Routes with a full refresh ( full page refresh )
*
* This can be optimum when using SSR as aided, otherwise
* use AppNavigate to navigate through the app itself
* without using any sort of data
*/
export function Navigate(base_url, ...data) {
if ( base_url == window.location.pathname ) {
//depends, like if the data was not same?
if ( data == [] ) {
return //if there is no data, means a static transition
}
}
window.history.pushState({ url: base_url, data }, "", base_url)
window.history.go()
}
//17th Oct - Implement App Router Navigator:
//Basically the App Router will be able to navigate to
//a route without refreshing the data itself, using
//some amazing listeners and all.
//AppRouter is same as a normal router, the exceptio being
//that the Trigger is stored in state instead of like having
//using the Native methods, this way we can implement
//a no-reload transition method. The push-state will still
//be used along side the URL
/**
*
* @param {*} base_url
* @param {...any} urlNodes
* @returns HTMLElement
*
* The AppRouter function also takes a base url to work with alongside
* the views with their corresponding urlNodes.
*
* The AppRouter will react to both SSR Url changes as well as app
* transition changes (non-SSR changes)
*/
export function AppRouter(base_url, ...urlNodes) {
//this is useful for many purposes
//the URLNodes are the functions that possess the URL data
//return whatever the current url is.
var routerElement = document.createElement("div")
let currentPath = window.location.pathname
//update the path during initialization
urlNodes.forEach(node => {
if ( currentPath == `${base_url}${node.url}` ) {
if ( window.history.state ) {
routerElement.replaceChildren(node.callBack(...window.history.state.data))
} else {
routerElement.replaceChildren(node.callBack())
}
}
})
//let's also add some event Listners in Case we
//want to listen to back track events
function CallBack() {
//now do the same thing
urlNodes.forEach(node => {
if ( window.location.pathname == `${base_url}${node.url}` ) {
if ( window.history.state ) {
routerElement.replaceChildren(node.callBack(...window.history.state.data))
} else {
routerElement.replaceChildren(node.callBack())
}
}
})
}
//this one is used to track the non-native page transition
//or the AppNavigate events
window.addEventListener("popstate", CallBack)
window.addEventListener("urlchange", CallBack) //a new custom event
//now remove the event listner, when not in Need, because
//ofcourse why would you even need when the component is out of scope
routerElement._bolt_remove_api = () => {
window.removeEventListener("popstate", CallBack)
window.removeEventListener("urlchange", CallBack)
}
return routerElement
}
export function AppNavigator(base_url, ...data) {
if ( base_url == window.location.pathname ) {
//depends, like if the data was not same?
if ( data == [] ) {
return //if there is no data, means a static transition
}
}
window.history.pushState({ url: base_url, data }, "", base_url)
//Now we will trigger some other type of event, a custom
//event that might contain some functions that could
//change the state
window.dispatchEvent(new Event('urlchange'))
//this event is used to say that the page was changed
//wihtout really reloading the app entierely.
//This is performant if you have no SSR requirements
}