The SpaStateManager class
Deserted Chateau's SPA is implemented via this class, and can be enabled or disabled by users via their navigation settings.
Registering page render params
Each JavaScript class that runs for a given page (e.g. DisplayArtwork.js, UserProfile.js), on page load, registers its parameters with SpaStateManager in order for the state manager to know what it needs to render that page if required by a user going back/forward. Example:
// From BrowseArt.js
$(function () {
SpaStateManager.registerPageRenderParams({
pageType: "/browse/art",
pageInitFunc: BrowseArt.initialise,
});
if (!SpaStateManager.pageIsLoadedViaAjax("/browse/art")) {
dcLogger.debug(color() + "Initialising Browse Art");
BrowseArt.initialise();
}
});
Page types and page identifiers
Pages all have a unique page type, corresponding to their backend URL before any Apache redirects.
Page identifiers are used to distinguish different pages of the same page type; for example, a user might browse multiple user profiles, which each will be rendered as their own separate subpage.
Page types and identifiers are stored in the subpage's containing div element, using the dc-page-type and dc-page-identifier attributes.
Overriding link behaviours
For each link on a page that directs to another page, the usual link behaviour is overridden to use the SpaStateManager, unless the user has opted to disable it. Example:
// From NavbarManager.js
$(`a.navbar-link[href="/browse/bookmarks"]`).on("click", function (e) {
dcLogger.debug(color() + "Browse bookmarks navbar button clicked");
if (SpaStateManager.userSPAEnabled) {
e.preventDefault();
const browseBookmarksUrl = "/browse/bookmarks";
dcLogger.debug(color() + "Rendering browse bookmarks via navbar");
SpaStateManager.renderPage({
newUrl: browseBookmarksUrl,
pageType: "/browse/bookmarks",
loginRequired: true,
});
}
});
The loginRequired parameter of SpaStateManager.renderPage is used to render the login page instead of the page provided in newUrl, if the user is not logged in (as otherwise, backend redirecting doesn't work correctly).