diff options
Diffstat (limited to 'src/content/dependencies/generatePageLayout.js')
| -rw-r--r-- | src/content/dependencies/generatePageLayout.js | 281 |
1 files changed, 177 insertions, 104 deletions
diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index a45f7415..00e6422b 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -1,27 +1,7 @@ import {openAggregate} from '#aggregate'; -import {empty, repeat} from '#sugar'; +import {atOffset, empty, repeat} from '#sugar'; export default { - contentDependencies: [ - 'generateColorStyleRules', - 'generateFooterLocalizationLinks', - 'generateImageOverlay', - 'generatePageSidebar', - 'generateSearchSidebarBox', - 'generateStickyHeadingContainer', - 'transformContent', - ], - - extraDependencies: [ - 'getColors', - 'html', - 'language', - 'pagePath', - 'pagePathStringFromRoot', - 'to', - 'wikiData', - ], - sprawl: ({wikiInfo}) => ({ enableSearch: wikiInfo.enableSearch, footerContent: wikiInfo.footerContent, @@ -45,6 +25,9 @@ export default { relations.stickyHeadingContainer = relation('generateStickyHeadingContainer'); + relations.titleText = + relation('generatePageTitleText'); + relations.sidebar = relation('generatePageSidebar'); @@ -58,8 +41,14 @@ export default { relation('transformContent', sprawl.footerContent); } - relations.colorStyleRules = - relation('generateColorStyleRules'); + relations.colorStyleTag = + relation('generateColorStyleTag'); + + relations.staticURLStyleTag = + relation('generateStaticURLStyleTag'); + + relations.wikiWallpaperStyleTag = + relation('generateWikiWallpaperStyleTag'); relations.imageOverlay = relation('generateImageOverlay'); @@ -73,6 +62,11 @@ export default { mutable: false, }, + titleDetail: { + type: 'html', + mutable: false, + }, + showWikiNameInTitle: { validate: v => v.is(true, false, 'auto'), default: 'auto', @@ -93,7 +87,7 @@ export default { mutable: false, }, - cover: { + artworkColumnContent: { type: 'html', mutable: false, }, @@ -107,9 +101,9 @@ export default { color: {validate: v => v.isColor}, - styleRules: { - validate: v => v.sparseArrayOf(v.isHTML), - default: [], + styleTags: { + type: 'html', + mutable: false, }, mainClasses: { @@ -262,29 +256,96 @@ export default { ? data.canonicalBase + pagePathStringFromRoot : null); - const titleContentsHTML = - (html.isBlank(slots.title) - ? null - : html.isBlank(slots.additionalNames) - ? language.sanitize(slots.title) - : html.tag('a', { - href: '#additional-names-box', - title: language.$('misc.additionalNames.tooltip').toString(), - }, language.sanitize(slots.title))); - - const titleHTML = - (html.isBlank(slots.title) - ? null - : slots.headingMode === 'sticky' - ? relations.stickyHeadingContainer.slots({ - title: titleContentsHTML, - cover: slots.cover, - }) - : html.tag('h1', titleContentsHTML)); + const primaryCover = (() => { + const apparentFirst = tag => html.smooth(tag).content[0]; + + const maybeTemplate = + apparentFirst(slots.artworkColumnContent); + + if (!maybeTemplate) return null; + + const maybeTemplateContent = + html.resolve(maybeTemplate, {normalize: 'tag'}); + + const maybeCoverArtwork = + apparentFirst(maybeTemplateContent); + + if (!maybeCoverArtwork) return null; + + if (maybeCoverArtwork.attributes.has('class', 'cover-artwork')) { + return maybeTemplate; + } else { + return null; + } + })(); + + const headingNamePart = + (() => { + if (html.isBlank(slots.title)) { + return html.blank(); + } + + if (!html.isBlank(slots.additionalNames)) { + const box = html.resolve(slots.additionalNames, {slots: ['alwaysVisible']}); + if (!box.getSlotValue('alwaysVisible')) { + return ( + html.tag('a', + {href: '#additional-names-box'}, + {title: language.$('misc.additionalNames.tooltip').toString()}, + language.sanitize(slots.title)) + ); + } + } + + return language.sanitize(slots.title); + })(); + + const headingContents = + language.encapsulate('misc.pageHeading', capsule => + language.encapsulate(capsule, workingCapsule => { + const workingOptions = { + [language.onlyIfOptions]: ['title'], + }; + + workingOptions.title = headingNamePart; + + if (!html.isBlank(slots.titleDetail)) { + workingCapsule += '.withDetail'; + workingOptions.detailAccent = + html.tag('span', {class: 'name-detail'}, + language.$(capsule, 'withDetail.accent', { + detail: slots.titleDetail, + })); + } + + return language.$(workingCapsule, workingOptions); + })); + + const headingHTML = + (() => { + if (html.isBlank(headingContents)) { + return html.blank(); + } + + if (slots.headingMode === 'sticky') { + return [ + relations.stickyHeadingContainer.slots({ + title: headingContents, + cover: primaryCover, + }), + + relations.stickyHeadingContainer.clone().slots({ + rootAttributes: {inert: true}, + }), + ]; + } + + return html.tag('h1', headingContents); + })(); // TODO: There could be neat interactions with the sticky heading here, // but for now subtitle is totally separate. - const subtitleHTML = + const subheadingHTML = (html.isBlank(slots.subtitle) ? null : html.tag('h2', {class: 'page-subtitle'}, @@ -304,17 +365,19 @@ export default { html.tag('main', {id: 'content'}, {class: slots.mainClasses}, - !html.isBlank(subtitleHTML) && + !html.isBlank(subheadingHTML) && {class: 'has-subtitle'}, [ - titleHTML, + headingHTML, - html.tag('div', {id: 'cover-art-container'}, + html.tag('div', {id: 'artwork-column'}, {[html.onlyIfContent]: true}, - slots.cover), + {class: 'isolate-tooltip-z-indexing'}, - subtitleHTML, + slots.artworkColumnContent), + + subheadingHTML, slots.additionalNames, @@ -355,7 +418,7 @@ export default { slots.navLinks ?.filter(Boolean) - ?.map((cur, i) => { + ?.map((cur, i, entries) => { let content; if (cur.html) { @@ -389,20 +452,13 @@ export default { (slots.navLinkStyle === 'hierarchical' && i === slots.navLinks.length - 1); - return ( + const navLink = html.tag('span', {class: 'nav-link'}, showAsCurrent && {class: 'current'}, [ html.tag('span', {class: 'nav-link-content'}, - // Use inline-block styling on the content span, - // rather than wrapping the whole nav-link in a proper - // blockwrap, so that if the content spans multiple - // lines, it'll kick the accent down beneath it. - i > 0 && - {class: 'blockwrap'}, - content), html.tag('span', {class: 'nav-link-accent'}, @@ -413,7 +469,25 @@ export default { [language.onlyIfOptions]: ['links'], links: cur.accent, })), - ])); + ]); + + if (slots.navLinkStyle === 'index') { + return navLink; + } + + const prev = + atOffset(entries, i, -1); + + if ( + prev && + prev.releaseRestToWrapTogether !== true && + (prev.releaseRestToWrapTogether === false || + prev.auto === 'home') + ) { + return navLink; + } else { + return html.metatag('blockwrap', navLink); + } })), html.tag('div', {class: 'nav-bottom-row'}, @@ -539,24 +613,33 @@ export default { {id: 'additional-files', string: 'additionalFiles'}, {id: 'commentary', string: 'commentary'}, {id: 'artist-commentary', string: 'artistCommentary'}, - {id: 'credit-sources', string: 'creditSources'}, + {id: 'crediting-sources', string: 'creditingSources'}, + {id: 'referencing-sources', string: 'referencingSources'}, ])), ]); - const styleRulesCSS = - html.resolve(slots.styleRules, {normalize: 'string'}); + const slottedStyleTags = + html.smush(slots.styleTags); + + const slottedWallpaperStyleTag = + slottedStyleTags.content + .find(tag => tag.attributes.has('class', 'wallpaper-style')); - const fallbackBackgroundStyleRule = - (styleRulesCSS.match(/body::before[^}]*background-image:/) - ? '' - : `body::before {\n` + - ` background-image: url("${to('media.path', 'bg.jpg')}");\n` + - `}`); + const fallbackWallpaperStyleTag = + (slottedWallpaperStyleTag + ? html.blank() + : relations.wikiWallpaperStyleTag); + + const usingWallpaperStyleTag = + (slottedWallpaperStyleTag + ? slottedWallpaperStyleTag + : html.resolve(fallbackWallpaperStyleTag, {normalize: 'tag'})); const numWallpaperParts = - html.resolve(slots.styleRules, {normalize: 'string'}) - .match(/\.wallpaper-part:nth-child/g) - ?.length ?? 0; + (usingWallpaperStyleTag && + usingWallpaperStyleTag.attributes.has('data-wallpaper-mode', 'parts') + ? parseInt(usingWallpaperStyleTag.attributes.get('data-num-wallpaper-parts')) + : 0); const wallpaperPartsHTML = html.tag('div', {class: 'wallpaper-parts'}, @@ -585,6 +668,13 @@ export default { footerHTML, ]; + relations.titleText.setSlots({ + title: slots.title, + detail: slots.titleDetail, + showWikiNameInTitle: slots.showWikiNameInTitle, + subtitle: slots.subtitle, + }); + const pageHTML = html.tags([ `<!DOCTYPE html>`, html.tag('html', @@ -609,30 +699,12 @@ export default { html.tag('head', [ html.tag('title', - language.encapsulate('misc.pageTitle', workingCapsule => { - const workingOptions = {}; - - workingOptions.title = slots.title; - - if (!html.isBlank(slots.subtitle)) { - workingCapsule += '.withSubtitle'; - workingOptions.subtitle = slots.subtitle; - } - - const showWikiName = - (slots.showWikiNameInTitle === true - ? true - : slots.showWikiNameInTitle === 'auto' - ? html.isBlank(slots.subtitle) - : false); + {'data-without-wiki-name': + relations.titleText.clone() + .slot('showWikiNameInTitle', false) + .toString()}, - if (showWikiName) { - workingCapsule += '.withWikiName'; - workingOptions.wikiName = data.wikiName; - } - - return language.$(workingCapsule, workingOptions); - })), + relations.titleText), html.tag('meta', {charset: 'utf-8'}), html.tag('meta', { @@ -698,16 +770,17 @@ export default { href: to('staticCSS.path', 'site.css'), }), - html.tag('style', [ - relations.colorStyleRules - .slot('color', slots.color ?? data.wikiColor), + relations.colorStyleTag + .slot('color', slots.color ?? data.wikiColor), - fallbackBackgroundStyleRule, - slots.styleRules, - ]), + relations.staticURLStyleTag, + + fallbackWallpaperStyleTag, + + slottedStyleTags, html.tag('script', { - src: to('staticLib.path', 'chroma-js/chroma.min.js'), + src: to('staticLib.path', 'chroma-js/chroma.min.cjs'), }), html.tag('script', { |