UNPKG

boltjs-preview

Version:

The modern web framework to build comprehensive web apps with native speeds

194 lines (177 loc) 6.6 kB
//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 }