mirror of
https://github.com/hugo-fixit/FixIt.git
synced 2026-08-24 15:28:57 +00:00
feat(code): add download button for code blocks and related functionality (#706)
This commit is contained in:
@@ -237,6 +237,12 @@ pre {
|
||||
color: fixit-var(global-link-hover-color);
|
||||
}
|
||||
|
||||
.download-btn[data-downloaded] .fa-download {
|
||||
--fa: "\f1ce";
|
||||
font-weight: 900;
|
||||
color: fixit-var(global-link-hover-color);
|
||||
}
|
||||
|
||||
@each $type, $text in $code-type-map {
|
||||
&.language-#{to-lower-case($type)} {
|
||||
// e.g., --fi-code-type: "JavaScript";
|
||||
|
||||
@@ -459,6 +459,33 @@ class FixIt {
|
||||
}, false);
|
||||
}
|
||||
|
||||
initDownloadCode(codeBlock, codePreEl) {
|
||||
const downloadBtn = codeBlock.querySelector('.code-header .download-btn');
|
||||
if (!downloadBtn) return;
|
||||
downloadBtn.addEventListener('click', () => {
|
||||
const $codeHeader = codeBlock.querySelector('.code-header');
|
||||
const fileNameFromTitle = $codeHeader?.querySelector('.code-title')?.dataset.name?.trim();
|
||||
const language = Array.from($codeHeader?.classList || []).find((className) => className.startsWith('language-'))?.replace('language-', '');
|
||||
const fallbackName = language && language !== 'fallback' ? `code.${language}` : 'code.txt';
|
||||
const fileName = (fileNameFromTitle || fallbackName).replace(/[\\/:*?"<>|\r\n]+/g, '-');
|
||||
const blob = new Blob([codePreEl.innerText], { type: 'text/plain;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = fileName || fallbackName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
downloadBtn.toggleAttribute('data-downloaded', true);
|
||||
downloadBtn.classList.toggle('fa-spin', true);
|
||||
setTimeout(() => {
|
||||
downloadBtn.toggleAttribute('data-downloaded', false);
|
||||
downloadBtn.classList.toggle('fa-spin', false);
|
||||
}, 300);
|
||||
}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* init code wrapper
|
||||
*/
|
||||
@@ -477,6 +504,7 @@ class FixIt {
|
||||
if ($codeBlock.dataset.mode === 'classic') {
|
||||
const $codeHeader = $codeBlock.querySelector('.code-header');
|
||||
if (!$codeHeader) return;
|
||||
this.initDownloadCode($codeBlock, $codePreEl);
|
||||
// code title
|
||||
$codeHeader.querySelector('.code-title').addEventListener('click', () => {
|
||||
$codeBlock.classList.toggle('is-collapsed');
|
||||
|
||||
@@ -1144,6 +1144,8 @@ wrapperClass = ""
|
||||
maxShownLines = 10
|
||||
# whether to enable code copy button
|
||||
copyable = true
|
||||
# [classic] whether to enable code download button in the code block header
|
||||
downloadable = false
|
||||
# [classic] whether to enable line numbers toggle button in the code block header
|
||||
lineNosToggler = true
|
||||
# [classic] whether to enable toggle line wrapping button in the code block header
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Kopiert"
|
||||
toggleLineNumbers = "Zeilennummern umschalten"
|
||||
toggleLineWrap = "Zeilenumbruch umschalten"
|
||||
toggleCodeEditable = "Codeblock editierbar umschalten"
|
||||
downloadCode = "Code herunterladen"
|
||||
expandCode = "Codeblock erweitern oder reduzieren"
|
||||
cookieconsentMessage = "Diese Website verwendet Cookies, um Ihre Erfahrung zu verbessern."
|
||||
cookieconsentDismiss = "Zustimmen"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Copied"
|
||||
toggleLineNumbers = "Toggle line numbers"
|
||||
toggleLineWrap = "Toggle code wrap"
|
||||
toggleCodeEditable = "Toggle code block editable"
|
||||
downloadCode = "Download code"
|
||||
expandCode = "Expand or collapse code block"
|
||||
cookieconsentMessage = "This website uses Cookies to improve your experience."
|
||||
cookieconsentDismiss = "Got it!"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Copiado"
|
||||
toggleLineNumbers = "Alternar números de línea"
|
||||
toggleLineWrap = "Alternar ajuste de línea"
|
||||
toggleCodeEditable = "Alternar bloque de código editable"
|
||||
downloadCode = "Descargar código"
|
||||
expandCode = "Expandir o contraer bloque de código"
|
||||
cookieconsentMessage = "Este sitio web utiliza Cookies para mejorar su experiencia."
|
||||
cookieconsentDismiss = "De acuerdo"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Copié"
|
||||
toggleLineNumbers = "Basculer les numéros de ligne"
|
||||
toggleLineWrap = "Basculer le retour à la ligne"
|
||||
toggleCodeEditable = "Basculer le bloc de code modifiable"
|
||||
downloadCode = "Télécharger le code"
|
||||
expandCode = "Développer ou réduire le bloc de code"
|
||||
cookieconsentMessage = "Ce site Web utilise des Cookies pour améliorer votre expérience."
|
||||
cookieconsentDismiss = "J'ai compris !"
|
||||
|
||||
@@ -103,6 +103,7 @@ copiedText = "कॉपी किया गया"
|
||||
toggleLineNumbers = "लाइन नंबर टॉगल करें"
|
||||
toggleLineWrap = "लाइन रैप टॉगल करें"
|
||||
toggleCodeEditable = "कोड ब्लॉक संपादन योग्य टॉगल करें"
|
||||
downloadCode = "कोड डाउनलोड करें"
|
||||
expandCode = "कोड ब्लॉक का विस्तार या संकुचित करें"
|
||||
cookieconsentMessage = "यह वेबसाइट आपके अनुभव को बेहतर बनाने के लिए कुकीज़ का उपयोग करती है।"
|
||||
cookieconsentDismiss = "समझ गया!"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Copiato"
|
||||
toggleLineNumbers = "Attiva/disattiva i numeri di linea"
|
||||
toggleLineWrap = "Attiva/disattiva il ritorno a capo del codice"
|
||||
toggleCodeEditable = "Attiva/disattiva la modifica del blocco di codice"
|
||||
downloadCode = "Scarica codice"
|
||||
expandCode = "Espandi o riduci il blocco di codice"
|
||||
cookieconsentMessage = "Questo sito Web utilizza i Cookies per migliorare la tua esperienza."
|
||||
cookieconsentDismiss = "Essere d'accordo"
|
||||
|
||||
@@ -100,6 +100,7 @@ copiedText = "コピー済み"
|
||||
toggleLineNumbers = "行番号の切り替え"
|
||||
toggleLineWrap = "自動折り返しの切り替え"
|
||||
toggleCodeEditable = "コードブロックの編集切り替え"
|
||||
downloadCode = "コードをダウンロード"
|
||||
expandCode = "コードブロックの展開/折りたたみ"
|
||||
cookieconsentMessage = "このウェブサイトはクッキーを使用して体験を向上させます。"
|
||||
cookieconsentDismiss = "同意する"
|
||||
|
||||
@@ -100,6 +100,7 @@ copiedText = "복사됨"
|
||||
toggleLineNumbers = "줄 번호 전환"
|
||||
toggleLineWrap = "자동 줄 바꿈 전환"
|
||||
toggleCodeEditable = "코드 블록 편집 전환"
|
||||
downloadCode = "코드 다운로드"
|
||||
expandCode = "코드 블록 확장/축소"
|
||||
cookieconsentMessage = "이 웹사이트는 쿠키를 사용하여 경험을 향상시킵니다."
|
||||
cookieconsentDismiss = "동의"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Skopiowano"
|
||||
toggleLineNumbers = "Przełącz numery linii"
|
||||
toggleLineWrap = "Przełącz zawijanie linii"
|
||||
toggleCodeEditable = "Przełącz edytowalny blok kodu"
|
||||
downloadCode = "Pobierz kod"
|
||||
expandCode = "Rozwiń lub zwiń blok kodu"
|
||||
cookieconsentMessage = "Ta strona korzysta z plików Cookies, aby poprawić komfort użytkowania."
|
||||
cookieconsentDismiss = "Zgodzić się"
|
||||
|
||||
@@ -103,6 +103,7 @@ copiedText = "Copiado"
|
||||
toggleLineNumbers = "Alternar números de linha"
|
||||
toggleLineWrap = "Alternar quebra de linha"
|
||||
toggleCodeEditable = "Alternar bloco de código editável"
|
||||
downloadCode = "Baixar código"
|
||||
expandCode = "Expandir ou recolher bloco de código"
|
||||
cookieconsentMessage = "Este site usa Cookies para melhorar sua experiência."
|
||||
cookieconsentDismiss = "Aceitar"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Copiat"
|
||||
toggleLineNumbers = "Comută numerele de linie"
|
||||
toggleLineWrap = "Comută înfășurarea liniei"
|
||||
toggleCodeEditable = "Comută blocul de cod editabil"
|
||||
downloadCode = "Descarcă codul"
|
||||
expandCode = "Extinde sau restrânge blocul de cod"
|
||||
cookieconsentMessage = "Acest site web utilizează Cookies pentru a vă îmbunătăți experiența."
|
||||
cookieconsentDismiss = "De acord"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Скопировано"
|
||||
toggleLineNumbers = "Переключить номера строк"
|
||||
toggleLineWrap = "Переключить перенос строк"
|
||||
toggleCodeEditable = "Переключить редактируемый блок кода"
|
||||
downloadCode = "Скачать код"
|
||||
expandCode = "Развернуть или свернуть блок кода"
|
||||
cookieconsentMessage = "Этот сайт использует Cookies для улучшения вашего опыта."
|
||||
cookieconsentDismiss = "Согласен"
|
||||
|
||||
@@ -102,6 +102,7 @@ copiedText = "Копирано"
|
||||
toggleLineNumbers = "Прекидач за бројеве линија"
|
||||
toggleLineWrap = "Прекидач за оматање линија"
|
||||
toggleCodeEditable = "Пребаци уређивање блока кода"
|
||||
downloadCode = "Преузми код"
|
||||
expandCode = "Прошири или смањи блок кода"
|
||||
cookieconsentMessage = "Ова веб локација користи Cookies да би побољшала ваше искуство."
|
||||
cookieconsentDismiss = "Договорити се"
|
||||
|
||||
@@ -101,6 +101,7 @@ copiedText = "Đã sao chép"
|
||||
toggleLineNumbers = "Chuyển đổi số dòng"
|
||||
toggleLineWrap = "Chuyển đổi xuống dòng"
|
||||
toggleCodeEditable = "Chuyển đổi khối mã có thể chỉnh sửa"
|
||||
downloadCode = "Tải mã"
|
||||
expandCode = "Mở rộng hoặc thu gọn khối mã"
|
||||
cookieconsentMessage = "Trang web này sử dụng Cookies để cải thiện trải nghiệm của bạn."
|
||||
cookieconsentDismiss = "Đã hiểu!"
|
||||
|
||||
@@ -100,6 +100,7 @@ copiedText = "已复制"
|
||||
toggleLineNumbers = "切换行号"
|
||||
toggleLineWrap = "切换自动换行"
|
||||
toggleCodeEditable = "切换可编辑代码块"
|
||||
downloadCode = "下载代码"
|
||||
expandCode = "展开或折叠代码块"
|
||||
cookieconsentMessage = "本网站使用 Cookies 来改善您的浏览体验。"
|
||||
cookieconsentDismiss = "同意"
|
||||
|
||||
@@ -100,6 +100,7 @@ copiedText = "已複製"
|
||||
toggleLineNumbers = "切換行號"
|
||||
toggleLineWrap = "切換自動換行"
|
||||
toggleCodeEditable = "切換可編輯程式碼區塊"
|
||||
downloadCode = "下載程式碼"
|
||||
expandCode = "展開或摺疊程式碼區塊"
|
||||
cookieconsentMessage = "本網站使用 Cookies 來改善您的流覽體驗。"
|
||||
cookieconsentDismiss = "同意"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
{{- $lineWrapBtn := "" -}}
|
||||
{{- $editBtn := "" -}}
|
||||
{{- $copyBtn := "" -}}
|
||||
{{- $downloadBtn := "" -}}
|
||||
{{- $foldIcon := dict "Class" "arrow fa-solid fa-chevron-down" | partial "plugin/icon.html" -}}
|
||||
{{- $titleEl := printf `<span class="code-title">%s</span>` $foldIcon -}}
|
||||
{{- $ellipsisBtn := printf `<span class="ellipses-btn" aria-label="Show more options" role="button">%s</span>` (dict "Class" "fa-solid fa-ellipsis-h" | partial "plugin/icon.html") -}}
|
||||
@@ -30,10 +31,14 @@
|
||||
{{- $copyIcon := dict "Class" "fa-regular fa-clone" | partial "plugin/icon.html" -}}
|
||||
{{- $copyBtn = printf `<span class="copy-btn" aria-label="%s" role="button" title="%s">%s</span>` (T "assets.copyToClipboard") (T "assets.copyToClipboard") $copyIcon -}}
|
||||
{{- end -}}
|
||||
{{- if $config.downloadable -}}
|
||||
{{- $downloadIcon := dict "Class" "fa-solid fa-download" | partial "plugin/icon.html" -}}
|
||||
{{- $downloadBtn = printf `<span class="download-btn" aria-label="%s" role="button" title="%s">%s</span>` (T "assets.downloadCode") (T "assets.downloadCode") $downloadIcon -}}
|
||||
{{- end -}}
|
||||
{{- with $config.name -}}
|
||||
{{- $titleEl = replace $titleEl `<span class="code-title">` (printf `<span class="code-title" data-name="%s">` .) -}}
|
||||
{{- end -}}
|
||||
{{- $codeHeader := printf `<div class="code-header language-%s">%s%s%s%s%s%s</div>` $lang $titleEl $ellipsisBtn $lineNosBtn $lineWrapBtn $editBtn $copyBtn -}}
|
||||
{{- $codeHeader := printf `<div class="code-header language-%s">%s%s%s%s%s%s%s</div>` $lang $titleEl $ellipsisBtn $lineNosBtn $lineWrapBtn $editBtn $copyBtn $downloadBtn -}}
|
||||
{{- $wrapper = replaceRE `(<div class="code-wrapper">)` (printf "%s$1" $codeHeader) $wrapper -}}
|
||||
|
||||
{{- return $wrapper -}}
|
||||
|
||||
Reference in New Issue
Block a user