« get me outta code hell

content: generateWallpaperStyleTag & friends - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-05-27 17:23:41 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-05-27 17:23:41 -0300
commite5410e230d966bb041d5f92407fbc879fb8ac1ef (patch)
tree59c08d24f1b53ce2a04ef88815f9e7d94562ecc0
parent067dca6580cfd292db192267bf229c3de24e7654 (diff)
content: generateWallpaperStyleTag & friends
-rw-r--r--src/content/dependencies/generateAlbumCommentaryPage.js8
-rw-r--r--src/content/dependencies/generateAlbumGalleryPage.js8
-rw-r--r--src/content/dependencies/generateAlbumInfoPage.js8
-rw-r--r--src/content/dependencies/generateAlbumReferencedArtworksPage.js8
-rw-r--r--src/content/dependencies/generateAlbumReferencingArtworksPage.js8
-rw-r--r--src/content/dependencies/generateAlbumStyleRules.js107
-rw-r--r--src/content/dependencies/generateAlbumStyleTags.js65
-rw-r--r--src/content/dependencies/generateAlbumWallpaperStyleTag.js38
-rw-r--r--src/content/dependencies/generatePageLayout.js30
-rw-r--r--src/content/dependencies/generateReferencedArtworksPage.js4
-rw-r--r--src/content/dependencies/generateReferencingArtworksPage.js4
-rw-r--r--src/content/dependencies/generateStyleTag.js48
-rw-r--r--src/content/dependencies/generateTrackInfoPage.js8
-rw-r--r--src/content/dependencies/generateTrackReferencedArtworksPage.js8
-rw-r--r--src/content/dependencies/generateTrackReferencingArtworksPage.js8
-rw-r--r--src/content/dependencies/generateWallpaperStyleTag.js80
-rw-r--r--src/content/dependencies/generateWikiWallpaperStyleTag.js17
17 files changed, 288 insertions, 169 deletions
diff --git a/src/content/dependencies/generateAlbumCommentaryPage.js b/src/content/dependencies/generateAlbumCommentaryPage.js
index 1e39b47d..03b145f8 100644
--- a/src/content/dependencies/generateAlbumCommentaryPage.js
+++ b/src/content/dependencies/generateAlbumCommentaryPage.js
@@ -5,7 +5,7 @@ export default {
     'generateAlbumCommentarySidebar',
     'generateAlbumNavAccent',
     'generateAlbumSecondaryNav',
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateCommentaryEntry',
     'generateContentHeading',
     'generateCoverArtwork',
@@ -44,8 +44,8 @@ export default {
     relations.sidebar =
       relation('generateAlbumCommentarySidebar', album);
 
-    relations.albumStyleRules =
-      relation('generateAlbumStyleRules', album, null);
+    relations.albumStyleTags =
+      relation('generateAlbumStyleTags', album, null);
 
     relations.albumLink =
       relation('linkAlbum', album);
@@ -151,7 +151,7 @@ export default {
         headingMode: 'sticky',
 
         color: data.color,
-        styleRules: [relations.albumStyleRules],
+        styleTags: relations.albumStyleTags,
 
         mainClasses: ['long-content'],
         mainContent: [
diff --git a/src/content/dependencies/generateAlbumGalleryPage.js b/src/content/dependencies/generateAlbumGalleryPage.js
index 2ba3b272..516a7ca8 100644
--- a/src/content/dependencies/generateAlbumGalleryPage.js
+++ b/src/content/dependencies/generateAlbumGalleryPage.js
@@ -9,7 +9,7 @@ export default {
     'generateAlbumGalleryTrackGrid',
     'generateAlbumNavAccent',
     'generateAlbumSecondaryNav',
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateIntrapageDotSwitcher',
     'generatePageLayout',
     'linkAlbum',
@@ -46,8 +46,8 @@ export default {
     layout:
       relation('generatePageLayout'),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', album, null),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', album, null),
 
     albumLink:
       relation('linkAlbum', album),
@@ -106,7 +106,7 @@ export default {
         headingMode: 'static',
 
         color: data.color,
-        styleRules: [relations.albumStyleRules],
+        styleTags: relations.albumStyleTags,
 
         mainClasses: ['top-index'],
         mainContent: [
diff --git a/src/content/dependencies/generateAlbumInfoPage.js b/src/content/dependencies/generateAlbumInfoPage.js
index 671116b0..9a4ccfd2 100644
--- a/src/content/dependencies/generateAlbumInfoPage.js
+++ b/src/content/dependencies/generateAlbumInfoPage.js
@@ -11,7 +11,7 @@ export default {
     'generateAlbumSecondaryNav',
     'generateAlbumSidebar',
     'generateAlbumSocialEmbed',
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateAlbumTrackList',
     'generateCommentaryEntry',
     'generateContentHeading',
@@ -26,8 +26,8 @@ export default {
     layout:
       relation('generatePageLayout'),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', album, null),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', album, null),
 
     socialEmbed:
       relation('generateAlbumSocialEmbed', album),
@@ -104,7 +104,7 @@ export default {
 
         color: data.color,
         headingMode: 'sticky',
-        styleRules: [relations.albumStyleRules],
+        styleTags: relations.albumStyleTags,
 
         additionalNames: relations.additionalNamesBox,
 
diff --git a/src/content/dependencies/generateAlbumReferencedArtworksPage.js b/src/content/dependencies/generateAlbumReferencedArtworksPage.js
index 7586393c..52c78dc2 100644
--- a/src/content/dependencies/generateAlbumReferencedArtworksPage.js
+++ b/src/content/dependencies/generateAlbumReferencedArtworksPage.js
@@ -1,6 +1,6 @@
 export default {
   contentDependencies: [
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateBackToAlbumLink',
     'generateReferencedArtworksPage',
     'linkAlbum',
@@ -12,8 +12,8 @@ export default {
     page:
       relation('generateReferencedArtworksPage', album.coverArtworks[0]),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', album, null),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', album, null),
 
     albumLink:
       relation('linkAlbum', album),
@@ -35,7 +35,7 @@ export default {
             data.name,
         }),
 
-      styleRules: [relations.albumStyleRules],
+      styleTags: relations.albumStyleTags,
 
       navLinks: [
         {auto: 'home'},
diff --git a/src/content/dependencies/generateAlbumReferencingArtworksPage.js b/src/content/dependencies/generateAlbumReferencingArtworksPage.js
index d072d2f6..bc36ae06 100644
--- a/src/content/dependencies/generateAlbumReferencingArtworksPage.js
+++ b/src/content/dependencies/generateAlbumReferencingArtworksPage.js
@@ -1,6 +1,6 @@
 export default {
   contentDependencies: [
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateBackToAlbumLink',
     'generateReferencingArtworksPage',
     'linkAlbum',
@@ -12,8 +12,8 @@ export default {
     page:
       relation('generateReferencingArtworksPage', album.coverArtworks[0]),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', album, null),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', album, null),
 
     albumLink:
       relation('linkAlbum', album),
@@ -35,7 +35,7 @@ export default {
             data.name,
         }),
 
-      styleRules: [relations.albumStyleRules],
+      styleTags: relations.albumStyleTags,
 
       navLinks: [
         {auto: 'home'},
diff --git a/src/content/dependencies/generateAlbumStyleRules.js b/src/content/dependencies/generateAlbumStyleRules.js
deleted file mode 100644
index 6bfcc62e..00000000
--- a/src/content/dependencies/generateAlbumStyleRules.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import {empty, stitchArrays} from '#sugar';
-
-export default {
-  extraDependencies: ['to'],
-
-  data(album, track) {
-    const data = {};
-
-    data.hasWallpaper = !empty(album.wallpaperArtistContribs);
-    data.hasBanner = !empty(album.bannerArtistContribs);
-
-    if (data.hasWallpaper) {
-      if (!empty(album.wallpaperParts)) {
-        data.wallpaperMode = 'parts';
-
-        data.wallpaperPaths =
-          album.wallpaperParts.map(part =>
-            (part.asset
-              ? ['media.albumWallpaperPart', album.directory, part.asset]
-              : null));
-
-        data.wallpaperStyles =
-          album.wallpaperParts.map(part => part.style);
-      } else {
-        data.wallpaperMode = 'one';
-        data.wallpaperPath = ['media.albumWallpaper', album.directory, album.wallpaperFileExtension];
-        data.wallpaperStyle = album.wallpaperStyle;
-      }
-    }
-
-    if (data.hasBanner) {
-      data.hasBannerStyle = !!album.bannerStyle;
-      data.bannerStyle = album.bannerStyle;
-    }
-
-    data.albumDirectory = album.directory;
-
-    if (track) {
-      data.trackDirectory = track.directory;
-    }
-
-    return data;
-  },
-
-  generate(data, {to}) {
-    const indent = parts =>
-      (parts ?? [])
-        .filter(Boolean)
-        .join('\n')
-        .split('\n')
-        .map(line => ' '.repeat(4) + line)
-        .join('\n');
-
-    const rule = (selector, parts) =>
-      (!empty(parts.filter(Boolean))
-        ? [`${selector} {`, indent(parts), `}`]
-        : []);
-
-    const oneWallpaperRule =
-      data.wallpaperMode === 'one' &&
-        rule(`body::before`, [
-          `background-image: url("${to(...data.wallpaperPath)}");`,
-          data.wallpaperStyle,
-        ]);
-
-    const wallpaperPartRules =
-      data.wallpaperMode === 'parts' &&
-        stitchArrays({
-          path: data.wallpaperPaths,
-          style: data.wallpaperStyles,
-        }).map(({path, style}, index) =>
-            rule(`.wallpaper-part:nth-child(${index + 1})`, [
-              path && `background-image: url("${to(...path)}");`,
-              style,
-            ]));
-
-    const nukeBasicWallpaperRule =
-      data.wallpaperMode === 'parts' &&
-        rule(`body::before`, ['display: none']);
-
-    const wallpaperRules = [
-      oneWallpaperRule,
-      ...wallpaperPartRules || [],
-      nukeBasicWallpaperRule,
-    ];
-
-    const bannerRule =
-      data.hasBanner &&
-        rule(`#banner img`, [
-          data.bannerStyle,
-        ]);
-
-    const dataRule =
-      rule(`:root`, [
-        data.albumDirectory &&
-          `--album-directory: ${data.albumDirectory};`,
-        data.trackDirectory &&
-          `--track-directory: ${data.trackDirectory};`,
-      ]);
-
-    return (
-      [...wallpaperRules, bannerRule, dataRule]
-        .filter(Boolean)
-        .flat()
-        .join('\n'));
-  },
-};
diff --git a/src/content/dependencies/generateAlbumStyleTags.js b/src/content/dependencies/generateAlbumStyleTags.js
new file mode 100644
index 00000000..4cdc6581
--- /dev/null
+++ b/src/content/dependencies/generateAlbumStyleTags.js
@@ -0,0 +1,65 @@
+import {empty} from '#sugar';
+
+export default {
+  contentDependencies: ['generateAlbumWallpaperStyleTag', 'generateStyleTag'],
+  extraDependencies: ['html'],
+
+  relations: (relation, album, _track) => ({
+    styleTag:
+      relation('generateStyleTag'),
+
+    wallpaperStyleTag:
+      relation('generateAlbumWallpaperStyleTag', album),
+  }),
+
+  data(album, track) {
+    const data = {};
+
+    data.hasBanner = !empty(album.bannerArtistContribs);
+
+    if (data.hasBanner) {
+      data.hasBannerStyle = !!album.bannerStyle;
+      data.bannerStyle = album.bannerStyle;
+    }
+
+    data.albumDirectory = album.directory;
+
+    if (track) {
+      data.trackDirectory = track.directory;
+    }
+
+    return data;
+  },
+
+  generate: (data, relations, {html}) =>
+    html.tags([
+      relations.wallpaperStyleTag,
+
+      relations.styleTag.clone().slots({
+        attributes: {class: 'album-banner-style'},
+
+        rules: [
+          data.hasBanner && {
+            select: '#banner img',
+            declare: [data.bannerStyle],
+          },
+        ],
+      }),
+
+      relations.styleTag.clone().slots({
+        attributes: {class: 'album-directory-style'},
+
+        rules: [
+          {
+            select: ':root',
+            declare: [
+              data.albumDirectory &&
+                `--album-directory: ${data.albumDirectory};`,
+              data.trackDirectory &&
+                `--track-directory: ${data.trackDirectory};`,
+            ],
+          },
+        ]
+      }),
+    ], {[html.joinChildren]: ''}),
+};
diff --git a/src/content/dependencies/generateAlbumWallpaperStyleTag.js b/src/content/dependencies/generateAlbumWallpaperStyleTag.js
new file mode 100644
index 00000000..2c18deaf
--- /dev/null
+++ b/src/content/dependencies/generateAlbumWallpaperStyleTag.js
@@ -0,0 +1,38 @@
+export default {
+  contentDependencies: ['generateWallpaperStyleTag'],
+  extraDependencies: ['html'],
+
+  relations: (relation, album) => ({
+    wallpaperStyle:
+      (album.hasWallpaperArt
+        ? relation('generateWallpaperStyleTag')
+        : null),
+  }),
+
+  data: (album) => ({
+    singleWallpaperPath:
+      ['media.albumWallpaper', album.directory, album.wallpaperFileExtension],
+
+    singleWallpaperStyle:
+      album.wallpaperStyle,
+
+    wallpaperPartPaths:
+      album.wallpaperParts.map(part =>
+        (part.asset
+          ? ['media.albumWallpaperPart', album.directory, part.asset]
+          : null)),
+
+    wallpaperPartStyles:
+      album.wallpaperParts.map(part => part.style),
+  }),
+
+  generate: (data, relations, {html}) =>
+    (relations.wallpaperStyle
+      ? relations.wallpaperStyle.slots({
+          singleWallpaperPath: data.singleWallpaperPath,
+          singleWallpaperStyle: data.singleWallpaperStyle,
+          wallpaperPartPaths: data.wallpaperPartPaths,
+          wallpaperPartStyles: data.wallpaperPartStyles,
+        })
+      : html.blank()),
+};
diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js
index 147e2a5e..a0552454 100644
--- a/src/content/dependencies/generatePageLayout.js
+++ b/src/content/dependencies/generatePageLayout.js
@@ -115,11 +115,6 @@ export default {
 
     color: {validate: v => v.isColor},
 
-    styleRules: {
-      validate: v => v.sparseArrayOf(v.isHTML),
-      default: [],
-    },
-
     styleTags: {
       type: 'html',
       mutable: false,
@@ -599,28 +594,23 @@ export default {
             ])),
         ]);
 
-    const slottedStyleTags = html.tags([
-      slots.styleRules.map(rule => html.tag('style', rule)),
-      slots.styleTags,
-    ]);
+    const slottedStyleTags =
+      html.smush(slots.styleTags);
 
-    const styleTagsCSS =
-      html.smush(slottedStyleTags)
-        .content
-        .map(tag =>
-          html.resolve(tag.content, {normalize: 'string'}))
-        .join('\n\n');
+    const slottedWallpaperStyleTag =
+      slottedStyleTags.content
+        .find(tag => tag.attributes.has('class', 'wallpaper-style'));
 
     const fallbackWallpaperStyleTag =
-      (styleTagsCSS.match(/body::before[^}]*background-image:/)
+      (slottedWallpaperStyleTag
         ? ''
         : relations.wikiWallpaperStyleTag);
 
     const numWallpaperParts =
-      styleTagsCSS
-        .match(/\.wallpaper-part:nth-child/g)
-        ?.length ??
-      0;
+      (slottedWallpaperStyleTag &&
+       slottedWallpaperStyleTag.attributes.has('data-wallpaper-mode', 'parts')
+        ? parseInt(slottedWallpaperStyleTag.attributes.get('data-num-wallpaper-parts'))
+        : 0);
 
     const wallpaperPartsHTML =
       html.tag('div', {class: 'wallpaper-parts'},
diff --git a/src/content/dependencies/generateReferencedArtworksPage.js b/src/content/dependencies/generateReferencedArtworksPage.js
index 154b4762..83451eca 100644
--- a/src/content/dependencies/generateReferencedArtworksPage.js
+++ b/src/content/dependencies/generateReferencedArtworksPage.js
@@ -47,7 +47,7 @@ export default {
   }),
 
   slots: {
-    styleRules: {type: 'html', mutable: false},
+    styleTags: {type: 'html', mutable: false},
 
     title: {type: 'html', mutable: false},
 
@@ -62,7 +62,7 @@ export default {
         subtitle: language.$(pageCapsule, 'subtitle'),
 
         color: data.color,
-        styleRules: slots.styleRules,
+        styleTags: slots.styleTags,
 
         artworkColumnContent:
           relations.cover.slots({
diff --git a/src/content/dependencies/generateReferencingArtworksPage.js b/src/content/dependencies/generateReferencingArtworksPage.js
index 55977b37..e97b01f8 100644
--- a/src/content/dependencies/generateReferencingArtworksPage.js
+++ b/src/content/dependencies/generateReferencingArtworksPage.js
@@ -47,7 +47,7 @@ export default {
   }),
 
   slots: {
-    styleRules: {type: 'html', mutable: false},
+    styleTags: {type: 'html', mutable: false},
 
     title: {type: 'html', mutable: false},
 
@@ -62,7 +62,7 @@ export default {
         subtitle: language.$(pageCapsule, 'subtitle'),
 
         color: data.color,
-        styleRules: slots.styleRules,
+        styleTags: slots.styleTags,
 
         artworkColumnContent:
           relations.cover.slots({
diff --git a/src/content/dependencies/generateStyleTag.js b/src/content/dependencies/generateStyleTag.js
new file mode 100644
index 00000000..5ed09ae5
--- /dev/null
+++ b/src/content/dependencies/generateStyleTag.js
@@ -0,0 +1,48 @@
+import {empty} from '#sugar';
+
+const indent = text =>
+  text
+    .split('\n')
+    .map(line => ' '.repeat(4) + line)
+    .join('\n');
+
+export default {
+  extraDependencies: ['html'],
+
+  slots: {
+    attributes: {
+      type: 'attributes',
+      mutable: false,
+    },
+
+    rules: {
+      validate: v =>
+        v.looseArrayOf(
+          v.validateProperties({
+            select: v.isString,
+            declare: v.looseArrayOf(v.isString),
+          })),
+    },
+  },
+
+  generate: (slots, {html}) =>
+    html.tag('style', slots.attributes,
+      {[html.onlyIfContent]: true},
+
+      slots.rules
+        .filter(Boolean)
+
+        .map(rule => ({
+          select: rule.select,
+          declare: rule.declare.filter(Boolean),
+        }))
+
+        .filter(rule => !empty(rule.declare))
+
+        .map(rule =>
+          `${rule.select} {\n` +
+          indent(rule.declare.join('\n')) + '\n' +
+          `}`)
+
+        .join('\n\n')),
+};
diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js
index 1411406e..8d59f85f 100644
--- a/src/content/dependencies/generateTrackInfoPage.js
+++ b/src/content/dependencies/generateTrackInfoPage.js
@@ -5,7 +5,7 @@ export default {
     'generateAlbumNavAccent',
     'generateAlbumSecondaryNav',
     'generateAlbumSidebar',
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateCommentaryEntry',
     'generateContentHeading',
     'generateContributionList',
@@ -38,8 +38,8 @@ export default {
     layout:
       relation('generatePageLayout'),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', track.album, track),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', track.album, track),
 
     socialEmbed:
       relation('generateTrackSocialEmbed', track),
@@ -136,7 +136,7 @@ export default {
         additionalNames: relations.additionalNamesBox,
 
         color: data.color,
-        styleRules: [relations.albumStyleRules],
+        styleTags: relations.albumStyleTags,
 
         artworkColumnContent:
           relations.artworkColumn,
diff --git a/src/content/dependencies/generateTrackReferencedArtworksPage.js b/src/content/dependencies/generateTrackReferencedArtworksPage.js
index 93438c5b..7073409e 100644
--- a/src/content/dependencies/generateTrackReferencedArtworksPage.js
+++ b/src/content/dependencies/generateTrackReferencedArtworksPage.js
@@ -1,6 +1,6 @@
 export default {
   contentDependencies: [
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateBackToTrackLink',
     'generateReferencedArtworksPage',
     'generateTrackNavLinks',
@@ -12,8 +12,8 @@ export default {
     page:
       relation('generateReferencedArtworksPage', track.trackArtworks[0]),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', track.album, track),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', track.album, track),
 
     navLinks:
       relation('generateTrackNavLinks', track),
@@ -35,7 +35,7 @@ export default {
             data.name,
         }),
 
-      styleRules: [relations.albumStyleRules],
+      styleTags: relations.albumStyleTags,
 
       navLinks:
         html.resolve(
diff --git a/src/content/dependencies/generateTrackReferencingArtworksPage.js b/src/content/dependencies/generateTrackReferencingArtworksPage.js
index e9818bad..a45144c8 100644
--- a/src/content/dependencies/generateTrackReferencingArtworksPage.js
+++ b/src/content/dependencies/generateTrackReferencingArtworksPage.js
@@ -1,6 +1,6 @@
 export default {
   contentDependencies: [
-    'generateAlbumStyleRules',
+    'generateAlbumStyleTags',
     'generateBackToTrackLink',
     'generateReferencingArtworksPage',
     'generateTrackNavLinks',
@@ -12,8 +12,8 @@ export default {
     page:
       relation('generateReferencingArtworksPage', track.trackArtworks[0]),
 
-    albumStyleRules:
-      relation('generateAlbumStyleRules', track.album, track),
+    albumStyleTags:
+      relation('generateAlbumStyleTags', track.album, track),
 
     navLinks:
       relation('generateTrackNavLinks', track),
@@ -35,7 +35,7 @@ export default {
             data.name,
         }),
 
-      styleRules: [relations.albumStyleRules],
+      styleTags: relations.albumStyleTags,
 
       navLinks:
         html.resolve(
diff --git a/src/content/dependencies/generateWallpaperStyleTag.js b/src/content/dependencies/generateWallpaperStyleTag.js
new file mode 100644
index 00000000..bf094300
--- /dev/null
+++ b/src/content/dependencies/generateWallpaperStyleTag.js
@@ -0,0 +1,80 @@
+import {empty, stitchArrays} from '#sugar';
+
+export default {
+  contentDependencies: ['generateStyleTag'],
+  extraDependencies: ['html', 'to'],
+
+  relations: (relation) => ({
+    styleTag:
+      relation('generateStyleTag'),
+  }),
+
+  slots: {
+    singleWallpaperPath: {
+      validate: v => v.strictArrayOf(v.isString),
+    },
+
+    singleWallpaperStyle: {
+      validate: v => v.isString,
+    },
+
+    wallpaperPartPaths: {
+      validate: v =>
+        v.strictArrayOf(v.optional(v.strictArrayOf(v.isString))),
+    },
+
+    wallpaperPartStyles: {
+      validate: v =>
+        v.strictArrayOf(v.optional(v.isString)),
+    },
+  },
+
+  generate(relations, slots, {html, to}) {
+    const attributes = html.attributes();
+    const rules = [];
+
+    attributes.add('class', 'wallpaper-style');
+
+    if (empty(slots.wallpaperPartPaths)) {
+      attributes.set('data-wallpaper-mode', 'one');
+
+      rules.push({
+        select: 'body::before',
+        declare: [
+          `background-image: url("${to(...slots.singleWallpaperPath)}");`,
+          slots.singleWallpaperStyle,
+        ],
+      });
+    } else {
+      attributes.set('data-wallpaper-mode', 'parts');
+      attributes.set('data-num-wallpaper-parts', slots.wallpaperPartPaths.length);
+
+      stitchArrays({
+        path: slots.wallpaperPartPaths,
+        style: slots.wallpaperPartStyles,
+      }).forEach(({path, style}, index) => {
+          rules.push({
+            select: `.wallpaper-part:nth-child(${index + 1})`,
+            declare: [
+              path && `background-image: url("${to(...path)}");`,
+              style,
+            ],
+          });
+        });
+
+      rules.push({
+        select: 'body::before',
+        declare: [
+          'display: none;',
+        ],
+      });
+    }
+
+    relations.styleTag.setSlots({
+      attributes,
+      rules,
+    });
+
+    return relations.styleTag;
+  },
+};
diff --git a/src/content/dependencies/generateWikiWallpaperStyleTag.js b/src/content/dependencies/generateWikiWallpaperStyleTag.js
index 5c2a66c2..d29b1f8f 100644
--- a/src/content/dependencies/generateWikiWallpaperStyleTag.js
+++ b/src/content/dependencies/generateWikiWallpaperStyleTag.js
@@ -1,10 +1,16 @@
 export default {
-  extraDependencies: ['html', 'to', 'wikiData'],
+  contentDependencies: ['generateWallpaperStyleTag'],
+  extraDependencies: ['wikiData'],
 
   sprawl: ({wikiInfo}) => ({
     wikiWallpaperFileExtension: wikiInfo.wikiWallpaperFileExtension,
   }),
 
+  relations: (relation) => ({
+    wallpaperStyle:
+      relation('generateWallpaperStyleTag'),
+  }),
+
   data: (sprawl) => ({
     path: [
       'media.path',
@@ -12,9 +18,8 @@ export default {
     ],
   }),
 
-  generate: (data, {html, to}) =>
-    html.tag('style', {class: 'wiki-wallpaper-style'},
-      `body::before {\n` +
-      `    background-image: url("${to(...data.path)}");\n` +
-      `}`),
+  generate: (data, relations) =>
+    relations.wallpaperStyle.slots({
+      singleWallpaperPath: data.path,
+    }),
 };