Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable code changes to **Markdown Viewer** are documented here.
Non-code commits (documentation, planning, README-only updates) are excluded.

## v3.6.4

- **Description:** Implemented Brazilian Portuguese (pt-BR) translation module. Localized all main editor labels, stats, tooltips, dialogs, placeholder, and search/replace options. Registered `hreflang` alternate link for Portuguese (pt-BR) search indexation and enabled automatic browser language detection fallback for Portuguese language preferences. Rotated Service Worker cache namespace to `v3.6.4` to trigger background cache updates.
- **Date:** 2026-05-27
- **URL:** https://github.com/ThisIs-Developer/Markdown-Viewer/commit/v3.6.4

---

## v3.6.3
Expand Down
11 changes: 7 additions & 4 deletions desktop-app/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<link rel="alternate" hreflang="zh-Hans" href="https://markdownviewer.pages.dev/?lang=zh" />
<link rel="alternate" hreflang="ja" href="https://markdownviewer.pages.dev/?lang=ja" />
<link rel="alternate" hreflang="ko" href="https://markdownviewer.pages.dev/?lang=ko" />
<link rel="alternate" hreflang="pt-BR" href="https://markdownviewer.pages.dev/?lang=pt" />

<!-- Asian Search Engine Verification Meta Tags -->
<meta name="baidu-site-verification" content="baidu_verification_code_placeholder" />
Expand Down Expand Up @@ -190,6 +191,7 @@ <h1 class="h4 mb-0 me-2">Markdown Viewer</h1>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="zh">🇨🇳 简体中文</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ja">🇯🇵 日本語</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ko">🇰🇷 한국어</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="pt">🇧🇷 Português (Brasil)</a></li>
</ul>
</div>

Expand Down Expand Up @@ -297,10 +299,11 @@ <h5>Menu</h5>
<i class="bi bi-translate me-2"></i> Language: <span id="mobile-current-lang-label">English</span>
</button>
<ul class="dropdown-menu w-100" aria-labelledby="mobileLanguageDropdown">
<li><a class="dropdown-item lang-select-item active" href="#" data-lang="en">🇺🇸 English</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="zh">🇨🇳 简体中文</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ja">🇯🇵 日本語</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ko">🇰🇷 한국어</a></li>
<li><a class="dropdown-item lang-select-item active" href="#" data-lang="en">us English</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="zh">CN 简体中文</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ja">JP 日本語</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ko">KR 한국어</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="pt">BR Português (Brasil)</a></li>
</ul>
</div>
<button id="mobile-theme-toggle" class="mobile-menu-item" title="Toggle Dark Mode">
Expand Down
106 changes: 101 additions & 5 deletions desktop-app/resources/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -3953,12 +3953,33 @@ This is a fully client-side application. Your content never leaves your browser

let frPreferredDocked = false;

function toggleFrDockMode() {
function toggleFrDockMode(forceFloat = false) {
const panel = document.getElementById('find-replace-modal');
const dockBtn = document.getElementById('find-replace-dock');
const contentCont = document.querySelector('.content-container');
if (!panel || !dockBtn || !contentCont) return;

if (window.innerWidth <= 768 || forceFloat) {
isFrDocked = false;
panel.classList.remove('docked');
if (panel.parentElement !== document.body) {
document.body.appendChild(panel);
}
contentCont.classList.remove('fr-docked');
contentCont.style.setProperty('--dock-width', '0px');

panel.style.top = '';
panel.style.left = '';
panel.style.right = '';

dockBtn.innerHTML = '<i class="bi bi-layout-sidebar-reverse"></i>';
dockBtn.title = "Toggle Dock Mode";

panel.style.display = 'flex';
applyPaneWidths();
return;
}

isFrDocked = !isFrDocked;

// Save preference to localStorage
Expand Down Expand Up @@ -4119,7 +4140,12 @@ This is a fully client-side application. Your content never leaves your browser
}

// Restore docked/floating mode preference
const wasDockedPref = localStorage.getItem('find-replace-docked') === 'true';
let wasDockedPref = localStorage.getItem('find-replace-docked') === 'true';

// Force floating-only mode on mobile/tablet viewports
if (window.innerWidth <= 768) {
wasDockedPref = false;
}

if (wasDockedPref) {
isFrDocked = false; // Set false so toggleFrDockMode() turns it to true
Expand Down Expand Up @@ -4456,6 +4482,28 @@ This is a fully client-side application. Your content never leaves your browser
}
}

function openHelpModal() {
if (helpModal) {
openAppModal(helpModal);
}
}

function openAboutModal() {
if (aboutModal) {
const aboutVersion = document.getElementById("about-version");
if (aboutVersion) {
aboutVersion.textContent = APP_VERSION;
}
openAppModal(aboutModal);
}
}

function openClearFormattingModal() {
if (clearFormattingModal) {
openAppModal(clearFormattingModal);
}
}

function runMarkdownTool(action, button) {
if (action === 'undo' || action === 'redo') {
markdownEditor.focus();
Expand Down Expand Up @@ -4571,6 +4619,7 @@ This is a fully client-side application. Your content never leaves your browser
}

function startResize(e) {
if (window.innerWidth <= 768) return;
if (currentViewMode !== 'split') return;
e.preventDefault();
isResizing = true;
Expand All @@ -4579,6 +4628,7 @@ This is a fully client-side application. Your content never leaves your browser
}

function startResizeTouch(e) {
if (window.innerWidth <= 768) return;
if (currentViewMode !== 'split') return;
e.preventDefault();
isResizing = true;
Expand Down Expand Up @@ -4625,6 +4675,10 @@ This is a fully client-side application. Your content never leaves your browser
}

function applyPaneWidths() {
if (window.innerWidth <= 768) {
resetPaneWidths();
return;
}
if (currentViewMode !== 'split') return;

const previewPercent = 100 - editorWidthPercent;
Expand Down Expand Up @@ -4733,7 +4787,12 @@ This is a fully client-side application. Your content never leaves your browser

// Initialize resizer - Story 1.3
initResizer();
window.addEventListener('resize', scheduleLineNumberUpdate);
window.addEventListener('resize', () => {
scheduleLineNumberUpdate();
if (window.innerWidth <= 768 && isFrDocked && isFindModalOpen) {
toggleFrDockMode(true);
}
});

// View Mode Button Event Listeners - Story 1.1
viewModeButtons.forEach(btn => {
Expand Down Expand Up @@ -6626,6 +6685,42 @@ This is a fully client-side application. Your content never leaves your browser
insertTable: "표 삽입",
findReplace: "찾기 및 바꾸기",
placeholder: "여기에 마크다운 내용을 입력하세요..."
},
pt: {
title: "Visualizador de Markdown",
syncOff: "Desativar Sincronia",
syncOn: "Ativar Sincronia",
import: "Importar",
importFile: "De arquivos",
importGithub: "Do GitHub",
export: "Exportar",
exportMd: "Markdown (.md)",
exportHtml: "HTML",
exportPdf: "PDF",
copy: "Copiar",
copied: "Copiado!",
share: "Compartilhar",
reset: "Redefinir",
editor: "Editor",
split: "Dividido",
preview: "Visualizar",
minRead: "Min de leitura",
words: "Palavras",
chars: "Caracteres",
switchRtl: "Mudar para RTL",
switchLtr: "Mudar para LTR",
darkMode: "Modo Escuro",
lightMode: "Modo Claro",
helpTitle: "Ajuda do Visualizador de Markdown",
aboutTitle: "Sobre o Markdown",
shareTitle: "Compartilhar Documento",
renameTitle: "Renomear arquivo",
insertLink: "Inserir link",
insertRef: "Inserir referência",
insertImg: "Inserir imagem",
insertTable: "Inserir tabela",
findReplace: "Localizar & Substituir",
placeholder: "Digite seu markdown aqui..."
}
};

Expand All @@ -6643,12 +6738,12 @@ This is a fully client-side application. Your content never leaves your browser
// Update dynamic current language labels in drop menus
const labelEl = document.getElementById('current-lang-label');
if (labelEl) {
const flags = { en: "🇺🇸 English", zh: "🇨🇳 简体中文", ja: "🇯🇵 日本語", ko: "🇰🇷 한국어" };
const flags = { en: "🇺🇸 English", zh: "🇨🇳 简体中文", ja: "🇯🇵 日本語", ko: "🇰🇷 한국어", pt: "🇧🇷 Português (Brasil)" };
labelEl.textContent = flags[lang];
}
const mobileLabelEl = document.getElementById('mobile-current-lang-label');
if (mobileLabelEl) {
const flags = { en: "🇺🇸 English", zh: "🇨🇳 简体中文", ja: "🇯🇵 日本語", ko: "🇰🇷 한국어" };
const flags = { en: "us English", zh: "CN 简体中文", ja: "JP 日本語", ko: "KR 한국어", pt: "BR Português (Brasil)" };
mobileLabelEl.textContent = flags[lang];
}

Expand Down Expand Up @@ -6821,6 +6916,7 @@ This is a fully client-side application. Your content never leaves your browser
if (navLang.startsWith('zh')) lang = 'zh';
else if (navLang.startsWith('ja')) lang = 'ja';
else if (navLang.startsWith('ko')) lang = 'ko';
else if (navLang.startsWith('pt')) lang = 'pt';
}

if (!lang || !I18N_DICTS[lang]) {
Expand Down
17 changes: 17 additions & 0 deletions desktop-app/resources/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -3376,4 +3376,21 @@ html[lang="ko"] .markdown-body h1, html[lang="ko"] .markdown-body h2, html[lang=
flex: 1;
position: relative;
overflow: hidden;
}

/* ========================================
MOBILE FIND PANEL RESPONSIVE FIXES
======================================== */
@media (max-width: 768px) {
#find-replace-dock {
display: none !important;
}

/* Prevent full screen expansion of floating panel on small mobile viewports */
.find-replace-panel {
width: calc(100% - 24px) !important;
right: 12px !important;
left: 12px !important;
top: 80px !important;
}
}
11 changes: 7 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<link rel="alternate" hreflang="zh-Hans" href="https://markdownviewer.pages.dev/?lang=zh" />
<link rel="alternate" hreflang="ja" href="https://markdownviewer.pages.dev/?lang=ja" />
<link rel="alternate" hreflang="ko" href="https://markdownviewer.pages.dev/?lang=ko" />
<link rel="alternate" hreflang="pt-BR" href="https://markdownviewer.pages.dev/?lang=pt" />

<!-- Asian Search Engine Verification Meta Tags -->
<meta name="baidu-site-verification" content="baidu_verification_code_placeholder" />
Expand Down Expand Up @@ -187,6 +188,7 @@ <h1 class="h4 mb-0 me-2">Markdown Viewer</h1>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="zh">🇨🇳 简体中文</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ja">🇯🇵 日本語</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ko">🇰🇷 한국어</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="pt">🇧🇷 Português (Brasil)</a></li>
</ul>
</div>

Expand Down Expand Up @@ -294,10 +296,11 @@ <h5>Menu</h5>
<i class="bi bi-translate me-2"></i> Language: <span id="mobile-current-lang-label">English</span>
</button>
<ul class="dropdown-menu w-100" aria-labelledby="mobileLanguageDropdown">
<li><a class="dropdown-item lang-select-item active" href="#" data-lang="en">🇺🇸 English</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="zh">🇨🇳 简体中文</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ja">🇯🇵 日本語</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ko">🇰🇷 한국어</a></li>
<li><a class="dropdown-item lang-select-item active" href="#" data-lang="en">us English</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="zh">CN 简体中文</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ja">JP 日本語</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="ko">KR 한국어</a></li>
<li><a class="dropdown-item lang-select-item" href="#" data-lang="pt">BR Português (Brasil)</a></li>
</ul>
</div>
<button id="mobile-theme-toggle" class="mobile-menu-item" title="Toggle Dark Mode">
Expand Down
Loading
Loading