|
1193 | 1193 | flex: 0 0 auto; |
1194 | 1194 | } |
1195 | 1195 |
|
| 1196 | +.md-output-options { |
| 1197 | + display: flex; |
| 1198 | + flex-wrap: wrap; |
| 1199 | + align-items: center; |
| 1200 | + gap: 12px; |
| 1201 | +} |
| 1202 | + |
| 1203 | +.md-secondary-button { |
| 1204 | + display: inline-flex; |
| 1205 | + align-items: center; |
| 1206 | + gap: 0.42rem; |
| 1207 | + appearance: none; |
| 1208 | + border: 1px solid #d0d7e5; |
| 1209 | + border-radius: 999px; |
| 1210 | + background: #f8fbff; |
| 1211 | + color: #28405f; |
| 1212 | + padding: 0.42rem 0.72rem; |
| 1213 | + font-size: 0.8rem; |
| 1214 | + font-weight: 600; |
| 1215 | + line-height: 1.1; |
| 1216 | + cursor: pointer; |
| 1217 | + transition: background 150ms ease, border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease; |
| 1218 | +} |
| 1219 | + |
| 1220 | +.md-secondary-button:hover { |
| 1221 | + background: #eef6ff; |
| 1222 | + border-color: #b7c9df; |
| 1223 | + transform: translateY(-1px); |
| 1224 | + box-shadow: 0 4px 10px rgba(40, 64, 95, 0.10); |
| 1225 | +} |
| 1226 | + |
| 1227 | +.md-secondary-button__icon { |
| 1228 | + width: 1.08rem; |
| 1229 | + height: 1.08rem; |
| 1230 | + flex: 0 0 auto; |
| 1231 | +} |
| 1232 | + |
1196 | 1233 | .md-code-block { |
1197 | 1234 | position: relative; |
1198 | 1235 | margin-top: 0.5rem; |
|
1331 | 1368 | <rect x="9" y="9" width="11" height="11" rx="2"/> |
1332 | 1369 | <rect x="4" y="4" width="11" height="11" rx="2"/> |
1333 | 1370 | </symbol> |
| 1371 | + <symbol id="md-icon-link" viewBox="0 0 24 24"> |
| 1372 | + <path d="M9.88 14.12a3 3 0 0 1 0-4.24l2-2a3 3 0 1 1 4.24 4.24l-.71.71"/> |
| 1373 | + <path d="M14.12 9.88a3 3 0 0 1 0 4.24l-2 2a3 3 0 1 1-4.24-4.24l.71-.71"/> |
| 1374 | + </symbol> |
1334 | 1375 | <symbol id="md-icon-trash" viewBox="0 0 24 24"> |
1335 | 1376 | <path d="M3 6h18"/> |
1336 | 1377 | <path d="M8 6V4h8v2"/> |
|
1401 | 1442 | <div id="promptOutputHelp" class="md-output-help"></div> |
1402 | 1443 | </div> |
1403 | 1444 | <lht-command-block command-id="promptOutput"></lht-command-block> |
1404 | | - <lht-switch-help |
1405 | | - switch-id="includeLabelPrefix" |
1406 | | - label="ラベル名を先頭に含める" |
1407 | | - help-label="ラベル名を先頭に含める説明"> |
1408 | | - ON の場合は `[ボタンラベル] 本文` の形式で出力します。OFF の場合は本文のみを出力します。 |
1409 | | - </lht-switch-help> |
| 1445 | + <div class="md-output-options"> |
| 1446 | + <lht-switch-help |
| 1447 | + switch-id="includeLabelPrefix" |
| 1448 | + label="ラベル名を先頭に含める" |
| 1449 | + help-label="ラベル名を先頭に含める説明"> |
| 1450 | + ON の場合は `[ボタンラベル] 本文` の形式で出力します。OFF の場合は本文のみを出力します。 |
| 1451 | + </lht-switch-help> |
| 1452 | + <button id="copyShareLinkButton" type="button" class="md-secondary-button"> |
| 1453 | + <svg viewBox="0 0 24 24" class="md-secondary-button__icon" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
| 1454 | + <use href="#md-icon-link" xlink:href="#md-icon-link"></use> |
| 1455 | + </svg> |
| 1456 | + <span>共有リンクをコピー</span> |
| 1457 | + </button> |
| 1458 | + </div> |
1410 | 1459 | </section> |
1411 | 1460 |
|
1412 | 1461 | <lht-toast id="toast"></lht-toast> |
|
6703 | 6752 | const commitIdInput = document.getElementById("commitId"); |
6704 | 6753 | const subjectInput = document.getElementById("subjectInput"); |
6705 | 6754 | const includeLabelPrefix = document.getElementById("includeLabelPrefix"); |
| 6755 | + const copyShareLinkButton = document.getElementById("copyShareLinkButton"); |
6706 | 6756 | const promptOutput = document.getElementById("promptOutput"); |
6707 | | - if (!promptSearch || !commitIdInput || !subjectInput || !includeLabelPrefix || !promptOutput || !promptCandidateArea || !commitInputSection || !subjectInputSection || !promptOutputSection || !promptOutputTitle || !promptOutputHelp) { |
| 6757 | + if (!promptSearch || !commitIdInput || !subjectInput || !includeLabelPrefix || !copyShareLinkButton || !promptOutput || !promptCandidateArea || !commitInputSection || !subjectInputSection || !promptOutputSection || !promptOutputTitle || !promptOutputHelp) { |
6708 | 6758 | return; |
6709 | 6759 | } |
6710 | 6760 | function loadSeriesVisibilitySettings() { |
|
7249 | 7299 | } |
7250 | 7300 | return includeLabelPrefix.checked ? `[${label}] ${body}` : body; |
7251 | 7301 | } |
| 7302 | + function buildShareLink() { |
| 7303 | + const url = new URL(window.location.href); |
| 7304 | + url.search = ""; |
| 7305 | + const query = (promptSearch.value || "").trim(); |
| 7306 | + const subject = subjectInput.value || ""; |
| 7307 | + const commitId = commitIdInput.value || ""; |
| 7308 | + if (query) { |
| 7309 | + url.searchParams.set("q", query); |
| 7310 | + } |
| 7311 | + if (subject) { |
| 7312 | + url.searchParams.set("subject", subject); |
| 7313 | + } |
| 7314 | + if (commitId) { |
| 7315 | + url.searchParams.set("commit", commitId); |
| 7316 | + } |
| 7317 | + return url.toString(); |
| 7318 | + } |
7252 | 7319 | function updateOutput() { |
7253 | 7320 | renderSelectedPromptHelp(); |
7254 | 7321 | const text = buildPromptText(); |
|
7323 | 7390 | commitIdInput.addEventListener("input", updateOutput); |
7324 | 7391 | subjectInput.addEventListener("input", updateOutput); |
7325 | 7392 | includeLabelPrefix.addEventListener("change", updateOutput); |
| 7393 | + copyShareLinkButton.addEventListener("click", () => { |
| 7394 | + void copyText(buildShareLink()); |
| 7395 | + }); |
| 7396 | + let initialQuery = ""; |
| 7397 | + let initialSubject = ""; |
| 7398 | + let initialCommitId = ""; |
| 7399 | + try { |
| 7400 | + const url = new URL(window.location.href); |
| 7401 | + initialQuery = (url.searchParams.get("q") || "").trim(); |
| 7402 | + initialSubject = url.searchParams.get("subject") || ""; |
| 7403 | + initialCommitId = url.searchParams.get("commit") || ""; |
| 7404 | + if (initialQuery) { |
| 7405 | + promptSearch.value = initialQuery; |
| 7406 | + } |
| 7407 | + } |
| 7408 | + catch (_error) { |
| 7409 | + // Ignore invalid or unavailable location values. |
| 7410 | + } |
7326 | 7411 | createSeriesVisibilityMenu(); |
7327 | 7412 | renderCandidates(); |
| 7413 | + if (initialSubject) { |
| 7414 | + subjectInput.value = initialSubject; |
| 7415 | + } |
| 7416 | + if (initialCommitId) { |
| 7417 | + commitIdInput.value = initialCommitId; |
| 7418 | + } |
7328 | 7419 | updateOutput(); |
7329 | 7420 | requestAnimationFrame(() => { |
7330 | 7421 | promptSearch.focus(); |
|
0 commit comments