diff --git a/.cfignore b/.cfignore index d0be21b..bab4295 100755 --- a/.cfignore +++ b/.cfignore @@ -4,9 +4,20 @@ # Version control .git/ +.gitattributes .gitignore .cfignore +# Environment and key material (must never be served) +.env +.env.* +.dev.vars +*.pem +*.key +*.p12 +*.pfx +*.secret + # CI / repo config .github/ @@ -25,5 +36,8 @@ node_modules/ scripts/ scanmysms-download/ .vscode/ +.idea/ +*.code-workspace .claude/ CLAUDE.md +.editorconfig diff --git a/.gitignore b/.gitignore index 7563c16..e8ca675 100755 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,18 @@ .Trashes ehthumbs.db Thumbs.db +Desktop.ini +$RECYCLE.BIN/ # ─── Editor ──────────────────────────────────────────── .vscode/ +.idea/ +*.code-workspace *.swp *.swo *~ +*.bak +*.orig # ─── Node ────────────────────────────────────────────── node_modules/ @@ -26,6 +32,12 @@ yarn.lock .env.* .env.local *.secret +*.pem +*.key +*.p12 +*.pfx +.wrangler/ +.dev.vars # ─── Build output ────────────────────────────────────── dist/ diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb1f1f..f45b41e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.5.1] - 2026-07-25 + +### Fixed + +- The footer copyright year never appeared: the language initialiser only re-rendered the page when a saved language differed from the current one, so a visitor using the default language kept the static placeholder. The year is now always rendered, and an unrecognised saved language falls back to English instead of blanking the interface + +### Changed + +- The licence notice and copyright now share a single bottom bar, separated by a dot and wrapping cleanly on narrow screens, instead of sitting as two stacked lines above and below the divider +- The licence link is underlined on hover rather than permanently, with a visible keyboard focus state +- `.gitignore` also covers JetBrains and workspace files, Windows shell artefacts, editor backups, and key material (`*.pem`, `*.key`, `*.p12`, `*.pfx`, `.dev.vars`, `.wrangler/`) +- `.cfignore` now excludes environment files and key material as well, so a misconfigured root-directory deploy could not serve them + ## [1.5.0] - 2026-07-25 ### Added diff --git a/README.md b/README.md index 8f00ec6..ae7b8bb 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CI](https://github.com/NX1X/EasyConvert/actions/workflows/ci.yml/badge.svg)](https://github.com/NX1X/EasyConvert/actions/workflows/ci.yml) [![CodeQL](https://github.com/NX1X/EasyConvert/actions/workflows/codeql.yml/badge.svg)](https://github.com/NX1X/EasyConvert/actions/workflows/codeql.yml) -[![Version](https://img.shields.io/badge/version-1.5.0-blue.svg)](https://github.com/NX1X/EasyConvert/releases) +[![Version](https://img.shields.io/badge/version-1.5.1-blue.svg)](https://github.com/NX1X/EasyConvert/releases) [![License](https://img.shields.io/badge/License-Apache%202.0-informational.svg)](LICENSE) [![Built](https://img.shields.io/badge/Built-June%202025-blue.svg)](#) [![Views](https://hits.sh/github.com/NX1X/EasyConvert.svg?label=Views&color=blue)](https://hits.sh/github.com/NX1X/EasyConvert/) diff --git a/package.json b/package.json index 47e0bb4..8d8841e 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "easyconvert", - "version": "1.5.0", + "version": "1.5.1", "description": "Free PDF table to Excel/CSV converter with advanced table detection and RTL text support", "main": "public/index.html", "scripts": { diff --git a/public/app.js b/public/app.js index b980df6..8ed4634 100755 --- a/public/app.js +++ b/public/app.js @@ -1171,7 +1171,7 @@ const translations = { footerLink3: "GitHub", footerPrivacy: "Privacy: Your PDFs are processed entirely in your browser. No files are uploaded to any server. Anonymous usage analytics via Cloudflare Analytics.", footerLicense: 'Open source under the Apache License 2.0', - footerCopyright: `© ${currentYear} NX1X.`, + footerCopyright: `© ${currentYear} NX1X`, statusVerify: "Please complete the security verification below to proceed.", statusLoading: "Loading PDF file...", statusExtracting: "Extracting data from PDF...", @@ -1231,7 +1231,7 @@ const translations = { footerLink3: "GitHub", footerPrivacy: "פרטיות: קבצי ה-PDF שלכם מעובדים לחלוטין בדפדפן שלכם. לא מועלים קבצים לשום שרת. אנליטיקה אנונימית בסיסית דרך Cloudflare Analytics.", footerLicense: 'קוד פתוח תחת רישיון Apache 2.0', - footerCopyright: `© ${currentYear} NX1X.`, + footerCopyright: `© ${currentYear} NX1X`, statusVerify: "אנא השלימו את אימות האבטחה למטה כדי להמשיך.", statusLoading: "טוען קובץ PDF...", statusExtracting: "מחלץ נתונים מה-PDF...", @@ -1343,10 +1343,13 @@ function updateLanguage() { function initializeLanguage() { const savedLanguage = localStorage.getItem('easyconvert-language'); - if (savedLanguage && savedLanguage !== currentLanguage) { + if (savedLanguage && translations[savedLanguage]) { currentLanguage = savedLanguage; - updateLanguage(); } + // Always run: parts of the page are only produced here (the copyright + // year, for example), so skipping this when the language already matches + // would leave that static placeholder text in place. + updateLanguage(); } document.addEventListener('DOMContentLoaded', initializeLanguage); diff --git a/public/index.html b/public/index.html index cb3327f..d4d1081 100755 --- a/public/index.html +++ b/public/index.html @@ -366,12 +366,10 @@

Found EasyConvert helpful?

Privacy: Your PDFs are processed entirely in your browser. No files are uploaded to any server. Anonymous usage analytics via Cloudflare Analytics. - - - diff --git a/public/style.css b/public/style.css index 2bd2a93..b62caa0 100755 --- a/public/style.css +++ b/public/style.css @@ -694,22 +694,41 @@ body { flex-shrink: 0; } -.footer-license { +/* Bottom legal bar: copyright and licence sit on one line, separated by a + dot, and wrap onto separate lines on narrow screens. */ +.footer-legal { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + gap: 4px 12px; font-size: 0.85rem; - opacity: 0.8; - margin-bottom: 12px; + opacity: 0.7; + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding-top: 20px; +} + +.footer-legal-dot { + opacity: 0.5; } -.footer-license a { +.footer-legal a { color: white; - text-decoration: underline; + text-decoration: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.35); + transition: var(--transition); } -.footer-copyright { - font-size: 0.85rem; - opacity: 0.7; - border-top: 1px solid rgba(255, 255, 255, 0.1); - padding-top: 20px; +.footer-legal a:hover, +.footer-legal a:focus-visible { + border-bottom-color: white; +} + +/* On very narrow screens the dot separator adds noise once items wrap */ +@media (max-width: 420px) { + .footer-legal-dot { + display: none; + } } /* Share Section */ diff --git a/public/sw.js b/public/sw.js index 5999803..fd6bcdd 100755 --- a/public/sw.js +++ b/public/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'easyconvert-v1.5.0'; +const CACHE_NAME = 'easyconvert-v1.5.1'; const urlsToCache = [ '/', '/index.html',