Updated Docs class code and JSDocs

This commit is contained in:
Atomos821 2020-11-26 09:53:18 +01:00
parent 22a3a12a2f
commit 5b0c3ac913

View File

@ -1,10 +1,4 @@
/** // TODO: Override the marker.js renderer for urls to enable proper anchor support.
* TODO: override the marker.js renderer for urls
* to enable proper anchor support.
*
* Probably just need to check if the text starts
* with a # or not to cover most cases.
*/
class Docs { class Docs {
/** /**
@ -33,26 +27,30 @@ class Docs {
this.onExec(); this.onExec();
} }
/**
* Called on instanciation by the constructor.
*/
async onExec() { async onExec() {
// Get routes.
this.routesData = await this.fetchRoutes(); this.routesData = await this.fetchRoutes();
// Generate nav based on routes. this.updateRoutes(this.routesData);
this.generateNav(this.routesData, document.querySelector('aside'));
this.generateNav(this.routes, document.querySelector('aside'));
// Add listener for hash change.
window.addEventListener('hashchange', () => this.handleLocation(window.location)); window.addEventListener('hashchange', () => this.handleLocation(window.location));
// Check for initial condition.
if (window.location.hash) { if (window.location.hash) {
// There is a hash in the address bar, load the view.
this.handleLocation(window.location); this.handleLocation(window.location);
} else if (typeof this.defaultViewPath !== 'undefined') { } else if (typeof this.defaultViewPath !== 'undefined') {
// TODO: Do it. // TODO: Load a default view.
console.log('Missing Feature !\nShould load the default view'); console.log('Missing Feature !\nShould load the default view');
} }
} }
/** /**
* Fetch the json file containing the routes.
* @returns {Array.<JSON>} The array containing the routes. * @returns {Array.<JSON>} The array containing the routes.
*/ */
async fetchRoutes() { async fetchRoutes() {
@ -63,22 +61,43 @@ class Docs {
} }
/** /**
* @param {Array.<JSON>} routes * Update the routes.
* @param {HTMLElement} target * @param {Array.<JSON>} routesData
*/ */
generateNav(routesData, target) { updateRoutes(routesData) {
/** @type {Array.<RoutingItem>} */
const routes = []; const routes = [];
const nav = document.createElement('nav');
routesData.forEach(routeData => { routesData.forEach(routeData => {
if ('routes' in routeData) { if ('routes' in routeData) {
routes.push(new RoutingNode(routeData['name'], routeData['hidden'], routeData['routes'])); const node = new RoutingNode(
routeData['name'],
routeData['hidden'],
routeData['routes']
);
routes.push(node);
} else { } else {
routes.push(new Route(routeData['name'], routeData['hidden'], routeData['filepath'])); const route = new Route(
routeData['name'],
routeData['hidden'],
routeData['filepath']
);
routes.push(route);
} }
}); });
this.routes = routes;
}
/**
* Generate the side nav HTML based on routing data.
* @param {Array.<RoutingItem>} routes
* @param {HTMLElement} target
*/
generateNav(routes, target) {
const nav = document.createElement('nav');
routes.forEach(routingItem => { routes.forEach(routingItem => {
if (routingItem['hidden'] === false || typeof routingItem['hidden'] === 'undefined') { if (routingItem['hidden'] === false || typeof routingItem['hidden'] === 'undefined') {
const el = routingItem.buildSelf(); const el = routingItem.buildSelf();
@ -86,35 +105,33 @@ class Docs {
if (typeof el !== 'undefined') { if (typeof el !== 'undefined') {
nav.appendChild(el); nav.appendChild(el);
} }
} else {
console.log(`skipped ${routingItem.name}`);
} }
}); });
target.appendChild(nav); target.appendChild(nav);
this.routes = routes;
} }
/** /**
* Handle if the view needs to be changed or to move to in-page anchor
* base on the location data.
* @param {Location} location * @param {Location} location
*/ */
handleLocation(location) { handleLocation(location) {
let hashes = location.hash.split('#'); const hashes = location.hash.split('#');
hashes.splice(0, 1); hashes.splice(0, 1);
console.log(hashes);
if (typeof this.currentRoute === 'undefined' || this.currentRoute.filepath !== hashes[0]) { if (typeof this.currentRoute === 'undefined' || this.currentRoute.filepath !== hashes[0]) {
// TODO: add check in case of no matching routes.
const route = this.findMatchingRoute(hashes[0], this.routes); const route = this.findMatchingRoute(hashes[0], this.routes);
// Scroll back to top. this.currentRoute = route;
// Scroll back to top of the content outlet.
document.querySelector('#router-outlet').scrollTop = 0; document.querySelector('#router-outlet').scrollTop = 0;
this.currentRoute = route;
this.displayRoute(route); this.displayRoute(route);
// Changing classes based on the new active route.
const activeLinks = document.querySelectorAll('a.active'); const activeLinks = document.querySelectorAll('a.active');
const newActiveLinks = document.querySelectorAll(`a[href='#${hashes[0]}']`); const newActiveLinks = document.querySelectorAll(`a[href='#${hashes[0]}']`);
@ -124,12 +141,11 @@ class Docs {
newActiveLinks.forEach(newLink => newLink.classList.add('active')); newActiveLinks.forEach(newLink => newLink.classList.add('active'));
// TODO: update active route in the page's navbar
if (hashes.length > 1) { if (hashes.length > 1) {
this.handleLocation(window.location); this.handleLocation(window.location);
} }
} else { } else {
// Page don't need to be changed, just move to anchor.
const el = document.querySelector(`#${hashes[1]}`); const el = document.querySelector(`#${hashes[1]}`);
el.scrollIntoView({ el.scrollIntoView({
@ -140,16 +156,16 @@ class Docs {
} }
/** /**
* Recursively search for a matching route based on a filepath.
* @param {string} filepath The filepath to search. * @param {string} filepath The filepath to search.
* @returns {Route} The matching route. * @returns {Route} The matching route.
*/ */
findMatchingRoute(filepath, routes) { findMatchingRoute(filepath, routes) {
console.log('filepath:', filepath); // TODO: Break the loops in a more elegant way.
let match = undefined; let match = undefined;
for (let routingItem of routes) { for (let routingItem of routes) {
// If the routingItem is a route and have what we are looking for. // If the routingItem is a Route and have what we are looking for.
if (routingItem.hasOwnProperty('filepath') && routingItem['filepath'] === filepath) { if (routingItem.hasOwnProperty('filepath') && routingItem['filepath'] === filepath) {
match = routingItem; match = routingItem;
break; break;
@ -172,6 +188,7 @@ class Docs {
} }
/** /**
* Load and displays a route's content.
* @param {Route} route The route to load. * @param {Route} route The route to load.
*/ */
async displayRoute(route) { async displayRoute(route) {
@ -183,6 +200,10 @@ class Docs {
Prism.highlightAll(); // edited Prism.highlightAll(); // edited
} }
/**
* Utilitary function to remove any content inside an HTML element
* @param {HTMLElement} element
*/
removeChildren(element) { removeChildren(element) {
let count = element.childNodes.length; let count = element.childNodes.length;