« get me outta code hell

content, client, css: basic (absolute) datetimestamp tooltips - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-11-29 17:57:28 -0400
committer(quasar) nebula <qznebula@protonmail.com>2023-11-29 17:57:55 -0400
commita0fa6520c77e46b7a2e55b87e9994df3af74f149 (patch)
tree812480bd7f5d9c8222644f7082adb7d83f74c86b /src
parente156e337c29558b44e75e2d63494221823c5a9f9 (diff)
content, client, css: basic (absolute) datetimestamp tooltips
Diffstat (limited to 'src')
-rw-r--r--src/content/dependencies/generateAbsoluteDatetimestamp.js41
-rw-r--r--src/content/dependencies/generateDatetimestampTemplate.js28
-rw-r--r--src/static/client3.js53
-rw-r--r--src/static/site6.css59
4 files changed, 156 insertions, 25 deletions
diff --git a/src/content/dependencies/generateAbsoluteDatetimestamp.js b/src/content/dependencies/generateAbsoluteDatetimestamp.js
new file mode 100644
index 00000000..63acecf2
--- /dev/null
+++ b/src/content/dependencies/generateAbsoluteDatetimestamp.js
@@ -0,0 +1,41 @@
+export default {
+  contentDependencies: ['generateDatetimestampTemplate'],
+  extraDependencies: ['html', 'language'],
+
+  data: (date) =>
+    ({date}),
+
+  relations: (relation) =>
+    ({template: relation('generateDatetimestampTemplate')}),
+
+  slots: {
+    style: {
+      validate: v => v.is('full', 'year'),
+      default: 'full',
+    },
+
+    // Only has an effect for 'year' style.
+    tooltip: {
+      type: 'boolean',
+      default: false,
+    },
+  },
+
+  generate: (data, relations, slots, {language}) =>
+    relations.template.slots({
+      mainContent:
+        (slots.style === 'full'
+          ? language.formatDate(data.date)
+       : slots.style === 'year'
+          ? data.date.getFullYear().toString()
+          : null),
+
+      tooltipContent:
+        slots.tooltip &&
+        slots.style === 'year' &&
+          language.formatDate(data.date),
+
+      datetime:
+        data.date.toISOString(),
+    }),
+};
diff --git a/src/content/dependencies/generateDatetimestampTemplate.js b/src/content/dependencies/generateDatetimestampTemplate.js
new file mode 100644
index 00000000..bfba647f
--- /dev/null
+++ b/src/content/dependencies/generateDatetimestampTemplate.js
@@ -0,0 +1,28 @@
+export default {
+  extraDependencies: ['html'],
+
+  slots: {
+    mainContent: {type: 'html'},
+    tooltipContent: {type: 'html'},
+    datetime: {type: 'string'},
+  },
+
+  generate: (slots, {html}) =>
+    html.tag('span', {
+      [html.joinChildren]: '',
+
+      class: [
+        'datetimestamp',
+        slots.tooltipContent && 'has-tooltip',
+      ],
+    }, [
+      html.tag('time',
+        {datetime: slots.datetime},
+        slots.mainContent),
+
+      slots.tooltipContent &&
+        html.tag('span', {class: 'datetimestamp-tooltip'},
+          html.tag('span', {class: 'datetimestamp-tooltip-content'},
+            slots.tooltipContent)),
+    ]),
+};
diff --git a/src/static/client3.js b/src/static/client3.js
index 1e64ebe1..ce057712 100644
--- a/src/static/client3.js
+++ b/src/static/client3.js
@@ -1981,8 +1981,8 @@ for (const info of groupContributionsTableInfo) {
 // Artist link icon tooltips ------------------------------
 
 const externalIconTooltipInfo = clientInfo.externalIconTooltipInfo = {
-  hoverableLinks: null,
-  iconContainers: null,
+  hoverables: null,
+  tooltips: null,
 };
 
 function getExternalIconTooltipReferences() {
@@ -1991,21 +1991,19 @@ function getExternalIconTooltipReferences() {
   const spans =
     Array.from(document.querySelectorAll('span.contribution.has-tooltip'));
 
-  info.hoverableLinks =
-    spans
-      .map(span => span.querySelector('a'));
+  info.hoverables =
+    spans.map(span => span.querySelector('a'));
 
-  info.iconContainers =
-    spans
-      .map(span => span.querySelector('span.icons-tooltip'));
+  info.tooltips =
+    spans.map(span => span.querySelector('span.icons-tooltip'));
 }
 
 function addExternalIconTooltipPageListeners() {
   const info = externalIconTooltipInfo;
 
   for (const {hoverable, tooltip} of stitchArrays({
-    hoverable: info.hoverableLinks,
-    tooltip: info.iconContainers,
+    hoverable: info.hoverables,
+    tooltip: info.tooltips,
   })) {
     registerTooltipElement(tooltip);
     registerTooltipHoverableElement(hoverable, tooltip);
@@ -2015,6 +2013,41 @@ function addExternalIconTooltipPageListeners() {
 clientSteps.getPageReferences.push(getExternalIconTooltipReferences);
 clientSteps.addPageListeners.push(addExternalIconTooltipPageListeners);
 
+// Datetimestamp tooltips ---------------------------------
+
+const datetimestampTooltipInfo = clientInfo.datetimestampTooltipInfo = {
+  hoverables: null,
+  tooltips: null,
+};
+
+function getDatestampTooltipReferences() {
+  const info = datetimestampTooltipInfo;
+
+  const spans =
+    Array.from(document.querySelectorAll('span.datetimestamp.has-tooltip'));
+
+  info.hoverables =
+    spans.map(span => span.querySelector('time'));
+
+  info.tooltips =
+    spans.map(span => span.querySelector('span.datetimestamp-tooltip'));
+}
+
+function addDatestampTooltipPageListeners() {
+  const info = datetimestampTooltipInfo;
+
+  for (const {hoverable, tooltip} of stitchArrays({
+    hoverable: info.hoverables,
+    tooltip: info.tooltips,
+  })) {
+    registerTooltipElement(tooltip);
+    registerTooltipHoverableElement(hoverable, tooltip);
+  }
+}
+
+clientSteps.getPageReferences.push(getDatestampTooltipReferences);
+clientSteps.addPageListeners.push(addDatestampTooltipPageListeners);
+
 // Sticky commentary sidebar ------------------------------
 
 const albumCommentarySidebarInfo = clientInfo.albumCommentarySidebarInfo = {
diff --git a/src/static/site6.css b/src/static/site6.css
index 76b58f32..b7d5ce04 100644
--- a/src/static/site6.css
+++ b/src/static/site6.css
@@ -473,37 +473,51 @@ a:not([href]):hover {
   white-space: nowrap;
 }
 
-.contribution {
+.contribution.has-tooltip,
+.datetimestamp.has-tooltip {
   position: relative;
 }
 
-.contribution.has-tooltip > a {
+.contribution.has-tooltip > a,
+.datetimestamp.has-tooltip > time {
   text-decoration: underline;
   text-decoration-style: dotted;
 }
 
-.contribution.has-tooltip > a:hover,
-.contribution.has-tooltip > a.has-visible-tooltip {
-  text-decoration-style: wavy !important;
+.datetimestamp.has-tooltip > time {
+  cursor: default;
 }
 
-.icons {
-  font-style: normal;
-  white-space: nowrap;
+.contribution.has-tooltip > a:hover,
+.contribution.has-tooltip > a.has-visible-tooltip,
+.datetimestamp.has-tooltip > time:hover,
+.datetimestamp.has-tooltip > time.has-visible-tooltip {
+  text-decoration-style: wavy !important;
 }
 
-.icons-tooltip {
+.icons-tooltip,
+.datetimestamp-tooltip {
   position: absolute;
   z-index: 3;
   left: -34px;
   top: calc(1em + 1px);
-  padding: 3px 6px 6px 6px;
   display: none;
 }
 
-.icons-tooltip-content {
+.icons-tooltip {
+  padding: 3px 6px 6px 6px;
+  left: -34px;
+}
+
+.datetimestamp-tooltip {
+  padding: 3px 4px 2px 2px;
+  left: 14px;
+}
+
+.icons-tooltip-content,
+.datetimestamp-tooltip-content {
   display: block;
-  padding: 6px 2px 2px 2px;
+
   background: var(--bg-black-color);
   border: 1px dotted var(--primary-color);
   border-radius: 6px;
@@ -514,16 +528,31 @@ a:not([href]):hover {
           backdrop-filter:
     brightness(1.5) saturate(1.4) blur(4px);
 
-  -webkit-user-select: none;
-          user-select: none;
-
   box-shadow:
     0 3px 4px 4px #000000aa,
     0 -2px 4px -2px var(--primary-color) inset;
+}
+
+.icons-tooltip-content {
+  padding: 6px 2px 2px 2px;
+
+  -webkit-user-select: none;
+          user-select: none;
 
   cursor: default;
 }
 
+.datetimestamp-tooltip-content {
+  padding: 5px 6px;
+  white-space: nowrap;
+  font-size: 0.9em;
+}
+
+.icons {
+  font-style: normal;
+  white-space: nowrap;
+}
+
 .icons a:hover {
   filter: brightness(1.4);
 }