fix(build): url-encode bookmarklet payload to prevent URI malformed error (v1.1.2)

This commit is contained in:
2026-02-16 19:14:21 +01:00
parent d82dd31bed
commit efdb50083e
8 changed files with 1710 additions and 1587 deletions

View File

@@ -161,18 +161,38 @@ print(html)
") ")
fi fi
# Embed the bookmarklet URL inline
echo "document.getElementById('bookmarklet-link').href = " >> "$DIST_DIR/install.html" echo "document.getElementById('bookmarklet-link').href = " >> "$DIST_DIR/install.html"
echo "$JS_CONTENT" | python3 -c " echo "$JS_CONTENT" | python3 -c "
import sys, json import sys, json, urllib.parse
js = sys.stdin.read()
css = open('$CSS_FILE').read().replace('\\n', ' ').replace(' ', ' ') # 1. Read JS and Replace VERSION
js_template = sys.stdin.read()
# We do replacement here in Python to be safe
js = js_template.replace('{{VERSION}}', '$VERSION')
# 2. Prepare CSS
css = open('$CSS_FILE').read().replace('\n', ' ').replace(' ', ' ')
escaped_css = css.replace('\\\\', '\\\\\\\\').replace(\"'\", \"\\\\'\").replace('\"', '\\\\\"') escaped_css = css.replace('\\\\', '\\\\\\\\').replace(\"'\", \"\\\\'\").replace('\"', '\\\\\"')
# Inject Update URL with htmlpreview # 3. Inject CSS and Update URL
update_url = 'https://htmlpreview.github.io/?https://github.com/TauNeutrino/kantine-overview/blob/main/dist/install.html' update_url = 'https://htmlpreview.github.io/?https://github.com/TauNeutrino/kantine-overview/blob/main/dist/install.html'
js = js.replace('https://github.com/TauNeutrino/kantine-overview/raw/main/dist/install.html', update_url) js = js.replace('https://github.com/TauNeutrino/kantine-overview/raw/main/dist/install.html', update_url)
js = js.replace('{{CSS_ESCAPED}}', escaped_css)
print(json.dumps('javascript:(function(){' + js.replace('{{CSS_ESCAPED}}', escaped_css) + '})();')) # 4. Create Bookmarklet Code
# Wrap in IIFE
bookmarklet_code = 'javascript:(function(){' + js + '})();'
# 5. URL Encode the body (keeping javascript: prefix)
# We accept that simple encoding is better.
# But browsers expect encoded URI for href.
# However, for bookmarklet usage, user drags the link.
# If we encode everything, it's safer.
encoded_code = urllib.parse.quote(bookmarklet_code, safe=':/()!;=+,')
# Output as JSON string for the HTML script to assign to href
print(json.dumps(encoded_code) + ';')
" >> "$DIST_DIR/install.html" " >> "$DIST_DIR/install.html"
# Inject Changelog into Installer HTML (Safe Python replace) # Inject Changelog into Installer HTML (Safe Python replace)

View File

@@ -1,3 +1,6 @@
## v1.1.2 (2026-02-16)
- **Fix**: Encoding-Problem beim Bookmarklet behoben (URL Malformed Error). 🔗
## v1.1.1 (2026-02-16) ## v1.1.1 (2026-02-16)
- **Fix**: Kritischer Fehler behoben, der das Laden des Wrappers verhinderte. 🐛 - **Fix**: Kritischer Fehler behoben, der das Laden des Wrappers verhinderte. 🐛

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

14
dist/install.html vendored

File diff suppressed because one or more lines are too long

View File

@@ -1417,7 +1417,7 @@ body {
<div class="brand"> <div class="brand">
<span class="material-icons-round logo-icon">restaurant_menu</span> <span class="material-icons-round logo-icon">restaurant_menu</span>
<div class="header-left"> <div class="header-left">
<h1>Kantinen Übersicht <small style="font-size: 0.6em; opacity: 0.7; font-weight: 400;">v1.1.1</small></h1> <h1>Kantinen Übersicht <small style="font-size: 0.6em; opacity: 0.7; font-weight: 400;">v1.1.2</small></h1>
<div id="last-updated-subtitle" class="subtitle"></div> <div id="last-updated-subtitle" class="subtitle"></div>
</div> </div>
</div> </div>
@@ -2750,14 +2750,62 @@ function createDayCard(day) {
// === Version Check === // === Version Check ===
async function checkForUpdates() { async function checkForUpdates() {
icon.className = 'update-icon'; const CurrentVersion = 'v1.1.2';
icon.href = url; const VersionUrl = 'https://raw.githubusercontent.com/TauNeutrino/kantine-overview/main/version.txt';
icon.target = '_blank'; const InstallerUrl = 'https://htmlpreview.github.io/?https://github.com/TauNeutrino/kantine-overview/blob/main/dist/install.html';
icon.innerHTML = '🆕'; // User requested icon
icon.title = `Neue Version verfügbar (${newVersion}). Klick für download`;
headerTitle.appendChild(icon); console.log(`[Kantine] Checking for updates... (Current: ${CurrentVersion})`);
showToast(`Update verfügbar: ${newVersion}`, 'info');
try {
const response = await fetch(VersionUrl, { cache: 'no-cache' });
if (!response.ok) return;
const remoteVersion = (await response.text()).trim();
if (remoteVersion && remoteVersion !== CurrentVersion) {
console.log(`[Kantine] New version available: ${remoteVersion}`);
// Fetch Changelog content
let changeSummary = '';
try {
const clResp = await fetch('https://raw.githubusercontent.com/TauNeutrino/kantine-overview/main/changelog.md');
if (clResp.ok) {
const clText = await clResp.text();
const match = clText.match(/## (v[^\n]+)\n((?:-[^\n]+\n)+)/);
if (match && match[1].includes(remoteVersion)) {
changeSummary = match[2].replace(/- /g, '• ').trim();
}
}
} catch (e) { console.warn('No changelog', e); }
// Create Banner
const updateBanner = document.createElement('div');
updateBanner.className = 'update-banner';
updateBanner.innerHTML = `
<div class="update-content">
<strong>Update verfügbar: ${remoteVersion}</strong>
${changeSummary ? `<pre class="change-summary">${changeSummary}</pre>` : ''}
<a href="${InstallerUrl}" target="_blank" class="update-link">
<span class="material-icons-round">system_update_alt</span>
Jetzt aktualisieren
</a>
</div>
<button class="icon-btn-small close-update">&times;</button>
`;
document.body.appendChild(updateBanner);
updateBanner.querySelector('.close-update').addEventListener('click', () => updateBanner.remove());
// Highlight Header Icon
const lastUpdatedIcon = document.querySelector('.material-icons-round.logo-icon');
if (lastUpdatedIcon) {
lastUpdatedIcon.style.color = 'var(--accent-color)';
lastUpdatedIcon.parentElement.title = `Update verfügbar: ${remoteVersion}`;
}
}
} catch (error) {
console.warn('[Kantine] Version check failed:', error);
}
} }
// === Order Countdown === // === Order Countdown ===

View File

@@ -1399,14 +1399,62 @@ function createDayCard(day) {
// === Version Check === // === Version Check ===
async function checkForUpdates() { async function checkForUpdates() {
icon.className = 'update-icon'; const CurrentVersion = '{{VERSION}}';
icon.href = url; const VersionUrl = 'https://raw.githubusercontent.com/TauNeutrino/kantine-overview/main/version.txt';
icon.target = '_blank'; const InstallerUrl = 'https://htmlpreview.github.io/?https://github.com/TauNeutrino/kantine-overview/blob/main/dist/install.html';
icon.innerHTML = '🆕'; // User requested icon
icon.title = `Neue Version verfügbar (${newVersion}). Klick für download`;
headerTitle.appendChild(icon); console.log(`[Kantine] Checking for updates... (Current: ${CurrentVersion})`);
showToast(`Update verfügbar: ${newVersion}`, 'info');
try {
const response = await fetch(VersionUrl, { cache: 'no-cache' });
if (!response.ok) return;
const remoteVersion = (await response.text()).trim();
if (remoteVersion && remoteVersion !== CurrentVersion) {
console.log(`[Kantine] New version available: ${remoteVersion}`);
// Fetch Changelog content
let changeSummary = '';
try {
const clResp = await fetch('https://raw.githubusercontent.com/TauNeutrino/kantine-overview/main/changelog.md');
if (clResp.ok) {
const clText = await clResp.text();
const match = clText.match(/## (v[^\n]+)\n((?:-[^\n]+\n)+)/);
if (match && match[1].includes(remoteVersion)) {
changeSummary = match[2].replace(/- /g, '• ').trim();
}
}
} catch (e) { console.warn('No changelog', e); }
// Create Banner
const updateBanner = document.createElement('div');
updateBanner.className = 'update-banner';
updateBanner.innerHTML = `
<div class="update-content">
<strong>Update verfügbar: ${remoteVersion}</strong>
${changeSummary ? `<pre class="change-summary">${changeSummary}</pre>` : ''}
<a href="${InstallerUrl}" target="_blank" class="update-link">
<span class="material-icons-round">system_update_alt</span>
Jetzt aktualisieren
</a>
</div>
<button class="icon-btn-small close-update">&times;</button>
`;
document.body.appendChild(updateBanner);
updateBanner.querySelector('.close-update').addEventListener('click', () => updateBanner.remove());
// Highlight Header Icon
const lastUpdatedIcon = document.querySelector('.material-icons-round.logo-icon');
if (lastUpdatedIcon) {
lastUpdatedIcon.style.color = 'var(--accent-color)';
lastUpdatedIcon.parentElement.title = `Update verfügbar: ${remoteVersion}`;
}
}
} catch (error) {
console.warn('[Kantine] Version check failed:', error);
}
} }
// === Order Countdown === // === Order Countdown ===

View File

@@ -1 +1 @@
v1.1.1 v1.1.2