diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx
index 68963129f..cfc10bbd6 100644
--- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx
+++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx
@@ -3,7 +3,6 @@ require('./headerNav.less');
import * as React from 'react';
import * as _ from 'lodash';
-
const MAX_TEXT_LENGTH = 40;
const HeaderNav = React.forwardRef(({}, pagesRef)=>{
@@ -11,11 +10,30 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{
const renderHeaderLinks = ()=>{
if(!pagesRef.current) return;
+ // Top Level Pages
+ // Pages that contain an element with a specified class (e.g. cover pages, table of contents)
+ // will NOT have its content scanned for navigation headers, instead displaying a custom label
+ // ---
+ // The property name is class that will be used for detecting the page is a top level page
+ // The property value is a function that returns the text to be used
+
+ const topLevelPages = {
+ '.frontCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Cover: ${text}` : 'Cover Page'; },
+ '.insideCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Interior: ${text}` : 'Interior Cover Page'; },
+ '.partCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Section: ${text}` : 'Section Cover Page'; },
+ '.backCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Back: ${text}` : 'Rear Cover Page'; },
+ '.toc' : ()=>{ return 'Table of Contents'; },
+ };
+
+ const getHeaderContent = el => el.querySelector('h1')?.textContent;
+
+ const topLevelPageSelector = Object.keys(topLevelPages).join(',');
+
const selector = [
- '.pages > .page', // All page elements, which by definition have IDs
- '.page:not(:has(.toc)) > [id]', // All direct children of non-ToC .page with an ID (Legacy)
- '.page:not(:has(.toc)) > .columnWrapper > [id]', // All direct children of non-ToC .page > .columnWrapper with an ID (V3)
- '.page:not(:has(.toc)) h2', // All non-ToC H2 titles, like Monster frame titles
+ '.pages > .page', // All page elements, which by definition have IDs
+ `.page:not(:has(${topLevelPageSelector})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy)
+ `.page:not(:has(${topLevelPageSelector})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3)
+ `.page:not(:has(${topLevelPageSelector})) h2`, // All non-excluded H2 titles, like Monster frame titles
];
const elements = pagesRef.current.querySelectorAll(selector.join(','));
if(!elements) return;
@@ -23,45 +41,37 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{
// navList is a list of objects which have the following structure:
// {
- // depth : how deeply indented the item should be
- // text : the text to display in the nav link
- // link : the hyperlink to navigate to when clicked
- // className : [optional] the class to apply to the nav link for styling
+ // depth : how deeply indented the item should be
+ // text : the text to display in the nav link
+ // link : the hyperlink to navigate to when clicked
+ // className : [optional] the class to apply to the nav link for styling
// }
elements.forEach((el)=>{
- if(el.className.match(/\bpage\b/)) {
- let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number
- if(el.querySelector('.toc')){ // If the page contains a table of contents, add "- Contents" to the display text
- text += ' - Contents';
- };
- navList.push({
- depth : 0, // Pages are always at the least indented level
- text : text,
- link : el.id,
- className : 'pageLink'
- });
- return;
- }
- if(el.localName.match(/^h[1-6]/)){ // Header elements H1 through H6
- navList.push({
- depth : el.localName[1], // Depth is set by the header level
- text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto'
- link : el.id
- });
- return;
- }
- navList.push({
- depth : 7, // All unmatched elements with IDs are set to the maximum depth (7)
- text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto'
+ const navEntry = { // Default structure of a navList entry
+ depth : 7, // All unmatched elements with IDs are set to the maximum depth (7)
+ text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto'
link : el.id
- });
- });
-
- return _.map(navList, (navItem, index)=>{
- return ;
+ }
+ if(el.classList.contains('page')) {
+ let text = `Page ${el.id.slice(1)}`; // Get the page # by trimming off the 'p' from the ID
+ const pageType = Object.keys(topLevelPages).find(pageType => el.querySelector(pageType));
+ if (pageType)
+ text += ` - ${topLevelPages[pageType](el, pageType)}` // If a Top Level Page, add extra label
+
+ navEntry.depth = 0; // Pages are always at the least indented level
+ navEntry.text = text;
+ navEntry.className = 'pageLink';
+ }
+ else if(el.localName.match(/^h[1-6]/)){ // Header elements H1 through H6
+ navEntry.depth = el.localName[1]; // Depth is set by the header level
+ }
+ navList.push(navEntry);
});
+ return _.map(navList, (navItem, index)=>
+
+ );
};
return ;
-}
-);
+});
const HeaderNavItem = ({ link, text, depth, className })=>{
diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.less b/client/homebrew/brewRenderer/headerNav/headerNav.less
index 8b35041d9..a5769ef99 100644
--- a/client/homebrew/brewRenderer/headerNav/headerNav.less
+++ b/client/homebrew/brewRenderer/headerNav/headerNav.less
@@ -35,11 +35,11 @@
font-weight: 900;
}
- @depths: 1,2,3,4,5,6,7;
+ @depths: 0,1,2,3,4,5,6,7;
each(@depths, {
&.depth-@{value} {
- padding-left: ((@value - 1) * 0.5em);
+ padding-left: ((@value) * 0.5em);
}
});
}