diff --git a/include/layout.inc b/include/layout.inc index 30550b6a65..eea636a0f7 100644 --- a/include/layout.inc +++ b/include/layout.inc @@ -504,6 +504,18 @@ function site_footer(array $config = []): void require __DIR__ . "/footer.inc"; } +function checksum_html(string $checksum, string $algorithm = 'sha256'): string +{ + $checksum = htmlspecialchars($checksum, ENT_QUOTES, 'UTF-8'); + $algorithm = htmlspecialchars($algorithm, ENT_QUOTES, 'UTF-8'); + + if ($algorithm !== 'sha256') { + return '' . $checksum . ''; + } + + return '' . $checksum . ''; +} + function get_nav_items(): array { return [ new NavItem( diff --git a/include/version.inc b/include/version.inc index 31e4ff7a8a..0f59fcfd66 100644 --- a/include/version.inc +++ b/include/version.inc @@ -139,8 +139,12 @@ function show_source_releases() ', $rel['md5'], ''; - if (isset($rel['sha256'])) echo '', $rel['sha256'], ''; + if (isset($rel['md5'])) { + echo '', $rel['md5'], ''; + } + if (isset($rel['sha256'])) { + echo checksum_html($rel['sha256']); + } ?>
diff --git a/js/common.js b/js/common.js
index 86b4862fd5..fe45d50041 100644
--- a/js/common.js
+++ b/js/common.js
@@ -879,3 +879,18 @@ function applyTheme(theme) {
}
applyTheme(savedTheme)
+
+const downloads = document.querySelector('.downloads');
+downloads?.addEventListener('click', function (event) {
+ var button = event.target.closest('.sha256-copy');
+ if (!button || !navigator.clipboard) {
+ return;
+ }
+
+ navigator.clipboard.writeText(button.dataset.copyText).then(function () {
+ button.textContent = 'Copied';
+ setTimeout(function () {
+ button.textContent = 'Copy';
+ }, 1500);
+ });
+});
diff --git a/pre-release-builds.php b/pre-release-builds.php
index 868ed84d50..e7cca3ec09 100644
--- a/pre-release-builds.php
+++ b/pre-release-builds.php
@@ -97,9 +97,8 @@
-
-
+
No checksum value available)
@@ -189,7 +188,7 @@
}
if ($includeSha && $sha !== '') {
- $parts[] = '' . htmlspecialchars($sha, ENT_QUOTES, 'UTF-8') . '';
+ $parts[] = checksum_html($sha);
}
return '
";
}
}
diff --git a/styles/theme-base.css b/styles/theme-base.css
index faeab9d6b4..a6cd2fe9e9 100644
--- a/styles/theme-base.css
+++ b/styles/theme-base.css
@@ -789,14 +789,47 @@ fieldset {
overflow: hidden;
text-overflow: ellipsis;
}
-.content-box .md5sum:before {
+.content-box .md5sum:before,
+.downloads .md5sum:before {
content: "md5: ";
font-family: var(--font-family-sans-serif);
}
-.content-box .sha256:before {
+.content-box .sha256:before,
+.downloads .sha256:before {
content: "sha256: ";
font-family: var(--font-family-sans-serif);
}
+.content-box .sha256-row,
+.downloads .sha256-row {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+.content-box .sha256-row .sha256,
+.downloads .sha256-row .sha256 {
+ min-width: 0;
+}
+.content-box .sha256-copy,
+.downloads .sha256-copy {
+ border: 1px solid var(--dark-blue-color);
+ border-radius: 30px;
+ background-color: var(--dark-blue-color);
+ color: #fff;
+ padding: 0.2rem 0.65rem;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ cursor: pointer;
+ min-width: 4.25rem;
+ text-align: center;
+ white-space: nowrap;
+}
+.content-box .sha256-copy:hover,
+.content-box .sha256-copy:focus,
+.downloads .sha256-copy:hover,
+.downloads .sha256-copy:focus {
+ border-color: var(--dark-magenta-color);
+ background-color: var(--dark-magenta-color);
+}
.content-box .releasedate {
float: right;
font-size: 0.9rem;