da81a0b148
Issue 1: Blur bar compatibility (Android doesn't always show at bottom) ✅ Solution: Wrap blur bar in @supports query for backdrop-filter - Only shows on devices that support backdrop-filter (primarily iOS) - Android devices without support won't see the bar - Prevents layout issues on non-iOS devices Issue 2: Keyboard shortcuts button on real mobile (no physical keyboard) ✅ Solution: Device detection + conditional hiding - Added device-detection.js: Detects real mobile vs desktop browser - Checks user agent (Android, iPhone, iPad, etc.) + touch support - Adds 'is-mobile-device' or 'is-desktop' class to <html> - CSS hides shortcuts button only on real mobile devices - Desktop browser in mobile view: shortcuts button still visible (for testing) Implementation Details: 1. Device Detection (static/js/device-detection.js): - User agent detection: /Android|iPhone|iPad|etc./ - Touch support check: ontouchstart + maxTouchPoints - Class added to <html>: is-mobile-device or is-desktop 2. Blur Bar (@supports query): - Detects backdrop-filter support before applying - iOS: Shows blur bar with backdrop-filter - Android (most): No blur bar (no backdrop-filter support) - Prevents empty/broken bar on incompatible devices 3. CSS Hiding Rules: - .is-mobile-device .shortcuts-btn { display: none !important; } - Also hides zoom-toggle-btn and zoom-control on real mobile - Desktop mobile view: shortcuts button remains visible Files Modified: - static/js/device-detection.js: NEW - Device detection logic - templates/index.html: Load device-detection.js early - static/css/05-responsive/_breakpoints.css: @supports wrapper for blur bar - static/css/04-interactive/_scroll-behavior.css: Hide shortcuts on real mobile - tests/mjs/52-mobile-device-detection-test.mjs: Comprehensive device detection test Test Results: ✅ iPhone (real mobile): is-mobile-device class, shortcuts hidden ✅ Desktop browser (mobile view): is-desktop class, shortcuts visible ✅ Blur bar: Only shows on devices with backdrop-filter support
78 lines
3.2 KiB
JavaScript
Executable File
78 lines
3.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import { chromium } from 'playwright';
|
|
|
|
const MOBILE_VIEWPORT = { width: 375, height: 667 };
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ headless: true });
|
|
|
|
console.log('🧪 Testing Mobile Device Detection and Button Visibility\n');
|
|
|
|
// TEST 1: Simulate mobile device (iPhone)
|
|
console.log('📱 TEST 1: iPhone User Agent (Real Mobile Device)\n');
|
|
const mobileContext = await browser.newContext({
|
|
viewport: MOBILE_VIEWPORT,
|
|
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
|
|
hasTouch: true
|
|
});
|
|
const mobilePage = await mobileContext.newPage();
|
|
|
|
await mobilePage.goto('http://localhost:1999/?lang=en&view=extended');
|
|
await mobilePage.waitForLoadState('networkidle');
|
|
|
|
const mobileDeviceClass = await mobilePage.evaluate(() => {
|
|
return {
|
|
hasClass: document.documentElement.classList.contains('is-mobile-device'),
|
|
allClasses: document.documentElement.className
|
|
};
|
|
});
|
|
|
|
const shortcutsVisible = await mobilePage.locator('.shortcuts-btn').isVisible().catch(() => false);
|
|
|
|
console.log('Device Detection:');
|
|
console.log(` • has 'is-mobile-device' class: ${mobileDeviceClass.hasClass ? '✅' : '❌'}`);
|
|
console.log(` • All classes: ${mobileDeviceClass.allClasses}`);
|
|
console.log(`\nShortcuts Button:`);
|
|
console.log(` • Visible: ${shortcutsVisible ? '❌ WRONG' : '✅ HIDDEN (correct)'}`);
|
|
|
|
await mobileContext.close();
|
|
|
|
// TEST 2: Desktop browser in mobile view
|
|
console.log('\n🖥️ TEST 2: Desktop User Agent in Mobile View\n');
|
|
const desktopContext = await browser.newContext({
|
|
viewport: MOBILE_VIEWPORT,
|
|
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
|
hasTouch: false
|
|
});
|
|
const desktopPage = await desktopContext.newPage();
|
|
|
|
await desktopPage.goto('http://localhost:1999/?lang=en&view=extended');
|
|
await desktopPage.waitForLoadState('networkidle');
|
|
|
|
const desktopDeviceClass = await desktopPage.evaluate(() => {
|
|
return {
|
|
hasClass: document.documentElement.classList.contains('is-desktop'),
|
|
allClasses: document.documentElement.className
|
|
};
|
|
});
|
|
|
|
const shortcutsVisibleDesktop = await desktopPage.locator('.shortcuts-btn').isVisible().catch(() => false);
|
|
|
|
console.log('Device Detection:');
|
|
console.log(` • has 'is-desktop' class: ${desktopDeviceClass.hasClass ? '✅' : '❌'}`);
|
|
console.log(` • All classes: ${desktopDeviceClass.allClasses}`);
|
|
console.log(`\nShortcuts Button:`);
|
|
console.log(` • Visible: ${shortcutsVisibleDesktop ? '✅ VISIBLE (correct for testing)' : '❌ HIDDEN'}`);
|
|
|
|
await desktopContext.close();
|
|
|
|
const allPassed = mobileDeviceClass.hasClass && !shortcutsVisible &&
|
|
desktopDeviceClass.hasClass && shortcutsVisibleDesktop;
|
|
|
|
console.log(`\n${allPassed ? '✅' : '❌'} Tests ${allPassed ? 'PASSED' : 'FAILED'}\n`);
|
|
|
|
await browser.close();
|
|
process.exit(allPassed ? 0 : 1);
|
|
})();
|