upskill-event-manager/includes/class-hvac-browser-detection.php
bengizmo 4117f730c5 feat: Implement comprehensive Safari browser compatibility system
Resolves critical Safari hanging issues through multi-layered protection:

Core Safari Resource Loading Bypass:
- Added Safari-specific minimal asset loading in HVAC_Scripts_Styles
- Prevents 35+ CSS file cascade that overwhelmed Safari rendering
- Implements intelligent browser detection with fallback systems
- Loads only essential CSS/JS files for Safari browsers
- Dequeues non-critical assets to prevent resource overload

Browser Detection Infrastructure:
- Created HVAC_Browser_Detection class with accurate Safari identification
- Added User-Agent parsing with version detection
- Implements fallback detection methods for edge cases
- Provides centralized browser compatibility services

Find Trainer Assets Management:
- Added HVAC_Find_Trainer_Assets class for proper WordPress hook timing
- Ensures Safari-compatible script loading order
- Prevents asset loading conflicts with theme integration

Safari Debugging System:
- Implemented HVAC_Safari_Request_Debugger for server-side monitoring
- Added comprehensive Safari debugging with error tracking
- Created detailed investigation documentation
- Provides real-time Safari compatibility insights

Performance Optimizations:
- Optimized database queries in find-trainer template to prevent hanging
- Implemented lazy component loading in HVAC_Plugin initialization
- Reduced Astra theme override hook priorities from 999 to 50
- Removed CSS @import statements causing Safari render blocking

MapGeo Integration Fixes:
- Fixed JavaScript syntax error (dangling }) in MapGeo integration
- Removed problematic console.log override causing Safari conflicts
- Maintained full MapGeo functionality while preventing browser hangs

Testing Results:
- Verified with Playwright WebKit engine (Safari emulation)
- Page loads successfully with complete functionality
- Interactive map, trainer cards, and navigation all functional
- Reduced CSS files from 35+ to 3 core files for optimal performance
- No hanging or blank page issues detected

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 21:13:43 -03:00

186 lines
No EOL
5.2 KiB
PHP

<?php
/**
* HVAC Browser Detection Service
*
* Centralized browser detection and compatibility handling
*
* @package HVAC_Community_Events
* @since 1.0.0
*/
// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}
/**
* HVAC Browser Detection Service
*/
class HVAC_Browser_Detection {
/**
* Instance
*
* @var HVAC_Browser_Detection
*/
private static $instance = null;
/**
* Cached user agent
*
* @var string
*/
private $user_agent = '';
/**
* Browser detection cache
*
* @var array
*/
private $browser_cache = [];
/**
* Get instance
*/
public static function instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
private function __construct() {
$this->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
}
/**
* Detect if user is using Safari browser
* Enhanced version with better detection accuracy
*
* @return bool
*/
public function is_safari_browser() {
if (isset($this->browser_cache['is_safari'])) {
return $this->browser_cache['is_safari'];
}
if (empty($this->user_agent)) {
$this->browser_cache['is_safari'] = false;
return false;
}
// Check for Safari but not Chrome/Chromium (Chrome contains Safari in UA)
// Also exclude Edge and other WebKit-based browsers
$is_safari = (strpos($this->user_agent, 'Safari') !== false &&
strpos($this->user_agent, 'Chrome') === false &&
strpos($this->user_agent, 'Chromium') === false &&
strpos($this->user_agent, 'Edge') === false &&
strpos($this->user_agent, 'Edg') === false);
// Additional Safari-specific checks
if ($is_safari) {
// Verify it's actually Safari by checking for Version string (Safari-specific)
$is_safari = strpos($this->user_agent, 'Version/') !== false ||
strpos($this->user_agent, 'Safari/') !== false;
}
$this->browser_cache['is_safari'] = $is_safari;
// Debug logging
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('[HVAC Browser Detection] Safari check: ' . ($is_safari ? 'true' : 'false') . ' | UA: ' . substr($this->user_agent, 0, 100));
}
return $is_safari;
}
/**
* Detect if user is using Mobile Safari (iPhone/iPad)
*
* @return bool
*/
public function is_mobile_safari() {
if (isset($this->browser_cache['is_mobile_safari'])) {
return $this->browser_cache['is_mobile_safari'];
}
$is_mobile_safari = $this->is_safari_browser() &&
(strpos($this->user_agent, 'iPhone') !== false ||
strpos($this->user_agent, 'iPad') !== false ||
strpos($this->user_agent, 'iPod') !== false);
$this->browser_cache['is_mobile_safari'] = $is_mobile_safari;
return $is_mobile_safari;
}
/**
* Get Safari version if available
*
* @return string|null Safari version or null if not Safari
*/
public function get_safari_version() {
if (!$this->is_safari_browser()) {
return null;
}
if (isset($this->browser_cache['safari_version'])) {
return $this->browser_cache['safari_version'];
}
$version = null;
// Extract version from user agent
if (preg_match('/Version\/([0-9]+(?:\.[0-9]+)*)/', $this->user_agent, $matches)) {
$version = $matches[1];
}
$this->browser_cache['safari_version'] = $version;
return $version;
}
/**
* Check if Safari version supports ES6+ features
* Safari 10+ has good ES6 support
*
* @return bool
*/
public function safari_supports_es6() {
if (!$this->is_safari_browser()) {
return true; // Not Safari, assume other browsers support ES6
}
$version = $this->get_safari_version();
if (!$version) {
return false; // Unknown version, assume no ES6 support
}
// Safari 10+ has good ES6 support
return version_compare($version, '10.0', '>=');
}
/**
* Get browser info for debugging
*
* @return array
*/
public function get_browser_info() {
return [
'user_agent' => $this->user_agent,
'is_safari' => $this->is_safari_browser(),
'is_mobile_safari' => $this->is_mobile_safari(),
'safari_version' => $this->get_safari_version(),
'supports_es6' => $this->safari_supports_es6(),
];
}
/**
* Clear browser detection cache
* Useful for testing or if user agent changes
*/
public function clear_cache() {
$this->browser_cache = [];
}
}