diff options
Diffstat (limited to 'src/content/dependencies/generatePageLayout.js')
-rw-r--r-- | src/content/dependencies/generatePageLayout.js | 168 |
1 files changed, 41 insertions, 127 deletions
diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index 9e9b461..0bf3454 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -1,60 +1,6 @@ import {openAggregate} from '#aggregate'; import {empty} from '#sugar'; -function sidebarSlots(side) { - return { - // Content is a flat HTML array. It'll generate one sidebar section - // if specified. - [side + 'Content']: { - type: 'html', - mutable: false, - }, - - // A single class to apply to the whole sidebar. If specifying multiple - // sections, this be added to the containing sidebar-column - specify a - // class on each section if that's more suitable. - [side + 'Class']: {type: 'string'}, - - // Multiple is an array of objects, each specifying content (HTML) and - // optionally class (a string). Each of these will generate one sidebar - // section. - [side + 'Multiple']: { - validate: v => - v.sparseArrayOf( - v.validateProperties({ - class: v.optional(v.isString), - content: v.isHTML, - })), - }, - - // Sticky mode controls which sidebar section(s), if any, follow the - // scroll position, "sticking" to the top of the browser viewport. - // - // 'last' - last or only sidebar box is sticky - // 'column' - entire column, incl. multiple boxes from top, is sticky - // 'none' - sidebar not sticky at all, stays at top of page - // - // Note: This doesn't affect the content of any sidebar section, only - // the whole section's containing box (or the sidebar column as a whole). - [side + 'StickyMode']: { - validate: v => v.is('last', 'column', 'static'), - default: 'static', - }, - - // Collapsing sidebars disappear when the viewport is sufficiently - // thin. (This is the default.) Override as false to make the sidebar - // stay visible in thinner viewports, where the page layout will be - // reflowed so the sidebar is as wide as the screen and appears below - // nav, above the main content. - [side + 'Collapse']: {type: 'boolean', default: true}, - - // Wide sidebars generally take up more horizontal space in the normal - // page layout, and should be used if the content of the sidebar has - // a greater than typical focus compared to main content. - [side + 'Wide']: {type: 'boolean', defualt: false}, - }; -} - export default { contentDependencies: [ 'generateColorStyleRules', @@ -162,8 +108,15 @@ export default { // Sidebars - ...sidebarSlots('leftSidebar'), - ...sidebarSlots('rightSidebar'), + leftSidebar: { + type: 'html', + mutable: true, + }, + + rightSidebar: { + type: 'html', + mutable: true, + }, // Banner @@ -266,6 +219,14 @@ export default { const colors = getColors(slots.color ?? data.wikiColor); const hasSocialEmbed = !html.isBlank(slots.socialEmbed); + // Hilariously jank. Sorry! We're going to need this content later ANYWAY, + // so it's "fine" to stringify it here, but this DOES mean that we're + // stringifying (and resolving) the content without the context that it's + // e.g. going to end up in a page HTML hierarchy. Might have implications + // later, mainly for: https://github.com/hsmusic/hsmusic-wiki/issues/434 + const mainContentHTML = html.tags([slots.mainContent]).toString(); + const hasID = id => mainContentHTML.includes(`id="${id}"`); + const titleContentsHTML = (html.isBlank(slots.title) ? null @@ -289,8 +250,11 @@ export default { let footerContent = slots.footerContent; if (html.isBlank(footerContent) && relations.defaultFooterContent) { - footerContent = relations.defaultFooterContent - .slot('mode', 'multiline'); + footerContent = + relations.defaultFooterContent.slots({ + mode: 'multiline', + indicateExternalLinks: false, + }); } const mainHTML = @@ -308,7 +272,7 @@ export default { html.tag('div', {class: 'main-content-container'}, {[html.onlyIfContent]: true}, - slots.mainContent), + mainContentHTML), ]); const footerHTML = @@ -384,9 +348,6 @@ export default { showAsCurrent && {class: 'current'}, - i > 0 && - {class: 'has-divider'}, - [ html.tag('span', {class: 'nav-link-content'}, // Use inline-block styling on the content span, @@ -413,64 +374,21 @@ export default { slots.navContent), ]); - const generateSidebarHTML = (side, id) => { - const content = slots[side + 'Content']; - const topClass = slots[side + 'Class']; - const multiple = slots[side + 'Multiple']; - const stickyMode = slots[side + 'StickyMode']; - const wide = slots[side + 'Wide']; - const collapse = slots[side + 'Collapse']; - - let sidebarClasses = []; - let sidebarContent = html.blank(); - - if (!html.isBlank(content)) { - sidebarClasses = ['sidebar', topClass]; - sidebarContent = content; - } else if (multiple) { - sidebarClasses = ['sidebar-multiple', topClass]; - sidebarContent = - multiple - .filter(Boolean) - .map(box => - html.tag('div', {class: 'sidebar'}, - {[html.onlyIfContent]: true}, - {class: box.class}, - box.content)); - } - - if (html.isBlank(sidebarContent)) { - return html.blank(); - } - - return html.tag('div', {class: 'sidebar-column'}, - {id, class: sidebarClasses}, - - wide && - {class: 'wide'}, - - !collapse && - {class: 'no-hide'}, - - stickyMode !== 'static' && - {class: `sticky-${stickyMode}`}, - - sidebarContent); - } - - const sidebarLeftHTML = generateSidebarHTML('leftSidebar', 'sidebar-left'); - const sidebarRightHTML = generateSidebarHTML('rightSidebar', 'sidebar-right'); - - const hasSidebarLeft = !html.isBlank(sidebarLeftHTML); - const hasSidebarRight = !html.isBlank(sidebarRightHTML); + const getSidebar = (side, id) => + (html.isBlank(slots[side]) + ? html.blank() + : slots[side].slots({ + attributes: + slots[side] + .getSlotValue('attributes') + .with({id}), + })); - const collapseSidebars = slots.leftSidebarCollapse && slots.rightSidebarCollapse; + const leftSidebar = getSidebar('leftSidebar', 'sidebar-left'); + const rightSidebar = getSidebar('rightSidebar', 'sidebar-right'); - const hasID = (() => { - // Hilariously jank. Sorry! - const mainContentHTML = slots.mainContent.toString(); - return id => mainContentHTML.includes(`id="${id}"`); - })(); + const hasSidebarLeft = !html.isBlank(html.resolve(leftSidebar)); + const hasSidebarRight = !html.isBlank(html.resolve(rightSidebar)); const processSkippers = skipperList => skipperList @@ -583,15 +501,11 @@ export default { slots.secondaryNav, - html.tag('div', {class: 'layout-columns'}, - !collapseSidebars && - {class: 'vertical-when-thin'}, - - [ - sidebarLeftHTML, - mainHTML, - sidebarRightHTML, - ]), + html.tag('div', {class: 'layout-columns'}, [ + leftSidebar, + mainHTML, + rightSidebar, + ]), slots.bannerPosition === 'bottom' && slots.banner, |