mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-13 18:46:17 +05:00
2229 lines
95 KiB
HTML
2229 lines
95 KiB
HTML
{% load static tz core_tags %}
|
||
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<title>{{title}}</title>
|
||
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
|
||
<style>
|
||
/* Keep this inline, don't move to external css file because this template is used to generate static exports that need to be usable as-is without an accompanying staticfiles dir */
|
||
* { box-sizing: border-box; }
|
||
html, body {
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: #ddd;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
body {
|
||
display: flex;
|
||
flex-direction: column;
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||
}
|
||
a { color: inherit; text-decoration: none; }
|
||
a:hover { text-decoration: underline; }
|
||
.container-fluid { width: 100%; margin: 0 auto; padding: 0 12px; }
|
||
.row { display: flex; flex-wrap: wrap; width: 100%; margin: 0; }
|
||
.col-lg-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }
|
||
.col-lg-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }
|
||
.col-lg-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }
|
||
.col-lg-12 { flex: 0 0 100%; max-width: 100%; }
|
||
.badge { display: inline-block; padding: 2px 6px; border-radius: 4px; font-size: 12px; line-height: 1.2; }
|
||
.badge-default { background: rgba(255,255,255,0.2); color: #f6f6f6; }
|
||
.badge-info { background: #dbe7ff; color: #2b4aa0; }
|
||
.badge-success { background: #d4edda; color: #1e7e34; }
|
||
.badge-warning { background: #fff3cd; color: #856404; }
|
||
.badge-danger { background: #f8d7da; color: #721c24; }
|
||
.alert { padding: 6px 10px; border-radius: 6px; background: #f5f5f5; color: #333; }
|
||
header {
|
||
background-color: #aa1e55;
|
||
order: 1;
|
||
flex: 0 0 auto;
|
||
container-type: inline-size;
|
||
container-name: snapshot-header;
|
||
}
|
||
small {
|
||
font-weight: 200;
|
||
}
|
||
header a:hover {
|
||
text-decoration: none;
|
||
}
|
||
.header-top {
|
||
width: 100%;
|
||
height: auto;
|
||
min-height: 40px;
|
||
margin: 0px;
|
||
text-align: center;
|
||
color: #f6f6f6;
|
||
font-size: calc(10px + 0.44vw);
|
||
font-weight: 200;
|
||
padding: 3px 4px;
|
||
background-color: #aa1e55;
|
||
}
|
||
.header-top .header-nav {
|
||
display: grid;
|
||
grid-template-columns: auto minmax(0, 1fr) auto auto;
|
||
align-items: start;
|
||
gap: 16px;
|
||
width: 100%;
|
||
}
|
||
.header-top .header-col {
|
||
min-height: 30px;
|
||
line-height: 1.2;
|
||
min-width: 0;
|
||
}
|
||
.header-top .header-left {
|
||
white-space: nowrap;
|
||
}
|
||
.header-top .header-main {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 4px;
|
||
min-width: 0;
|
||
}
|
||
.header-top .header-meta {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
gap: 4px;
|
||
min-width: 0;
|
||
}
|
||
.header-top .header-right {
|
||
text-align: right;
|
||
white-space: nowrap;
|
||
padding-right: 10px;
|
||
}
|
||
.header-right .header-date {
|
||
text-align: center;
|
||
}
|
||
.header-right .snapshot-date-summary {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.header-right .snapshot-count-badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-width: 18px;
|
||
height: 18px;
|
||
padding: 0 5px;
|
||
border-radius: 999px;
|
||
background: rgba(255,255,255,0.18);
|
||
color: #f6f6f6;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
box-sizing: border-box;
|
||
}
|
||
.snapshot-variants {
|
||
position: relative;
|
||
display: inline-block;
|
||
white-space: nowrap;
|
||
}
|
||
.snapshot-variants summary {
|
||
list-style: none;
|
||
cursor: pointer;
|
||
color: #f6f6f6 !important;
|
||
}
|
||
.snapshot-variants summary:hover {
|
||
color: #f6f6f6 !important;
|
||
}
|
||
.header-top .snapshot-variants summary {
|
||
color: #f6f6f6 !important;
|
||
}
|
||
.snapshot-variants summary::-webkit-details-marker {
|
||
display: none;
|
||
}
|
||
.snapshot-variants-list {
|
||
position: absolute;
|
||
right: 0;
|
||
top: calc(100% + 6px);
|
||
background: rgba(18, 18, 18, 0.95);
|
||
border: 1px solid rgba(255,255,255,0.15);
|
||
border-radius: 8px;
|
||
min-width: 260px;
|
||
max-width: 420px;
|
||
max-height: 240px;
|
||
overflow: auto;
|
||
box-shadow: 0 6px 20px rgba(0,0,0,0.3);
|
||
z-index: 50;
|
||
padding: 6px;
|
||
}
|
||
.snapshot-variants-list a {
|
||
display: block;
|
||
padding: 6px 8px;
|
||
color: #f6f6f6;
|
||
font-size: 12px;
|
||
line-height: 1.3;
|
||
border-radius: 6px;
|
||
}
|
||
.snapshot-variants-list a:hover {
|
||
background: rgba(255,255,255,0.08);
|
||
color: #fff;
|
||
}
|
||
.header-top .snapshot-variants-list a {
|
||
color: #f6f6f6 !important;
|
||
}
|
||
.header-top .snapshot-variants-list a:hover {
|
||
color: #fff !important;
|
||
}
|
||
.year-variants summary {
|
||
list-style: none;
|
||
cursor: pointer;
|
||
}
|
||
.year-variants summary::-webkit-details-marker {
|
||
display: none;
|
||
}
|
||
.header-top .header-url {
|
||
width: 100%;
|
||
background-color: rgb(216, 216, 235, 0.05);
|
||
text-align: left;
|
||
line-height: 1.3;
|
||
font-family: monospace;
|
||
font-weight: 200;
|
||
margin-top: 0;
|
||
font-size: 23px;
|
||
opacity: 0.8;
|
||
border-radius: 0px 0px 8px 8px;
|
||
}
|
||
.header-top .header-url a.header-url-text {
|
||
display: block;
|
||
color: #f6f6f6;
|
||
user-select: all;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
padding: 2px 10px;
|
||
}
|
||
.header-top .header-url a.header-url-text:hover {
|
||
color: rgb(144, 161, 255);
|
||
}
|
||
.header-top a {
|
||
text-decoration: none;
|
||
color: rgba(0,0,0,0.6);
|
||
}
|
||
.header-top a:hover {
|
||
text-decoration: none;
|
||
color: rgba(0,0,0,0.9);
|
||
}
|
||
.header-title-line {
|
||
color: rgba(0,0,0,0.6);
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
min-width: 0;
|
||
width: 100%;
|
||
}
|
||
.header-title-text {
|
||
display: inline-block;
|
||
max-width: 100%;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
text-align: left;
|
||
}
|
||
.header-tags {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-start;
|
||
gap: 4px;
|
||
align-items: center;
|
||
}
|
||
.header-tags .tag-pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
padding: 3px 8px;
|
||
border-radius: 999px;
|
||
background: var(--tag-bg, rgba(255,255,255,0.2));
|
||
color: var(--tag-fg, #fff);
|
||
border: 1px solid var(--tag-border, rgba(255,255,255,0.26));
|
||
font-size: 12px;
|
||
line-height: 1.2;
|
||
white-space: nowrap;
|
||
}
|
||
.header-tags .permission-pill {
|
||
border-style: dashed;
|
||
text-transform: uppercase;
|
||
}
|
||
.header-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.header-mobile-badges {
|
||
display: none;
|
||
}
|
||
.badge-label,
|
||
.badge-mobile-text,
|
||
.header-date-label {
|
||
display: none;
|
||
}
|
||
.header-year-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
gap: 6px;
|
||
margin-top: 4px;
|
||
}
|
||
.header-top .favicon {
|
||
width: 20px;
|
||
height: 20px;
|
||
max-width: 30px;
|
||
max-height: 30px;
|
||
vertical-align: -4px;
|
||
margin-right: 6px;
|
||
object-fit: contain;
|
||
border-radius: 3px;
|
||
background: rgba(255,255,255,0.08);
|
||
}
|
||
.header-top .col-lg-4 {
|
||
text-align: center;
|
||
padding-top: 4px;
|
||
padding-bottom: 4px;
|
||
}
|
||
.header-archivebox img {
|
||
display: inline-block;
|
||
margin-right: 3px;
|
||
height: 30px;
|
||
margin-left: 12px;
|
||
margin-top: -4px;
|
||
margin-bottom: 2px;
|
||
}
|
||
.header-archivebox {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
white-space: nowrap;
|
||
}
|
||
.header-right .header-date {
|
||
display: inline-block;
|
||
white-space: nowrap;
|
||
}
|
||
.header-archivebox img:hover {
|
||
opacity: 0.5;
|
||
}
|
||
header small code {
|
||
white-space: nowrap;
|
||
font-weight: 200;
|
||
display: block;
|
||
margin-top: -1px;
|
||
font-size: 13px;
|
||
opacity: 0.8;
|
||
user-select: all;
|
||
}
|
||
.header-toggle {
|
||
line-height: 1;
|
||
font-size: 24px;
|
||
margin-top: 0;
|
||
margin-left: 4px;
|
||
}
|
||
@container snapshot-header (max-width: 900px) {
|
||
.header-top .header-nav {
|
||
grid-template-columns: 1fr;
|
||
gap: 8px;
|
||
}
|
||
.header-top .header-left,
|
||
.header-top .header-main,
|
||
.header-top .header-meta,
|
||
.header-top .header-right {
|
||
width: 100%;
|
||
text-align: left;
|
||
align-items: flex-start;
|
||
}
|
||
.header-archivebox img {
|
||
margin-left: 0;
|
||
}
|
||
}
|
||
@container snapshot-header (max-width: 900px) {
|
||
.header-top {
|
||
padding: 10px 12px 12px;
|
||
font-size: 14px;
|
||
text-align: left;
|
||
}
|
||
.header-top .header-nav {
|
||
gap: 10px;
|
||
}
|
||
.header-top .header-left {
|
||
order: 1;
|
||
padding-bottom: 2px;
|
||
}
|
||
.header-top .header-main {
|
||
order: 2;
|
||
gap: 8px;
|
||
}
|
||
.header-top .header-meta {
|
||
order: 3;
|
||
gap: 8px;
|
||
}
|
||
.header-top .header-right {
|
||
order: 4;
|
||
display: grid;
|
||
grid-template-columns: minmax(0, 1fr);
|
||
gap: 8px;
|
||
padding: 0 !important;
|
||
}
|
||
.header-archivebox {
|
||
color: #fff !important;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
.header-archivebox img {
|
||
width: 28px;
|
||
height: 28px;
|
||
margin: 0;
|
||
}
|
||
.header-top .header-url {
|
||
font-size: 15px;
|
||
background: rgba(0, 0, 0, 0.14);
|
||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||
border-radius: 7px;
|
||
}
|
||
.header-title-text,
|
||
.header-top .header-url a.header-url-text {
|
||
white-space: normal;
|
||
overflow: hidden;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
}
|
||
.header-top .header-url a.header-url-text {
|
||
padding: 7px 9px;
|
||
line-height: 1.35;
|
||
}
|
||
.header-title-line {
|
||
display: grid;
|
||
grid-template-columns: 22px minmax(0, 1fr) 28px;
|
||
gap: 7px;
|
||
align-items: center;
|
||
color: #fff;
|
||
}
|
||
.header-title-text {
|
||
grid-column: 2;
|
||
grid-row: 1;
|
||
color: #fff;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
line-height: 1.35;
|
||
}
|
||
.header-top .favicon {
|
||
grid-column: 1;
|
||
grid-row: 1;
|
||
width: 22px;
|
||
height: 22px;
|
||
margin: 0;
|
||
}
|
||
.header-tags {
|
||
grid-column: 1 / -1;
|
||
grid-row: 2;
|
||
width: 100%;
|
||
justify-content: flex-start;
|
||
}
|
||
.header-tags .tag-pill {
|
||
padding: 4px 8px;
|
||
font-size: 11px;
|
||
background: rgba(255, 255, 255, 0.15);
|
||
color: #fff;
|
||
}
|
||
.header-toggle {
|
||
grid-column: 3;
|
||
grid-row: 1;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 28px;
|
||
height: 28px;
|
||
margin: 0;
|
||
border-radius: 6px;
|
||
background: rgba(0, 0, 0, 0.14);
|
||
color: #fff !important;
|
||
font-size: 24px;
|
||
line-height: 1;
|
||
}
|
||
.header-badges {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 8rem), 1fr));
|
||
width: 100%;
|
||
gap: 6px;
|
||
}
|
||
header .header-badges .badge {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
min-width: 0;
|
||
min-height: 34px;
|
||
margin: 0;
|
||
padding: 6px 8px;
|
||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||
font-family: inherit;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
.badge-label,
|
||
.header-date-label {
|
||
display: inline;
|
||
margin-right: 6px;
|
||
color: currentColor;
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.04em;
|
||
opacity: 0.72;
|
||
text-transform: uppercase;
|
||
}
|
||
.badge-desktop-icon {
|
||
display: none;
|
||
}
|
||
.badge-mobile-text {
|
||
display: inline;
|
||
}
|
||
.header-year-badges {
|
||
width: 100%;
|
||
margin: 0;
|
||
padding: 1px 0 0;
|
||
justify-content: flex-start;
|
||
}
|
||
.header-year-badges::before {
|
||
content: "Years";
|
||
color: rgba(255, 255, 255, 0.7);
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
}
|
||
header .header-year-badges .badge {
|
||
margin: 0;
|
||
padding: 4px 7px;
|
||
font-size: 11px;
|
||
}
|
||
.header-right .header-date,
|
||
.header-right .snapshot-variants {
|
||
display: block;
|
||
width: 100%;
|
||
min-width: 0;
|
||
white-space: normal;
|
||
}
|
||
.header-right .snapshot-date-summary,
|
||
.header-right > .header-date {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
min-height: 34px;
|
||
padding: 6px 8px;
|
||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||
border-radius: 6px;
|
||
background: rgba(0, 0, 0, 0.12);
|
||
color: #fff !important;
|
||
gap: 7px;
|
||
}
|
||
.header-right br {
|
||
display: none;
|
||
}
|
||
header .external-links {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
width: 100%;
|
||
padding: 0;
|
||
color: #fff;
|
||
font-size: 12px;
|
||
text-align: left;
|
||
overflow: visible;
|
||
}
|
||
header .external-links a {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
min-height: 32px;
|
||
padding: 6px 9px;
|
||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||
border-radius: 6px;
|
||
background: rgba(0, 0, 0, 0.12);
|
||
color: #fff;
|
||
}
|
||
.external-links-separator {
|
||
display: none;
|
||
}
|
||
.snapshot-variants-list {
|
||
right: auto;
|
||
left: 0;
|
||
width: min(360px, calc(100vw - 24px));
|
||
min-width: 0;
|
||
}
|
||
}
|
||
@container snapshot-header (max-width: 480px) {
|
||
.header-top {
|
||
padding: 6px 8px 7px;
|
||
font-size: 12px;
|
||
}
|
||
.header-top .header-nav {
|
||
grid-template-columns: 22px minmax(0, 1fr);
|
||
gap: 6px;
|
||
}
|
||
.header-top .header-left {
|
||
grid-column: 1;
|
||
grid-row: 1;
|
||
min-height: 0;
|
||
padding-bottom: 0;
|
||
line-height: 1 !important;
|
||
}
|
||
.header-top .header-main {
|
||
display: contents;
|
||
}
|
||
.header-top .header-meta {
|
||
grid-column: 1 / -1;
|
||
grid-row: 3;
|
||
gap: 4px;
|
||
}
|
||
.header-top .header-right {
|
||
grid-column: 1 / -1;
|
||
grid-row: 4;
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
align-items: stretch;
|
||
gap: 4px;
|
||
}
|
||
.header-archivebox {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 22px;
|
||
height: 22px;
|
||
overflow: hidden;
|
||
font-size: 0;
|
||
line-height: 1;
|
||
}
|
||
.header-archivebox img {
|
||
display: block;
|
||
width: auto;
|
||
height: auto;
|
||
max-width: 20px;
|
||
max-height: 20px;
|
||
margin: 0;
|
||
object-fit: contain;
|
||
}
|
||
.header-top .header-url {
|
||
grid-column: 2;
|
||
grid-row: 1;
|
||
font-size: 13px;
|
||
}
|
||
.header-top .header-url a.header-url-text {
|
||
display: block;
|
||
padding: 5px 7px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.header-title-line {
|
||
grid-column: 1 / -1;
|
||
grid-row: 2;
|
||
grid-template-columns: 22px minmax(0, 1fr) 24px;
|
||
gap: 5px;
|
||
}
|
||
.header-top .favicon {
|
||
width: 18px;
|
||
height: 18px;
|
||
justify-self: center;
|
||
}
|
||
.header-title-text {
|
||
display: block;
|
||
font-size: 13px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.header-toggle {
|
||
width: 24px;
|
||
height: 24px;
|
||
font-size: 20px;
|
||
}
|
||
.header-tags {
|
||
gap: 3px;
|
||
}
|
||
.header-tags .tag-pill {
|
||
padding: 2px 6px;
|
||
font-size: 10px;
|
||
}
|
||
.header-badges {
|
||
display: none;
|
||
}
|
||
.header-mobile-badges {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
gap: 4px;
|
||
width: 100%;
|
||
}
|
||
.header-mobile-badge {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
min-width: 0;
|
||
min-height: 28px;
|
||
padding: 4px 7px;
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
border-radius: 6px;
|
||
background: rgba(255, 255, 255, 0.14);
|
||
color: #fff !important;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
}
|
||
.header-mobile-badge:last-child {
|
||
background: rgba(212, 237, 218, 0.96);
|
||
color: #315d3b !important;
|
||
}
|
||
.header-mobile-badge-separator {
|
||
margin: 0 5px;
|
||
opacity: 0.45;
|
||
}
|
||
.badge-label,
|
||
.header-date-label,
|
||
.header-year-badges::before {
|
||
font-size: 9px;
|
||
}
|
||
.header-year-badges {
|
||
display: none;
|
||
}
|
||
.header-right .snapshot-date-summary,
|
||
.header-right > .header-date {
|
||
height: 100%;
|
||
min-height: 32px;
|
||
padding: 4px 6px;
|
||
gap: 5px;
|
||
font-size: 11px;
|
||
font-family: inherit;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
}
|
||
.header-right .snapshot-date-summary > * {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
height: 16px;
|
||
margin: 0;
|
||
font-family: inherit;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
letter-spacing: 0;
|
||
text-transform: none;
|
||
opacity: 1;
|
||
}
|
||
.header-right > .snapshot-variants,
|
||
.header-right > .header-date {
|
||
grid-column: 2;
|
||
grid-row: 1;
|
||
height: 100%;
|
||
}
|
||
.header-right .snapshot-count-badge {
|
||
min-width: 16px;
|
||
height: 16px;
|
||
padding: 0 4px;
|
||
font-size: 9px;
|
||
}
|
||
header .external-links {
|
||
grid-column: 1;
|
||
grid-row: 1;
|
||
display: grid;
|
||
grid-template-columns: auto minmax(0, 1fr);
|
||
align-items: stretch;
|
||
gap: 4px;
|
||
font-size: 11px;
|
||
flex-wrap: nowrap;
|
||
height: 100%;
|
||
}
|
||
header .external-links a {
|
||
justify-content: center;
|
||
height: 100%;
|
||
min-height: 32px;
|
||
font-family: inherit;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
padding: 4px 7px;
|
||
}
|
||
}
|
||
|
||
.info-row {
|
||
margin-top: 2px;
|
||
margin-bottom: 5px;
|
||
}
|
||
.info-row .alert {
|
||
margin-bottom: 0px;
|
||
}
|
||
.row.header-bottom {
|
||
margin-left: -10px;
|
||
margin-right: -10px;
|
||
}
|
||
.header-bottom .col-lg-2 {
|
||
padding-left: 4px;
|
||
padding-right: 4px;
|
||
}
|
||
|
||
.header-bottom-frames .card {
|
||
box-shadow: 2px 2px 7px 0px rgba(0, 0, 0, 0.1);
|
||
margin-bottom: 6px;
|
||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||
border-radius: 10px;
|
||
background-color: #efefef;
|
||
overflow: hidden;
|
||
min-height: 130px;
|
||
}
|
||
.header-bottom-frames .card:has([data-compact]) {
|
||
min-height: 0;
|
||
}
|
||
.card h4 {
|
||
font-size: 0.8em;
|
||
display: inline-block;
|
||
width: auto;
|
||
text-transform: uppercase;
|
||
margin-top: 0px;
|
||
margin-bottom: 5px;
|
||
color: #222;
|
||
}
|
||
.card-body {
|
||
font-size: 14px;
|
||
padding: 4px 10px;
|
||
padding-bottom: 0px;
|
||
/* padding-left: 3px; */
|
||
/* padding-right: 3px; */
|
||
/* padding-bottom: 3px; */
|
||
line-height: 1;
|
||
word-wrap: break-word;
|
||
max-height: 102px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
color: #222;
|
||
background-color: #f6f6f6;
|
||
}
|
||
.card-title {
|
||
margin-bottom: 4px;
|
||
text-transform: uppercase;
|
||
}
|
||
.card-img-top {
|
||
border: 0px;
|
||
padding: 0px;
|
||
margin: 0px;
|
||
overflow: hidden;
|
||
opacity: 0.8;
|
||
border-top: 1px solid rgba(0,0,0,0);
|
||
border-radius: 4px;
|
||
border-bottom: 1px solid rgba(0,0,0,0);
|
||
height: 430px;
|
||
width: 405%;
|
||
margin-bottom: -330px;
|
||
background-color: #333;
|
||
margin-left: -1%;
|
||
margin-right: -1%;
|
||
pointer-events: none;
|
||
|
||
transform: scale(0.25);
|
||
transform-origin: 0 0;
|
||
}
|
||
#main-frame {
|
||
border-top: 1px solid #ddd;
|
||
width: 100%;
|
||
height: 100%;
|
||
margin: 0px;
|
||
border: 0px;
|
||
border-top: 3px solid #aa1e55;
|
||
}
|
||
#main-frame-wrapper {
|
||
width: 100%;
|
||
height: auto;
|
||
border-top: 3px solid #aa1e55;
|
||
overflow: hidden;
|
||
order: 2;
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
#main-frame-wrapper iframe {
|
||
width: 100%;
|
||
height: 100%;
|
||
border: none;
|
||
}
|
||
#snapshot-progress-wrapper {
|
||
flex: 0 0 auto;
|
||
width: 100%;
|
||
}
|
||
#main-frame-wrapper > #main-frame,
|
||
#main-frame-wrapper > #snapshot-empty-state {
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
}
|
||
.full-page-wrapper {
|
||
width: 100%;
|
||
min-height: 0;
|
||
}
|
||
.snapshot-empty-state {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: #f6f8fa;
|
||
color: #475569;
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||
}
|
||
.snapshot-empty-state-inner {
|
||
max-width: 520px;
|
||
padding: 32px 36px;
|
||
text-align: center;
|
||
}
|
||
.snapshot-empty-icon {
|
||
font-size: 56px;
|
||
line-height: 1;
|
||
margin-bottom: 12px;
|
||
}
|
||
.snapshot-empty-state h2 {
|
||
margin: 0 0 12px;
|
||
color: #1f2937;
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
}
|
||
.snapshot-empty-state p {
|
||
margin: 4px 0;
|
||
color: #64748b;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
}
|
||
.snapshot-empty-actions {
|
||
display: flex;
|
||
justify-content: center;
|
||
flex-wrap: wrap;
|
||
gap: 10px;
|
||
margin-top: 22px;
|
||
}
|
||
.snapshot-empty-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 8px 16px;
|
||
background: #ffffff;
|
||
border: 1px solid #d0d7de;
|
||
border-radius: 6px;
|
||
color: #1f2937;
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
text-decoration: none;
|
||
transition: background-color 0.15s, border-color 0.15s;
|
||
}
|
||
.snapshot-empty-btn:hover {
|
||
background: #eef4fa;
|
||
border-color: #b7d3ea;
|
||
color: #004882;
|
||
text-decoration: none;
|
||
}
|
||
.thumbnail-wrapper {
|
||
height: 100px;
|
||
overflow: hidden;
|
||
background-color: #f2f2f2;
|
||
pointer-events: none;
|
||
}
|
||
.thumbnail-wrapper.compact {
|
||
height: 32px;
|
||
background-color: #e9e9e9;
|
||
}
|
||
.thumbnail-wrapper iframe {
|
||
width: 405%;
|
||
height: 430px;
|
||
margin-bottom: -330px;
|
||
margin-left: -1%;
|
||
transform: scale(0.25);
|
||
transform-origin: 0 0;
|
||
border: none;
|
||
background: #fff;
|
||
}
|
||
.thumbnail-wrapper img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
object-position: top center;
|
||
}
|
||
.thumbnail-compact {
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 0 8px;
|
||
font-size: 13px;
|
||
line-height: 1;
|
||
color: #bdbdbd;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.02em;
|
||
}
|
||
.thumbnail-compact-label {
|
||
color: #e1e1e1;
|
||
}
|
||
.thumbnail-compact-meta {
|
||
color: #777;
|
||
font-size: 11px;
|
||
margin-left: auto;
|
||
}
|
||
.thumbnail-compact svg,
|
||
.thumbnail-compact img {
|
||
height: 12px;
|
||
width: 12px;
|
||
}
|
||
.thumbnail-text {
|
||
height: 100px;
|
||
background: #121212;
|
||
color: #d8d8d8;
|
||
padding: 6px 8px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||
font-size: 11px;
|
||
line-height: 1.2;
|
||
overflow: hidden;
|
||
}
|
||
.thumbnail-text-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 10px;
|
||
color: #9b9b9b;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.04em;
|
||
}
|
||
.thumbnail-text-pre {
|
||
margin: 0;
|
||
white-space: pre-wrap;
|
||
overflow: hidden;
|
||
display: -webkit-box;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 5;
|
||
}
|
||
.thumbnail-text[data-plugin="title"] .thumbnail-text-pre {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
-webkit-line-clamp: 3;
|
||
}
|
||
.card.selected-card {
|
||
border: 2px solid orange;
|
||
box-shadow: 0px -6px 13px 1px rgba(0,0,0,0.05);
|
||
}
|
||
.thumb-compact .card-body {
|
||
display: block;
|
||
padding: 4px 8px;
|
||
font-size: 12px;
|
||
line-height: 1.2;
|
||
max-height: none;
|
||
}
|
||
.thumb-compact {
|
||
margin-bottom: 0px;
|
||
border-radius: 6px;
|
||
}
|
||
.thumb-compact .thumbnail-wrapper {
|
||
height: 32px;
|
||
}
|
||
.thumb-compact .thumbnail-compact,
|
||
.thumb-compact .thumbnail-text {
|
||
height: 32px;
|
||
max-height: 32px;
|
||
}
|
||
.preview-hidden {
|
||
display: none !important;
|
||
}
|
||
img.external {
|
||
height: 30px;
|
||
margin-right: -10px;
|
||
padding: 3px;
|
||
border-radius: 4px;
|
||
vertical-align: middle;
|
||
border: 4px solid rgba(0,0,0,0);
|
||
}
|
||
img.external:hover {
|
||
border: 4px solid green;
|
||
}
|
||
.screenshot {
|
||
background-color: #333;
|
||
transform: scale(1.05);
|
||
transform-origin: top center;
|
||
width: 100%;
|
||
min-height: 100px;
|
||
max-height: 100px;
|
||
margin-bottom: 0px;
|
||
object-fit: cover;
|
||
object-position: top center;
|
||
}
|
||
.thumb-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(clamp(180px, 14vw, 250px), 1fr));
|
||
grid-auto-flow: row dense;
|
||
grid-auto-rows: 42px;
|
||
gap: 6px;
|
||
width: 100%;
|
||
max-width: 100%;
|
||
margin-left: 0;
|
||
padding: 2px 6px 0;
|
||
}
|
||
.thumb-card {
|
||
box-shadow: 2px 2px 7px 0px rgba(0, 0, 0, 0.1);
|
||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||
border-radius: 10px;
|
||
background-color: #efefef;
|
||
overflow: hidden;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
height: 138px;
|
||
min-height: 138px;
|
||
max-height: 138px;
|
||
display: inline-flex;
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
grid-row: span 3;
|
||
break-inside: avoid;
|
||
margin-bottom: 0;
|
||
vertical-align: top;
|
||
content-visibility: auto;
|
||
contain-intrinsic-size: 138px;
|
||
}
|
||
.thumb-card:not([data-plugin-name]) {
|
||
order: 1;
|
||
}
|
||
.thumb-card:has([data-compact]) {
|
||
height: 42px;
|
||
min-height: 42px;
|
||
max-height: 42px;
|
||
grid-row: span 1;
|
||
order: 2;
|
||
contain-intrinsic-size: 42px;
|
||
}
|
||
.thumb-card .thumb-body {
|
||
display: grid;
|
||
grid-template-columns: minmax(0, 1fr) auto;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 14px;
|
||
min-height: 30px;
|
||
padding: 4px 6px 4px 8px;
|
||
line-height: 1.2;
|
||
word-wrap: break-word;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
color: #222;
|
||
background-color: #f6f6f6;
|
||
flex: 0 0 auto;
|
||
position: relative;
|
||
}
|
||
.thumb-actions {
|
||
position: static;
|
||
grid-column: 2;
|
||
grid-row: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
opacity: 0.8;
|
||
}
|
||
.thumb-actions a,
|
||
.thumb-actions button {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 22px;
|
||
height: 22px;
|
||
border-radius: 5px;
|
||
background: #e7ebef;
|
||
text-decoration: none;
|
||
color: inherit;
|
||
border: 0;
|
||
cursor: pointer;
|
||
}
|
||
.thumb-actions a:hover,
|
||
.thumb-actions button:hover {
|
||
background: #d9e0e7;
|
||
opacity: 1;
|
||
}
|
||
.thumb-actions .delete-pending {
|
||
width: auto;
|
||
min-width: 22px;
|
||
color: #b91c1c;
|
||
font-weight: 700;
|
||
}
|
||
.thumb-card .thumb-body > a:not(.thumb-actions a),
|
||
.thumb-card .thumb-body > h4 {
|
||
grid-column: 1;
|
||
grid-row: 1;
|
||
min-width: 0;
|
||
}
|
||
.thumb-card .thumb-body h4 {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 2px;
|
||
font-size: 0.8em;
|
||
text-transform: uppercase;
|
||
margin: 0 0 2px 0;
|
||
color: #222;
|
||
line-height: 1.1;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.thumb-card .thumb-body h4 .abx-plugin-icon {
|
||
flex: 0 0 20px;
|
||
align-self: center;
|
||
line-height: 1;
|
||
vertical-align: middle;
|
||
transform: translateY(1px);
|
||
}
|
||
.thumb-card .thumbnail-wrapper,
|
||
.thumb-card iframe.card-img-top {
|
||
display: block;
|
||
width: 100%;
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
}
|
||
.thumb-card .thumbnail-wrapper {
|
||
display: flex;
|
||
align-items: stretch;
|
||
width: 100% !important;
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
box-sizing: border-box;
|
||
height: auto !important;
|
||
position: relative;
|
||
overflow: hidden;
|
||
pointer-events: auto;
|
||
}
|
||
.thumb-card .thumbnail-wrapper > *,
|
||
.thumb-card iframe.card-img-top {
|
||
width: 100% !important;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
max-width: 100%;
|
||
}
|
||
.thumb-card .card-img-top {
|
||
width: 100% !important;
|
||
max-width: 100% !important;
|
||
height: 100% !important;
|
||
margin: 0 !important;
|
||
transform: none !important;
|
||
opacity: 1 !important;
|
||
}
|
||
.thumb-card .thumbnail-wrapper img,
|
||
.thumb-card .thumbnail-wrapper video,
|
||
.thumb-card .thumbnail-wrapper canvas {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
max-width: 100% !important;
|
||
object-fit: cover;
|
||
transform: none !important;
|
||
margin: 0 !important;
|
||
}
|
||
.thumb-card .thumbnail-wrapper iframe,
|
||
.thumb-card .thumbnail-wrapper object,
|
||
.thumb-card .thumbnail-wrapper embed {
|
||
width: 405% !important;
|
||
height: 405% !important;
|
||
transform: scale(0.25);
|
||
transform-origin: 0 0;
|
||
margin: 0 !important;
|
||
border: 0 !important;
|
||
pointer-events: none;
|
||
}
|
||
.thumb-card iframe.card-img-top {
|
||
width: 405% !important;
|
||
height: 405% !important;
|
||
transform: scale(0.25);
|
||
transform-origin: 0 0;
|
||
margin: 0 !important;
|
||
border: 0 !important;
|
||
pointer-events: none;
|
||
}
|
||
.thumb-card .thumbnail-click-overlay {
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 2;
|
||
display: block;
|
||
background: transparent;
|
||
pointer-events: auto;
|
||
cursor: pointer;
|
||
}
|
||
.thumb-card .thumbnail-wrapper > :not(.thumbnail-click-overlay),
|
||
.thumb-card .thumbnail-wrapper > :not(.thumbnail-click-overlay) * {
|
||
pointer-events: none !important;
|
||
}
|
||
.thumb-card:has([data-compact]) .thumbnail-wrapper,
|
||
.thumb-card:has([data-compact]) .thumbnail-wrapper.compact {
|
||
height: 20px;
|
||
flex: 0 0 auto;
|
||
}
|
||
.thumb-card:has([data-compact]) .thumb-body {
|
||
min-height: 22px;
|
||
padding: 2px 4px 2px 6px;
|
||
font-size: 12px;
|
||
max-height: 24px;
|
||
}
|
||
.thumb-card:has([data-compact]) .thumb-actions a,
|
||
.thumb-card:has([data-compact]) .thumb-actions button {
|
||
width: 18px;
|
||
height: 18px;
|
||
border-radius: 4px;
|
||
}
|
||
.thumb-card:has([data-compact]) .thumb-actions .delete-pending {
|
||
width: auto;
|
||
}
|
||
.thumb-card:has([data-compact]) .thumb-body h4 {
|
||
font-size: 0.9em;
|
||
margin-bottom: 0px;
|
||
line-height: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.thumb-card:has([data-compact]) .thumbnail-text-header,
|
||
.thumb-card:has([data-compact]) .thumbnail-compact-icon,
|
||
.thumb-card:has([data-compact]) .thumbnail-compact-label {
|
||
display: none;
|
||
}
|
||
.thumb-card.selected-card {
|
||
border: 2px solid orange;
|
||
box-shadow: 0px -6px 13px 1px rgba(0,0,0,0.05);
|
||
content-visibility: visible;
|
||
}
|
||
.loose-items {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 4px 8px;
|
||
font-size: 12px;
|
||
line-height: 1.2;
|
||
max-height: 84px;
|
||
overflow: auto;
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
}
|
||
.loose-items a {
|
||
color: #333;
|
||
text-decoration: none;
|
||
background: rgba(0, 0, 0, 0.04);
|
||
padding: 2px 6px;
|
||
border-radius: 6px;
|
||
min-width: 0;
|
||
max-width: 100%;
|
||
overflow-wrap: anywhere;
|
||
word-break: break-word;
|
||
}
|
||
.loose-items a:hover {
|
||
background: rgba(0, 0, 0, 0.08);
|
||
}
|
||
.failed-items a {
|
||
color: #b91c1c;
|
||
background: rgba(185, 28, 28, 0.08);
|
||
}
|
||
.failed-items a:hover {
|
||
background: rgba(185, 28, 28, 0.16);
|
||
}
|
||
.header-bottom {
|
||
border-top: 1px solid rgba(170, 30, 85, 0.9);
|
||
padding-bottom: 1px;
|
||
border-bottom: 5px solid rgb(170, 30, 85);
|
||
margin-bottom: -1px;
|
||
|
||
border-radius: 0px;
|
||
background-color: #f4eeee;
|
||
border: 1px solid rgba(0,0,0,0.2);
|
||
box-shadow: 4px 4px 4px rgba(0,0,0,0.2);
|
||
margin-top: 0px;
|
||
}
|
||
.header-bottom.container-fluid {
|
||
padding-left: 6px;
|
||
padding-right: 6px;
|
||
}
|
||
.header-bottom-info {
|
||
color: #6f6f6f;
|
||
padding-top: 0px;
|
||
padding-bottom: 0px;
|
||
margin: 0px -15px;
|
||
}
|
||
|
||
.header-bottom-info > div {
|
||
text-align: center;
|
||
}
|
||
.header-bottom-info h5 {
|
||
font-size: 12px;
|
||
font-weight: 400;
|
||
margin-top: 3px;
|
||
margin-bottom: 3px;
|
||
}
|
||
.info-chunk {
|
||
width: auto;
|
||
display: inline-block;
|
||
text-align: center;
|
||
margin: 8px 4px;
|
||
vertical-align: top;
|
||
font-size: 14px;
|
||
}
|
||
header .badge {
|
||
margin-top: 3px;
|
||
font-size: 0.9rem;
|
||
font-weight: 200;
|
||
font-family: monospace;
|
||
}
|
||
header .internal-links {
|
||
text-align: left;
|
||
opacity: 1;
|
||
background-color: rgba(0,0,0,0.03);
|
||
padding: 1px 3px;
|
||
}
|
||
header .external-links {
|
||
text-align: center;
|
||
opacity: 0.9;
|
||
/*background-color: rgba(0,0,0,0.03);*/
|
||
margin-top: 0px;
|
||
padding: 1px 3px;
|
||
font-size: 14px;
|
||
color: #ddd;
|
||
width: 100%;
|
||
overflow: hidden;
|
||
}
|
||
.row.header-bottom-frames {
|
||
padding-top: 5px;
|
||
display: block !important;
|
||
width: 100%;
|
||
max-width: 100%;
|
||
column-width: 180px;
|
||
column-gap: 8px;
|
||
column-fill: auto;
|
||
margin-left: 0px;
|
||
margin-right: 0px;
|
||
flex: none !important;
|
||
}
|
||
.header-bottom-frames .col-lg-2 {
|
||
padding-left: 0px;
|
||
padding-right: 0px;
|
||
max-width: 100%;
|
||
width: 100% !important;
|
||
display: inline-block !important;
|
||
float: none !important;
|
||
flex: none !important;
|
||
break-inside: avoid;
|
||
margin-bottom: 6px;
|
||
vertical-align: top;
|
||
}
|
||
.header-bottom-frames .card:has([data-compact]) .thumbnail-wrapper,
|
||
.header-bottom-frames .card:has([data-compact]) .thumbnail-wrapper.compact {
|
||
height: 32px;
|
||
}
|
||
.header-bottom-frames .card:has([data-compact]) .thumbnail-text {
|
||
height: auto;
|
||
max-height: 64px;
|
||
}
|
||
.header-bottom-frames .card:has([data-compact]) .card-body {
|
||
padding: 4px 8px;
|
||
max-height: 44px;
|
||
}
|
||
.header-bottom-frames .card-title {
|
||
width: 100%;
|
||
text-align: center;
|
||
font-size: 17px;
|
||
margin-bottom: 0px;
|
||
display: inline-block;
|
||
color: #222;
|
||
font-weight: 200;
|
||
vertical-align: 3px;
|
||
}
|
||
.header-bottom-frames .card-text {
|
||
/* width: 100%;
|
||
text-align: center;*/
|
||
font-size: 0.9em;
|
||
display: inline-block;
|
||
position: relative;
|
||
/* top: -11px;*/
|
||
}
|
||
.card-text code {
|
||
padding: .1rem .2rem;
|
||
font-size: 90%;
|
||
color: #bd4147;
|
||
background-color: rgb(204, 204, 204, 0.28);
|
||
border-radius: .25rem;
|
||
}
|
||
|
||
/*@media(max-width: 1092px) {
|
||
iframe {
|
||
display: none;
|
||
}
|
||
}*/
|
||
|
||
|
||
@media(max-width: 728px) {
|
||
.card h4 {
|
||
font-size: 5vw;
|
||
}
|
||
.card-body {
|
||
font-size: 4vw;
|
||
}
|
||
.card {
|
||
margin-bottom: 5px;
|
||
}
|
||
header > h1 > a.header-url, header > h1 > a.header-archivebox {
|
||
display: none;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="main-frame-wrapper" class="full-page-wrapper" data-has-outputs="{{ has_outputs|yesno:'1,0' }}" data-snapshot-state="{{ snapshot_state }}">
|
||
{% if not STATIC_EXPORT %}
|
||
{% if snapshot_state == 'queued' or snapshot_state == 'started' or snapshot_state == 'paused' %}
|
||
<div id="snapshot-progress-wrapper">
|
||
{% include "progressmonitor/progress_monitor.html" with progress_endpoint=progress_endpoint progress_scope="snapshot" %}
|
||
</div>
|
||
{% endif %}
|
||
{% endif %}
|
||
{% if has_outputs %}
|
||
<iframe id="main-frame"
|
||
sandbox="allow-same-origin allow-top-navigation-by-user-activation allow-scripts allow-forms"
|
||
class="full-page-iframe"
|
||
src="about:blank"
|
||
data-default-src="{% if best_result.path %}{% snapshot_preview_url snapshot best_result.path %}{% elif STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}"
|
||
name="preview"
|
||
loading="eager"
|
||
fetchpriority="high"></iframe>
|
||
{% else %}
|
||
<div id="snapshot-empty-state" class="snapshot-empty-state" data-snapshot-state="{{ snapshot_state }}">
|
||
<div class="snapshot-empty-state-inner">
|
||
{% if snapshot_state == 'paused' %}
|
||
<div class="snapshot-empty-icon">⏸️</div>
|
||
<h2>Crawl paused</h2>
|
||
<p>This snapshot's crawl is paused — no extractors have run yet.</p>
|
||
<p>Resume the crawl to start archiving content.</p>
|
||
{% elif snapshot_state == 'started' %}
|
||
<div class="snapshot-empty-icon">⏳</div>
|
||
<h2>Archiving in progress…</h2>
|
||
<p>Extractors are running. Results will appear automatically.</p>
|
||
{% elif snapshot_state == 'queued' %}
|
||
<div class="snapshot-empty-icon">🕓</div>
|
||
<h2>Queued for archiving</h2>
|
||
<p>This snapshot is waiting in the queue. Results will appear automatically once a worker picks it up.</p>
|
||
{% else %}
|
||
<div class="snapshot-empty-icon">📭</div>
|
||
<h2>No archive outputs yet</h2>
|
||
<p>This snapshot has no archived content to display.</p>
|
||
{% endif %}
|
||
<div class="snapshot-empty-actions">
|
||
<button type="button" id="snapshot-empty-refresh" class="snapshot-empty-btn">🔄 Refresh page</button>
|
||
<a href="{{ url }}" target="_blank" rel="noopener noreferrer" class="snapshot-empty-btn">🌐 Open original URL</a>
|
||
{% if not STATIC_EXPORT %}
|
||
<a href="{% admin_base_url %}/admin/core/snapshot/{{ snapshot_id }}/change/" class="snapshot-empty-btn">✏️ Edit in admin</a>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
<script>
|
||
(() => {
|
||
const refreshBtn = document.getElementById('snapshot-empty-refresh');
|
||
if (refreshBtn) refreshBtn.addEventListener('click', () => location.reload());
|
||
const monitor = document.getElementById('progress-monitor');
|
||
if (!monitor) return;
|
||
const wrapper = document.getElementById('main-frame-wrapper');
|
||
const hasOutputs = wrapper && wrapper.dataset.hasOutputs === '1';
|
||
if (!hasOutputs) monitor.classList.remove('collapsed');
|
||
})();
|
||
</script>
|
||
<script>
|
||
(() => {
|
||
const frame = document.getElementById('main-frame')
|
||
if (!frame) return
|
||
const snapshotBaseUrlEarly = "{% snapshot_base_url snapshot %}"
|
||
const snapshotFilesUrlEarly = "{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}"
|
||
const defaultSrc = frame.dataset.defaultSrc || snapshotFilesUrlEarly
|
||
const rawHash = window.location.hash ? window.location.hash.slice(1) : ''
|
||
|
||
function resolveEarlyPreviewUrl(raw) {
|
||
if (!raw) return defaultSrc
|
||
let value = raw
|
||
try {
|
||
value = decodeURIComponent(value)
|
||
} catch (err) {}
|
||
if (value === 'all') return snapshotFilesUrlEarly
|
||
if (value.startsWith('http://') || value.startsWith('https://')) return value
|
||
if (value.startsWith('//')) return window.location.protocol + value
|
||
value = value.replace(/^\/+/, '')
|
||
return `${snapshotBaseUrlEarly}/${value}`
|
||
}
|
||
|
||
const target = resolveEarlyPreviewUrl(rawHash)
|
||
if (target) {
|
||
if (target.endsWith('.pdf')) {
|
||
frame.removeAttribute('sandbox')
|
||
}
|
||
frame.src = target
|
||
frame.dataset.initialSrc = target
|
||
}
|
||
})()
|
||
</script>
|
||
<header>
|
||
<div class="header-top">
|
||
<div class="header-nav">
|
||
<div class="header-col header-left" style="line-height: 58px; vertical-align: middle">
|
||
{% web_base_url as web_base %}
|
||
{% static_export_root_url as static_root %}
|
||
<a href="{% if STATIC_EXPORT %}{{ static_root }}index.html{% elif web_base %}{{ web_base }}/public/{% else %}/{% endif %}" class="header-archivebox" title="Go to Public Index...">
|
||
<img src="{% if STATIC_EXPORT %}data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><rect x='8' y='5' width='48' height='54' rx='7' fill='%23fff' opacity='.95'/><path d='M18 16h28M18 26h28M18 36h20M18 46h24' stroke='%23aa1e55' stroke-width='5' stroke-linecap='round'/></svg>{% elif web_base %}{{ web_base }}/static/archive.png{% else %}{% static 'archive.png' %}{% endif %}" alt="Archive Icon">
|
||
ArchiveBox
|
||
</a>
|
||
</div>
|
||
<div class="header-col header-main">
|
||
<div class="header-url">
|
||
<a class="header-url-text" href="{{url}}" title="Open original URL in new window..." target="_blank" rel="noreferrer">
|
||
{{url}}
|
||
</a>
|
||
</div>
|
||
<div class="header-title-line header-toggle-trigger">
|
||
{% snapshot_archiveresult_url snapshot 'favicon' 'favicon.ico' as header_favicon_url %}
|
||
{% if header_favicon_url %}
|
||
<img src="{{ header_favicon_url }}" onerror="this.onerror=null;this.src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='rgba(255,255,255,0.65)' stroke-width='1.4'><circle cx='10' cy='10' r='7.25'/><ellipse cx='10' cy='10' rx='3.25' ry='7.25'/><line x1='2.75' y1='10' x2='17.25' y2='10'/></svg>"" alt="Favicon" class="favicon"/>
|
||
{% else %}
|
||
<img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='rgba(255,255,255,0.65)' stroke-width='1.4'><circle cx='10' cy='10' r='7.25'/><ellipse cx='10' cy='10' rx='3.25' ry='7.25'/><line x1='2.75' y1='10' x2='17.25' y2='10'/></svg>" alt="Favicon" class="favicon"/>
|
||
{% endif %}
|
||
<span class="header-title-text">{{title|truncatechars:120}}</span>
|
||
{% if title_tags %}
|
||
<span class="header-tags">
|
||
<span class="tag-pill permission-pill">{{ snapshot_permissions_icon }} {{ snapshot_permissions }}</span>
|
||
{% for tag in title_tags %}
|
||
<span class="tag-pill" style="{{ tag.style }}">{{ tag.name }}</span>
|
||
{% endfor %}
|
||
</span>
|
||
{% else %}
|
||
<span class="header-tags">
|
||
<span class="tag-pill permission-pill">{{ snapshot_permissions_icon }} {{ snapshot_permissions }}</span>
|
||
</span>
|
||
{% endif %}
|
||
<a href="#" class="header-toggle">▾</a>
|
||
</div>
|
||
</div>
|
||
<div class="header-col header-meta">
|
||
<div class="header-badges">
|
||
<div class="badge badge-default" style="font-weight: 200">
|
||
<span class="badge-label">Outputs</span>
|
||
<span class="badge-value">
|
||
{{num_outputs}}
|
||
{% if num_failures %}
|
||
+ {{num_failures}} <small>errors</small>
|
||
{% endif %}
|
||
</span>
|
||
</div>
|
||
<div class="badge badge-info">
|
||
<span class="badge-label">Size</span>
|
||
{% if STATIC_EXPORT %}
|
||
<span class="badge-value">{{size}}</span>
|
||
{% else %}
|
||
<a class="badge-value" href="{% admin_base_url %}/admin/core/snapshot/{{snapshot_id|default:id}}/change/" title="Click to edit this Snapshot in the Admin UI">
|
||
{{size}}
|
||
</a>
|
||
{% endif %}
|
||
</div>
|
||
{% if not STATIC_EXPORT %}
|
||
<div class="badge badge-default">
|
||
<span class="badge-label">Manage</span>
|
||
<a class="badge-value" href="{% admin_base_url %}/admin/core/snapshot/{{snapshot_id|default:id}}/change/" title="Click to edit this Snapshot in the Admin UI">
|
||
<span class="badge-desktop-icon">✏️</span><span class="badge-mobile-text">Edit</span>
|
||
</a>
|
||
</div>
|
||
{% endif %}
|
||
<div class="badge badge-{{status_color}}">
|
||
<span class="badge-label">Status</span>
|
||
{% if STATIC_EXPORT %}
|
||
<span class="badge-value">{{status|upper}}</span>
|
||
{% else %}
|
||
<a class="badge-value" href="{% admin_base_url %}/admin/core/snapshot/?q={{snapshot_id|default:id}}" title="Click to see options to pull, re-snapshot, or delete this Snapshot">
|
||
{{status|upper}}
|
||
</a>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
<div class="header-mobile-badges">
|
||
<a class="header-mobile-badge" href="{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}" title="Browse all files for this snapshot">
|
||
<span>{{num_outputs}} Files</span>
|
||
<span class="header-mobile-badge-separator">|</span>
|
||
<span>{{size}}</span>
|
||
</a>
|
||
{% if not STATIC_EXPORT %}<a class="header-mobile-badge" href="{% admin_base_url %}/admin/core/snapshot/{{snapshot_id|default:id}}/change/" title="Edit this snapshot in the Admin UI">
|
||
<span>{{status|capfirst}}</span>
|
||
<span class="header-mobile-badge-separator">|</span>
|
||
<span>Edit</span>
|
||
</a>{% endif %}
|
||
</div>
|
||
{% if related_years %}
|
||
<div class="header-year-badges">
|
||
{% for entry in related_years %}
|
||
{% if entry.snapshots|length > 1 %}
|
||
<details class="snapshot-variants year-variants">
|
||
<summary class="badge badge-default">{{ entry.year }}</summary>
|
||
<div class="snapshot-variants-list">
|
||
{% for snap in entry.snapshots %}
|
||
<a href="{% snapshot_base_url snap %}/index.html" title="{{ snap.url }}">
|
||
{{ snap.bookmarked_at|default:snap.created_at|default:snap.downloaded_at|date:"Y-m-d H:i:s" }} 💾 {{ snap.output_size|filesizeformat }}
|
||
</a>
|
||
{% endfor %}
|
||
</div>
|
||
</details>
|
||
{% else %}
|
||
<div class="badge badge-default">
|
||
<a href="{% snapshot_base_url entry.latest %}/index.html" title="{{ entry.latest.url }}">
|
||
{{ entry.year }}
|
||
</a>
|
||
</div>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
<div class="header-col header-right" style="padding-top: 4px">
|
||
{% if related_snapshots %}
|
||
<details class="snapshot-variants">
|
||
<summary class="header-date" title="Click to see other snapshots for this URL">
|
||
<span class="snapshot-date-summary">
|
||
<span class="snapshot-count-badge">{{ related_snapshots|length }}</span>
|
||
<span class="header-date-label">Captures</span>
|
||
<span>{{oldest_archive_date|default:downloaded_datestr|default:bookmarked_date|slice:":10"}}</span>
|
||
</span>
|
||
</summary>
|
||
<div class="snapshot-variants-list">
|
||
{% for snap in related_snapshots %}
|
||
<a href="{% snapshot_base_url snap %}/index.html" title="{{ snap.url }}">
|
||
{{ snap.bookmarked_at|default:snap.created_at|default:snap.downloaded_at|date:"Y-m-d H:i:s" }} 💾 {{ snap.output_size|filesizeformat }}
|
||
</a>
|
||
{% endfor %}
|
||
</div>
|
||
</details>
|
||
{% else %}
|
||
<a class="header-date" href="{% snapshot_base_url snapshot %}/index.html" title="Date Added: {{bookmarked_date}} | First Archived: {{oldest_archive_date|default:downloaded_datestr}} | Last Checked: {{downloaded_datestr}} (UTC)">
|
||
<span class="header-date-label">Captures</span>
|
||
{{oldest_archive_date|default:downloaded_datestr|default:bookmarked_date|slice:":10"}}
|
||
</a>
|
||
{% endif %}
|
||
<br/>
|
||
<div class="external-links">
|
||
<a href="{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}" title="Browse the full SNAP_DIR for this snapshot" target="_blank">📁 {% if STATIC_EXPORT %}Snapshot manifest{% else %}See all files...{% endif %}</a>
|
||
<span class="external-links-separator">|</span>
|
||
<a href="https://web.archive.org/web/{{url}}" title="Search for a copy of the URL saved in Archive.org" target="_blank" rel="noreferrer">🏛️ Archive.org</a>
|
||
<!--<a href="https://archive.md/{{url}}" title="Search for a copy of the URL saved in Archive.today" target="_blank" rel="noreferrer">Archive.today</a> | -->
|
||
<!--<a href="https://ghostarchive.org/search?term={{url}}" title="Search for a copy of the URL saved in GhostArchive.org" target="_blank" rel="noreferrer">More...</a>-->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="header-bottom container-fluid">
|
||
<div class="thumb-grid">
|
||
|
||
|
||
{% for result in archiveresults %}
|
||
{% with display_path=result.path display_url='' preview_url='' %}
|
||
{% if display_path %}{% snapshot_url snapshot display_path as display_url %}{% endif %}
|
||
{% if display_path %}{% snapshot_preview_url snapshot display_path result.result as preview_url %}{% endif %}
|
||
<div class="thumb-card{% if forloop.first %} selected-card{% endif %}" data-plugin-name="{{result.name|plugin_name}}"{% if preview_url %} data-preview-url="{{preview_url}}"{% endif %}{% if display_path %} data-output-path="{{display_path}}"{% endif %}>
|
||
<div class="thumb-body">
|
||
<div class="thumb-actions">
|
||
{% if not STATIC_EXPORT %}<a href="{% snapshot_url snapshot result.name %}/?files=1" data-no-preview="1" title="Open output folder" target="_blank" rel="noopener">📁</a>{% endif %}
|
||
{% if display_path %}
|
||
<a href="{{display_url}}" data-no-preview="1" title="Download output file" download>⬇️</a>
|
||
{% endif %}
|
||
{% if can_delete_outputs and result.result %}
|
||
<button type="button" data-no-preview="1" data-archive-result-ids="{{result.result_ids}}" data-delete-url="{% admin_base_url %}/admin/core/archiveresult/" data-delete-handoff="1" data-delete-snapshot-id="{{snapshot.id}}" title="Delete this output">×</button>
|
||
{% endif %}
|
||
</div>
|
||
{% if display_path %}
|
||
<a href="{{preview_url}}" target="preview" title="./{{display_path}} (downloaded {{result.ts}})">
|
||
<h4>{% plugin_icon result.name %} {{result.name|plugin_name|truncatechars:20}}{% if result.size %} <small>({{result.size|filesizeformat}})</small>{% endif %}</h4>
|
||
</a>
|
||
{% else %}
|
||
<h4>{% plugin_icon result.name %} {{result.name|plugin_name|truncatechars:20}}{% if result.size %} <small>({{result.size|filesizeformat}})</small>{% endif %}</h4>
|
||
{% endif %}
|
||
{% if result.result %}
|
||
{% with plugin_base=result.name|plugin_name %}
|
||
{% if plugin_base == 'ytdlp' or plugin_base == 'yt-dlp' or plugin_base == 'youtube-dl' %}
|
||
{% plugin_card result.result %}
|
||
{% endif %}
|
||
{% endwith %}
|
||
{% endif %}
|
||
</div>
|
||
{% if result.result and display_path %}
|
||
{% with plugin_base=result.name|plugin_name %}
|
||
{% if plugin_base != 'ytdlp' and plugin_base != 'yt-dlp' and plugin_base != 'youtube-dl' %}
|
||
{# Use plugin-specific card template when ArchiveResult is available #}
|
||
<div class="card-img-top thumbnail-wrapper">
|
||
<a class="thumbnail-click-overlay" href="{{preview_url}}" target="preview" title="./{{display_path}} (downloaded {{result.ts}})" aria-label="Preview {{result.name|plugin_name}}"></a>
|
||
{% plugin_card result.result %}
|
||
</div>
|
||
{% else %}
|
||
{# YT-DLP renders its file list in the body #}
|
||
{% endif %}
|
||
{% endwith %}
|
||
{% elif result.is_metadata and display_path %}
|
||
<div class="card-img-top thumbnail-wrapper">
|
||
<a class="thumbnail-click-overlay" href="{{preview_url}}" target="preview" title="./{{display_path}}" aria-label="Preview {{result.name|plugin_name}}"></a>
|
||
{% output_card snapshot display_path result.name %}
|
||
</div>
|
||
{% elif display_path %}
|
||
{# Fall back to generic iframe for filesystem-discovered files #}
|
||
<div class="card-img-top thumbnail-wrapper">
|
||
<a class="thumbnail-click-overlay" href="{{preview_url}}" target="preview" title="./{{display_path}}" aria-label="Preview {{result.name|plugin_name}}"></a>
|
||
<iframe class="card-img-top" src="{{display_url}}?autoplay=0" allow="autoplay 'none'; fullscreen 'none'; navigation-override 'none'; " sandbox="allow-same-origin allow-top-navigation-by-user-activation allow-scripts allow-forms" scrolling="no" loading="lazy" fetchpriority="low"></iframe>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
{% endwith %}
|
||
{% endfor %}
|
||
{% if loose_items %}
|
||
<div class="thumb-card">
|
||
<div class="thumb-body">
|
||
<div class="thumb-actions">
|
||
<a href="{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}" data-no-preview="1" title="{% if STATIC_EXPORT %}Open snapshot manifest{% else %}Browse all snapshot files{% endif %}" target="_blank" rel="noopener">📁</a>
|
||
</div>
|
||
<h4>📦 Other files</h4>
|
||
<div class="loose-items">
|
||
{% for item in loose_items %}
|
||
{% if item.is_dir %}
|
||
<a href="{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_url snapshot item.path %}/?files=1{% endif %}" data-no-preview="1" target="_blank" rel="noopener">📁 {{item.name}}</a>
|
||
{% else %}
|
||
<a href="{% snapshot_url snapshot item.path %}" data-no-preview="1" target="_blank" rel="noopener">📄 {{item.name}}</a>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% if failed_items %}
|
||
<div class="thumb-card">
|
||
<div class="thumb-body">
|
||
<div class="thumb-actions">
|
||
<a href="{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}" data-no-preview="1" title="{% if STATIC_EXPORT %}Open snapshot manifest{% else %}Browse all snapshot files{% endif %}" target="_blank" rel="noopener">📁</a>
|
||
</div>
|
||
<h4>⚠️ Failed</h4>
|
||
<div class="loose-items failed-items">
|
||
{% for item in failed_items %}
|
||
{% if item.is_dir %}
|
||
<a href="{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_url snapshot item.path %}/?files=1{% endif %}" data-no-preview="1" target="_blank" rel="noopener">📁 {{item.name}}</a>
|
||
{% else %}
|
||
<a href="{% snapshot_url snapshot item.path %}" data-no-preview="1" target="_blank" rel="noopener">📄 {{item.name}}</a>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
{% if can_delete_outputs %}{% include "includes/output_delete_controls.html" %}{% endif %}
|
||
|
||
<script>
|
||
const snapshotBaseUrl = "{% snapshot_base_url snapshot %}";
|
||
const snapshotFilesUrl = "{% if STATIC_EXPORT %}{% snapshot_url snapshot 'index.jsonl' %}{% else %}{% snapshot_base_url snapshot %}/?files=1{% endif %}";
|
||
|
||
function tryCenterImageFrame(frame) {
|
||
try {
|
||
const doc = frame.contentDocument || frame.contentWindow.document
|
||
if (!doc || !doc.body || !doc.images || doc.images.length !== 1) {
|
||
return
|
||
}
|
||
const img = doc.images[0]
|
||
doc.documentElement.style.height = '100%'
|
||
doc.body.style.height = '100%'
|
||
doc.documentElement.style.width = '100%'
|
||
doc.body.style.width = '100%'
|
||
doc.body.style.minWidth = '100%'
|
||
doc.body.style.margin = '0'
|
||
doc.body.style.display = 'flex'
|
||
doc.body.style.flexDirection = 'column'
|
||
doc.body.style.alignItems = 'center'
|
||
doc.body.style.justifyContent = 'flex-start'
|
||
doc.body.style.overflowX = 'auto'
|
||
doc.body.style.background = '#fff'
|
||
img.style.maxWidth = '100%'
|
||
img.style.width = 'auto'
|
||
img.style.height = 'auto'
|
||
img.style.maxHeight = 'none'
|
||
img.style.display = 'block'
|
||
img.style.margin = '0 auto'
|
||
} catch (err) {}
|
||
}
|
||
|
||
function resetPreviewFrameSize(frame) {
|
||
const wrapper = document.getElementById('main-frame-wrapper')
|
||
if (!wrapper || !frame) return
|
||
wrapper.style.height = ''
|
||
wrapper.style.overflow = ''
|
||
frame.style.height = ''
|
||
}
|
||
|
||
function fitPreviewFrameToContent(frame) {
|
||
const wrapper = document.getElementById('main-frame-wrapper')
|
||
if (!wrapper || !frame || frame.src.includes('.pdf')) return
|
||
try {
|
||
const doc = frame.contentDocument || frame.contentWindow.document
|
||
if (!doc || !doc.documentElement) return
|
||
const candidates = [
|
||
doc.documentElement,
|
||
doc.body,
|
||
...doc.querySelectorAll('main, [role="main"], #doc, .ui-content, .markdown-body'),
|
||
].filter(Boolean)
|
||
const contentHeight = Math.ceil(Math.max(...candidates.map((element) => element.scrollHeight || 0)))
|
||
const minimumHeight = Math.max(window.innerHeight - wrapper.getBoundingClientRect().top, 320)
|
||
if (!Number.isFinite(contentHeight) || contentHeight <= minimumHeight + 4) {
|
||
resetPreviewFrameSize(frame)
|
||
return
|
||
}
|
||
wrapper.style.height = `${contentHeight}px`
|
||
wrapper.style.overflow = 'visible'
|
||
frame.style.height = `${contentHeight}px`
|
||
} catch (err) {
|
||
resetPreviewFrameSize(frame)
|
||
}
|
||
}
|
||
|
||
function attachPreviewFrameHandlers(frame) {
|
||
resetPreviewFrameSize(frame)
|
||
if (frame.src.endsWith('.pdf')) {
|
||
frame.removeAttribute('sandbox')
|
||
frame.src = frame.src + '#toolbar=0'
|
||
}
|
||
frame.onload = function() {
|
||
if (this.src.includes('.pdf')) {
|
||
this.removeAttribute('sandbox')
|
||
this.src = this.src.split('?autoplay=')[0] + '#toolbar=0'
|
||
}
|
||
tryCenterImageFrame(this)
|
||
try {
|
||
// doesnt work if frame origin rules prevent accessing its DOM via JS
|
||
this.contentWindow.scrollTo(0, 0);
|
||
} catch(err) {}
|
||
requestAnimationFrame(() => {
|
||
fitPreviewFrameToContent(this)
|
||
try {
|
||
if (this._archiveboxResizeObserver) this._archiveboxResizeObserver.disconnect()
|
||
this._archiveboxResizeObserver = new ResizeObserver(() => fitPreviewFrameToContent(this))
|
||
this._archiveboxResizeObserver.observe(this.contentDocument.documentElement)
|
||
} catch (err) {}
|
||
})
|
||
}
|
||
}
|
||
|
||
function setPreviewResourcePriority(root, highPriority=false) {
|
||
for (const iframe of root.querySelectorAll('iframe')) {
|
||
iframe.loading = highPriority ? 'eager' : 'lazy'
|
||
iframe.setAttribute('fetchpriority', highPriority ? 'high' : 'low')
|
||
attachPreviewFrameHandlers(iframe)
|
||
}
|
||
for (const img of root.querySelectorAll('img')) {
|
||
img.loading = highPriority ? 'eager' : 'lazy'
|
||
img.decoding = highPriority ? 'sync' : 'async'
|
||
img.setAttribute('fetchpriority', highPriority ? 'high' : 'low')
|
||
}
|
||
for (const video of root.querySelectorAll('video')) {
|
||
video.loading = highPriority ? 'eager' : 'lazy'
|
||
video.setAttribute('preload', highPriority ? 'metadata' : 'none')
|
||
}
|
||
}
|
||
|
||
function prioritizeCardThumbnail(card, highPriority=false) {
|
||
if (!card) {
|
||
return
|
||
}
|
||
setPreviewResourcePriority(card, highPriority)
|
||
}
|
||
|
||
function prepareThumbnailPriorities() {
|
||
const cards = [...document.querySelectorAll('.thumb-card')]
|
||
cards.forEach((card) => prioritizeCardThumbnail(card, card.classList.contains('selected-card')))
|
||
}
|
||
|
||
// un-sandbox iframes showing pdfs (required to display pdf viewer)
|
||
document.querySelectorAll('iframe').forEach((frame) => attachPreviewFrameHandlers(frame))
|
||
|
||
function getPreviewHashValueFromHref(href, normalize=false) {
|
||
if (href == './') {
|
||
return 'all'
|
||
}
|
||
if (!href) {
|
||
return ''
|
||
}
|
||
try {
|
||
const url = new URL(href, window.location.href)
|
||
let path = url.pathname || ''
|
||
if (snapshotBaseUrl) {
|
||
const baseUrl = new URL(snapshotBaseUrl, window.location.href)
|
||
const basePath = (baseUrl.pathname || '').replace(/\/+$/, '')
|
||
if (url.origin === baseUrl.origin && basePath && path.startsWith(`${basePath}/`)) {
|
||
path = path.slice(basePath.length + 1)
|
||
} else {
|
||
path = path.replace(/^\/+/, '')
|
||
}
|
||
} else {
|
||
path = path.replace(/^\/+/, '')
|
||
}
|
||
const searchParams = new URLSearchParams(url.search || '')
|
||
searchParams.delete('preview')
|
||
const search = searchParams.toString()
|
||
const suffix = `${search ? `?${search}` : ''}${url.hash || ''}`
|
||
const value = `${path}${suffix}`.replace(/^\/+/, '')
|
||
return normalize ? value.toLowerCase() : value
|
||
} catch (err) {
|
||
const value = href.replace(/^https?:\/\/[^/]+\/?/, '').replace(/^\/+/, '')
|
||
return normalize ? value.toLowerCase() : value
|
||
}
|
||
}
|
||
|
||
function getPreviewHashValue(link) {
|
||
return getPreviewHashValueFromHref((link && link.getAttribute('href')) || '', true)
|
||
}
|
||
|
||
function resolvePreviewUrl(raw) {
|
||
if (!raw) return ''
|
||
if (raw.startsWith('http://') || raw.startsWith('https://')) return raw
|
||
if (raw.startsWith('//')) return window.location.protocol + raw
|
||
if (!snapshotBaseUrl) return raw
|
||
return snapshotBaseUrl + (raw.startsWith('/') ? raw : `/${raw}`)
|
||
}
|
||
|
||
function isSnapshotRootPreview(urlValue) {
|
||
if (!urlValue || !snapshotBaseUrl) {
|
||
return false
|
||
}
|
||
try {
|
||
const target = new URL(urlValue, window.location.href)
|
||
const base = new URL(snapshotBaseUrl, window.location.href)
|
||
if (target.origin !== base.origin) {
|
||
return false
|
||
}
|
||
const basePath = (base.pathname || '').replace(/\/+$/, '')
|
||
const targetPath = (target.pathname || '').replace(/\/+$/, '')
|
||
return (
|
||
target.search !== "{% if STATIC_EXPORT %}{% else %}?files=1{% endif %}"
|
||
&& (
|
||
targetPath === basePath
|
||
|| targetPath === `${basePath}/index.html`
|
||
|| targetPath === `${basePath}/index.json`
|
||
)
|
||
)
|
||
} catch (err) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
function createMainFrame(previousFrame) {
|
||
const frame = document.createElement('iframe')
|
||
frame.id = 'main-frame'
|
||
frame.name = 'preview'
|
||
frame.className = 'full-page-iframe'
|
||
frame.sandbox = "allow-same-origin allow-top-navigation-by-user-activation allow-scripts allow-forms"
|
||
frame.loading = 'eager'
|
||
frame.setAttribute('fetchpriority', 'high')
|
||
attachPreviewFrameHandlers(frame)
|
||
return frame
|
||
}
|
||
|
||
function ensureMainFrame(forceReplace=false) {
|
||
let frame = document.getElementById('main-frame')
|
||
const wrapper = document.getElementById('main-frame-wrapper')
|
||
if (wrapper && wrapper.querySelector('#snapshot-empty-state')) {
|
||
return null
|
||
}
|
||
if (!frame || forceReplace) {
|
||
const previousFrame = frame
|
||
frame = createMainFrame(previousFrame)
|
||
if (previousFrame && previousFrame.parentNode) {
|
||
try {
|
||
previousFrame.src = 'about:blank'
|
||
} catch (err) {}
|
||
previousFrame.parentNode.replaceChild(frame, previousFrame)
|
||
} else if (wrapper) {
|
||
wrapper.innerHTML = ''
|
||
wrapper.appendChild(frame)
|
||
wrapper.classList.remove('full-page-wrapper')
|
||
}
|
||
}
|
||
const pluginWrapper = document.getElementById('plugin-full-wrapper')
|
||
if (pluginWrapper) {
|
||
pluginWrapper.classList.add('preview-hidden')
|
||
}
|
||
frame.classList.remove('preview-hidden')
|
||
return frame
|
||
}
|
||
|
||
function activateCardPreview(card, link, updateHash=true) {
|
||
if (!card) {
|
||
return false
|
||
}
|
||
prioritizeCardThumbnail(card, true)
|
||
const previewUrl = card.dataset.previewUrl
|
||
const rawTarget = previewUrl || (link ? link.getAttribute('href') : '') || ''
|
||
const target = resolvePreviewUrl(rawTarget)
|
||
if (!target || target.endsWith('#')) {
|
||
return false
|
||
}
|
||
|
||
document.querySelectorAll('.selected-card').forEach((selected) => selected.classList.remove('selected-card'))
|
||
card.closest('.thumb-card').classList.add('selected-card')
|
||
|
||
const nextSrc = isSnapshotRootPreview(target) ? snapshotFilesUrl : target
|
||
const existingFrame = document.getElementById('main-frame')
|
||
let currentSrc = ''
|
||
try {
|
||
currentSrc = existingFrame ? new URL(existingFrame.getAttribute('src') || existingFrame.src || '', window.location.href).href : ''
|
||
} catch (err) {}
|
||
let nextSrcAbs = nextSrc
|
||
try {
|
||
nextSrcAbs = new URL(nextSrc, window.location.href).href
|
||
} catch (err) {}
|
||
const iframe_elem = ensureMainFrame(currentSrc !== nextSrcAbs)
|
||
if (target.endsWith('.pdf')) {
|
||
iframe_elem.removeAttribute('sandbox')
|
||
} else {
|
||
iframe_elem.sandbox = "allow-same-origin allow-top-navigation-by-user-activation allow-scripts allow-forms"
|
||
}
|
||
if (rawTarget && updateHash) {
|
||
window.location.hash = getPreviewHashValueFromHref(rawTarget)
|
||
}
|
||
|
||
if (currentSrc !== nextSrcAbs) {
|
||
iframe_elem.src = nextSrc
|
||
}
|
||
return false
|
||
}
|
||
|
||
function handleCardClick(card, event) {
|
||
if (!event || event.defaultPrevented) {
|
||
return false
|
||
}
|
||
const targetEl = event.target.nodeType === Node.ELEMENT_NODE ? event.target : event.target.parentElement
|
||
if (targetEl && targetEl.closest('[data-no-preview]')) {
|
||
return true
|
||
}
|
||
const link = (targetEl && targetEl.closest('a[target=preview]')) || card.querySelector('a[target=preview]') || card.querySelector('a')
|
||
event.preventDefault()
|
||
if (typeof event.stopPropagation === 'function') {
|
||
event.stopPropagation()
|
||
}
|
||
if (typeof event.stopImmediatePropagation === 'function') {
|
||
event.stopImmediatePropagation()
|
||
}
|
||
return activateCardPreview(card, link)
|
||
}
|
||
|
||
function findPreviewLinkForHash(hashValue) {
|
||
if (!hashValue) {
|
||
return null
|
||
}
|
||
const previewLinks = [...document.querySelectorAll('a[target=preview]')]
|
||
const pathMatch = previewLinks.find((link) => getPreviewHashValue(link) == hashValue)
|
||
if (pathMatch) {
|
||
return pathMatch
|
||
}
|
||
const pluginCard = [...document.querySelectorAll('.thumb-card[data-plugin-name]')].find(
|
||
(card) => (card.dataset.pluginName || '').toLowerCase() == hashValue,
|
||
)
|
||
return pluginCard && pluginCard.querySelector('a[target=preview]')
|
||
}
|
||
|
||
function selectInitialPreview() {
|
||
const selectedPreviewHash = window.location.hash ? decodeURIComponent(window.location.hash.slice(1)).toLowerCase() : ''
|
||
const matchingLink = findPreviewLinkForHash(selectedPreviewHash)
|
||
if (matchingLink) {
|
||
return activateCardPreview(matchingLink.closest('.thumb-card'), matchingLink, false)
|
||
}
|
||
|
||
const selectedCard = document.querySelector('.thumb-card.selected-card') || document.querySelector('.thumb-card')
|
||
const selectedLink = selectedCard && (selectedCard.querySelector('a[target=preview]') || selectedCard.querySelector('a'))
|
||
if (selectedCard && selectedLink) {
|
||
return activateCardPreview(selectedCard, selectedLink, false)
|
||
}
|
||
|
||
const frame = ensureMainFrame(false)
|
||
const defaultSrc = frame && frame.dataset.defaultSrc
|
||
if (frame && defaultSrc && (!frame.src || frame.src === 'about:blank')) {
|
||
frame.src = defaultSrc
|
||
}
|
||
return false
|
||
}
|
||
|
||
for (const card of [...document.querySelectorAll('.thumb-card')]) {
|
||
card.addEventListener('click', function(event) {
|
||
if (event.target && event.target.closest('a')) {
|
||
return
|
||
}
|
||
handleCardClick(card, event)
|
||
})
|
||
for (const link of card.querySelectorAll('a')) {
|
||
link.addEventListener('click', function(event) {
|
||
handleCardClick(card, event)
|
||
})
|
||
}
|
||
}
|
||
|
||
function hideSnapshotHeader() {
|
||
console.log('Collapsing Snapshot header...')
|
||
document.querySelectorAll('.header-toggle').forEach((toggle) => { toggle.textContent = '▸' })
|
||
document.querySelectorAll('.header-bottom').forEach((header) => { header.hidden = true })
|
||
try {
|
||
localStorage.setItem("archivebox-snapshot-header-visible", "false")
|
||
} catch (e) {
|
||
console.log('Could not use localStorage to persist header collapse state', e)
|
||
}
|
||
}
|
||
function showSnapshotHeader() {
|
||
console.log('Expanding Snapshot header...')
|
||
document.querySelectorAll('.header-toggle').forEach((toggle) => { toggle.textContent = '▾' })
|
||
document.querySelectorAll('.header-bottom').forEach((header) => { header.hidden = false })
|
||
try {
|
||
localStorage.setItem("archivebox-snapshot-header-visible", "true")
|
||
} catch (e) {
|
||
console.log('Could not use localStorage to persist header collapse state', e)
|
||
}
|
||
}
|
||
function loadSnapshotHeaderState() {
|
||
// collapse snapshot header if user has previously hidden it
|
||
let snapshotHeaderIsExpanded = 'false'
|
||
try {
|
||
snapshotHeaderIsExpanded = localStorage.getItem("archivebox-snapshot-header-visible") || 'false'
|
||
} catch (e) {
|
||
console.log('Could not use localStorage to get header collapse state', e)
|
||
}
|
||
if (snapshotHeaderIsExpanded === 'false') {
|
||
hideSnapshotHeader()
|
||
}
|
||
}
|
||
function handleSnapshotHeaderToggle(event) {
|
||
event.preventDefault()
|
||
if ([...document.querySelectorAll('.header-toggle')].some((toggle) => toggle.textContent.includes('▾'))) {
|
||
hideSnapshotHeader()
|
||
} else {
|
||
showSnapshotHeader()
|
||
}
|
||
return true
|
||
}
|
||
|
||
// Hide or show the header once when its title row or collapse icon is clicked.
|
||
document.querySelectorAll('.header-toggle-trigger').forEach((trigger) => trigger.addEventListener('click', handleSnapshotHeaderToggle))
|
||
|
||
// check URL for hash e.g. #git and load relevant preview
|
||
selectInitialPreview()
|
||
prepareThumbnailPriorities()
|
||
loadSnapshotHeaderState()
|
||
|
||
|
||
|
||
// hide all preview iframes on small screens
|
||
// if (window.innerWidth < 1091) {
|
||
// jQuery('.card a[target=preview]').attr('target', '_self')
|
||
// }
|
||
</script>
|
||
</body>
|
||
</html>
|