This commit is contained in:
2026-04-22 14:58:18 +09:00
parent 4d618f3b22
commit ba04eaf573
6 changed files with 131 additions and 176 deletions
@@ -30,39 +30,50 @@
}
}
// ---- JSON-copy button (inside the JSON tab) ----
const copyJsonBtn = document.getElementById("tls-copy-json");
const rawJsonEl = document.getElementById("tls-raw-json");
if (copyJsonBtn && rawJsonEl) {
const origLabel = copyJsonBtn.textContent;
copyJsonBtn.addEventListener("click", async () => {
const text = rawJsonEl.textContent || "";
try {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(text);
} else {
const ta = document.createElement("textarea");
ta.value = text;
ta.style.position = "fixed";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
try { document.execCommand("copy"); } catch (_) {}
document.body.removeChild(ta);
}
copyJsonBtn.textContent = "コピーしました";
copyJsonBtn.classList.add("is-done");
setTimeout(() => {
copyJsonBtn.textContent = origLabel;
copyJsonBtn.classList.remove("is-done");
}, 1500);
} catch (_) {
copyJsonBtn.textContent = "コピー失敗";
setTimeout(() => { copyJsonBtn.textContent = origLabel; }, 1500);
// ---- Shared copy helper (clipboard API + textarea fallback) ----
async function copyText(text) {
try {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(text);
return true;
}
const ta = document.createElement("textarea");
ta.value = text;
ta.style.position = "fixed";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
try { document.execCommand("copy"); } catch (_) {}
document.body.removeChild(ta);
return true;
} catch (_) {
return false;
}
}
// Swap a button's label and is-done class for 1.5s based on action result.
function bindCopyButton(btn, getText) {
if (!btn) return;
const orig = btn.textContent;
btn.addEventListener("click", async () => {
const ok = await copyText(getText());
btn.textContent = ok ? "コピーしました" : "コピー失敗";
if (ok) btn.classList.add("is-done");
setTimeout(() => {
btn.textContent = orig;
btn.classList.remove("is-done");
}, 1500);
});
}
// ---- JSON-copy button (inside the JSON tab) ----
const rawJsonEl = document.getElementById("tls-raw-json");
bindCopyButton(document.getElementById("tls-copy-json"), () => (rawJsonEl && rawJsonEl.textContent) || "");
// ---- Copy-link button ----
const copyLinkBtn = document.getElementById("tls-copy-link");
bindCopyButton(copyLinkBtn, () => (copyLinkBtn && copyLinkBtn.dataset.link) || location.href);
// ---- PDF / print button ----
const printBtn = document.getElementById("tls-print-pdf");
if (printBtn) {
@@ -88,37 +99,4 @@
}
});
}
// ---- Copy-link button ----
const copyBtn = document.getElementById("tls-copy-link");
if (copyBtn) {
const origLabel = copyBtn.textContent;
copyBtn.addEventListener("click", async () => {
const link = copyBtn.dataset.link || location.href;
try {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(link);
} else {
// Fallback: use a hidden textarea + document.execCommand
const ta = document.createElement("textarea");
ta.value = link;
ta.style.position = "fixed";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
try { document.execCommand("copy"); } catch (_) {}
document.body.removeChild(ta);
}
copyBtn.textContent = "コピーしました";
copyBtn.classList.add("is-done");
setTimeout(() => {
copyBtn.textContent = origLabel;
copyBtn.classList.remove("is-done");
}, 1500);
} catch (_) {
copyBtn.textContent = "コピー失敗";
setTimeout(() => { copyBtn.textContent = origLabel; }, 1500);
}
});
}
})();
+25 -50
View File
@@ -1,11 +1,4 @@
/* =====================================================
* Nercone TLS Test — shared styles
* Palette comes from /public/assets/css/style.css
* #1A1A1A = page bg #272727 = block bg
* #202020 = input bg #3a3a3a = border
* #E0E0E0 = tx #939393 = light-grey-alt
* #00C878 = bright-green #00C0FF = bright-blue
* ===================================================== */
/* Nercone TLS Test — shared styles. Palette uses CSS vars from /assets/css/style.css. */
/* ------ Landing page ------ */
.tls-landing {
@@ -22,7 +15,6 @@
margin: 0 0 8px 0;
font-size: clamp(40pt, 6vw, 64pt);
line-height: 1.1;
color: #FFFFFF;
letter-spacing: -0.01em;
}
.tls-landing-subtitle {
@@ -40,21 +32,21 @@
flex: 1;
min-width: 0;
background-color: #3a3a3a;
color: #E0E0E0;
color: var(--color-light-grey);
border: 1px solid #4a4a4a;
border-radius: 6px;
padding: 12px 16px;
font-family: inherit;
font-size: 13pt;
}
.tls-landing-input::placeholder { color: #939393; }
.tls-landing-input::placeholder { color: var(--color-light-grey-alt); }
.tls-landing-input:focus {
outline: none;
border-color: #00C0FF;
border-color: var(--color-bright-blue);
}
.tls-landing-submit {
background-color: #0096D0;
color: #FFFFFF;
color: var(--color-white);
border: none;
border-radius: 6px;
padding: 12px 28px;
@@ -75,10 +67,10 @@
flex-wrap: wrap;
}
.tls-landing-links a {
color: #939393;
color: var(--color-light-grey-alt);
text-decoration: underline;
}
.tls-landing-links a:hover { color: #E0E0E0; }
.tls-landing-links a:hover { color: var(--color-light-grey); }
.tls-aux-section {
max-width: 900px;
@@ -110,9 +102,6 @@
.tls-status-testid {
margin: 10px 0 0 0;
}
.tls-status-testid code {
font-family: "MesloLGS Nerd Font", "MesloLGS NF", "Menlo", "Consolas", monospace;
}
.tls-progress-track {
width: 100%;
height: 6px;
@@ -122,7 +111,7 @@
}
.tls-progress-bar {
height: 100%;
background-color: #00C878;
background-color: var(--color-bright-green);
transition: width 0.25s ease;
}
@@ -130,7 +119,7 @@
.tls-log-wrap {
width: min(1100px, 100%);
margin: 0 auto;
background-color: #272727;
background-color: var(--color-dark-grey-alt);
border-radius: 8px;
padding: 18px 22px;
text-align: left;
@@ -183,10 +172,10 @@
.tls-results-header {
position: static;
display: block;
background-color: #272727;
background-color: var(--color-dark-grey-alt);
padding: 28px clamp(16px, 4vw, 40px) 0;
margin-bottom: 0;
border-bottom: 1px solid #1a1a1a;
border-bottom: 1px solid var(--color-dark-grey);
backdrop-filter: none;
}
.tls-results-header::before {
@@ -234,7 +223,6 @@
margin: 0 0 4px 0;
font-size: 22pt;
font-weight: 700;
color: #FFFFFF;
word-break: break-all;
}
.tls-results-metaline {
@@ -249,7 +237,6 @@
font-size: 10pt;
}
.tls-results-testid code {
font-family: "MesloLGS Nerd Font", "MesloLGS NF", "Menlo", "Consolas", monospace;
padding: 0;
}
.tls-results-actions {
@@ -271,15 +258,15 @@
}
.tls-btn-secondary {
background-color: #3a3a3a;
color: #E0E0E0;
color: var(--color-light-grey);
}
.tls-btn-secondary:hover { background-color: #4a4a4a; }
.tls-btn-primary {
background-color: #0096D0;
color: #FFFFFF;
color: var(--color-white);
}
.tls-btn-primary:hover { background-color: #00B4F0; }
.tls-btn-primary.is-done { background-color: #00A050; }
.tls-btn-primary.is-done { background-color: var(--color-green); }
/* Tabs — sit at the bottom of the results header banner. */
.tls-results-header .tls-tabs {
@@ -291,11 +278,11 @@
flex-wrap: wrap;
gap: 0;
margin: 12px 0 16px 0;
border-bottom: 1px solid #1a1a1a;
border-bottom: 1px solid var(--color-dark-grey);
}
.tls-tab {
background: transparent;
color: #939393;
color: var(--color-light-grey-alt);
border: none;
border-bottom: 2px solid transparent;
padding: 10px 18px 10px 18px;
@@ -305,12 +292,12 @@
margin-bottom: -1px;
}
.tls-tab:hover {
color: #E0E0E0;
color: var(--color-light-grey);
}
.tls-tab.is-active {
color: #FFFFFF;
color: var(--color-white);
font-weight: 600;
border-bottom-color: #E0E0E0;
border-bottom-color: var(--color-light-grey);
}
.tls-tab-panels {
padding: 0 clamp(16px, 4vw, 40px) 40px;
@@ -332,7 +319,6 @@
.tls-section-title {
font-size: 14pt;
font-weight: 600;
color: #FFFFFF;
margin: 0 0 10px 0;
padding-bottom: 6px;
border-bottom: 1px solid #3a3a3a;
@@ -346,7 +332,7 @@
background-color: #202020;
border-radius: 6px;
overflow: hidden;
color: #E0E0E0;
color: var(--color-light-grey);
}
.tls-table th,
.tls-table td {
@@ -357,7 +343,7 @@
}
.tls-table thead th {
background-color: #2a2a2a;
color: #939393;
color: var(--color-light-grey-alt);
font-weight: 500;
font-size: 10.5pt;
text-transform: uppercase;
@@ -368,7 +354,6 @@
border-bottom: none;
}
.tls-table code {
font-family: "MesloLGS Nerd Font", "MesloLGS NF", "Menlo", "Consolas", monospace;
font-size: 10.5pt;
background-color: transparent;
padding: 0;
@@ -381,7 +366,7 @@
.tls-cipher-version {
margin: 0 0 6px 0;
font-size: 11.5pt;
color: #E0E0E0;
color: var(--color-light-grey);
font-weight: 600;
}
.tls-cipher-list {
@@ -395,9 +380,8 @@
gap: 4px 16px;
}
.tls-cipher-list code {
font-family: "MesloLGS Nerd Font", "MesloLGS NF", "Menlo", "Consolas", monospace;
font-size: 10pt;
color: #E0E0E0;
color: var(--color-light-grey);
background: transparent;
padding: 0;
}
@@ -421,36 +405,28 @@
margin: 0;
}
.tls-raw code {
font-family: "MesloLGS Nerd Font", "MesloLGS NF", "Menlo", "Consolas", monospace;
white-space: pre;
background: transparent;
padding: 0;
}
/* ------------------------------------------------------------------
* Print stylesheet — "PDFをダウンロード" uses window.print() which
* lets the user save the page as a PDF from the browser print dialog.
* Hide chrome (tabs, buttons, site header/footer) and expand all tab
* panels so the resulting PDF contains every finding.
* ------------------------------------------------------------------ */
/* Print stylesheet — "PDFをダウンロード" uses window.print(). Hide chrome and
* expand all tab panels so the resulting PDF contains every finding. */
@media print {
html, body {
background: #ffffff !important;
color: #101010 !important;
}
/* Hide site-wide chrome and interactive controls. */
footer, .tls-tabs, .tls-results-actions,
#tls-copy-json, script, .tls-landing-links {
display: none !important;
}
/* Keep the results-header banner but make it paper-friendly. */
.tls-results-header {
background: transparent !important;
border: 0 !important;
padding: 0 0 16px 0 !important;
border-bottom: 1px solid #cccccc !important;
}
/* Expand every tab panel so the full report prints. */
.tls-tab-panels {
padding: 0 !important;
}
@@ -481,7 +457,6 @@
border-bottom: 1px dotted #cccccc;
padding: 4px 0;
}
/* Rank badge keeps its colour via currentColor. */
.tls-rank-badge {
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
+12 -21
View File
@@ -7,24 +7,15 @@
const logEl = document.getElementById("tls-log");
const verbEl = document.getElementById("tls-status-verb");
// Colors for the severity label tag. Order Good→Bad maps to
// bright-{green,blue,yellow,red,purple}. Matches SEVERITY_COLORS in
// schemas.py so the live log and results page render identically.
const SEV_COLOR = {
good: "bright-green",
normal: "bright-blue",
notgood: "bright-yellow",
bad: "bright-red",
serious: "bright-purple",
info: "light-grey-alt",
};
const SEV_LABEL = {
good: "GOOD",
normal: "NORMAL",
notgood: "NOT GOOD",
bad: "BAD",
serious: "SERIOUS",
info: "INFO",
// Severity label tag. Matches SEVERITY_COLORS in schemas.py so the live
// log and results page render identically.
const SEV = {
good: { color: "bright-green", label: "GOOD" },
normal: { color: "bright-blue", label: "NORMAL" },
notgood: { color: "bright-yellow", label: "NOT GOOD" },
bad: { color: "bright-red", label: "BAD" },
serious: { color: "bright-purple", label: "SERIOUS" },
info: { color: "light-grey-alt", label: "INFO" },
};
let reconnectAttempts = 0;
@@ -50,10 +41,10 @@
const msg = document.createElement("span");
msg.className = "tls-log-msg";
if (severity && SEV_LABEL[severity] && severity !== "info") {
if (severity && SEV[severity] && severity !== "info") {
const sev = document.createElement("span");
sev.className = "text-" + (SEV_COLOR[severity] || "light-grey") + " font-bold";
sev.textContent = SEV_LABEL[severity];
sev.className = "text-" + SEV[severity].color + " font-bold";
sev.textContent = SEV[severity].label;
msg.appendChild(sev);
msg.appendChild(document.createTextNode(" "));
}