The WindowsManager system is built upon a centralized Vue.js UI Host architecture. It manages the lifecycle of translation windows and icons through event-based messaging with the UI Host, which resides within a secure Shadow DOM. This ensures complete CSS/JS isolation and a clear separation between business logic and UI rendering.
The system follows a strict Decoupled Architecture:
- WindowsManager: Acts as the business logic orchestrator, managing state and coordinating events.
- Vue UI Host: Handles all UI rendering and user interaction within the Shadow DOM.
- Event-Based Communication: All interaction between the logic and UI layers occurs via
PageEventBus. - Shadow DOM Isolation: Prevents host webpage styles from leaking into the extension UI and vice-versa.
To manage growing complexity (previously over 2000 lines), the WindowsManager has been refactored into a Facade Pattern. The main class now delegates specialized responsibilities to dedicated sub-managers.
WindowsManager(Facade): The primary entry point and singleton. It coordinates high-level operations and maintains the public API.DisplayManager: Handles all UI presentation logic, including showing translation windows, icons, and mobile sheets. It manages the two-phase loading process.DismissalManager: Manages the complex logic for dismissing UI elements, handling outside clicks, and coordinating text selection preservation.EventCoordinator: Orchestrates event listeners for thePageEventBusand handles cross-frame messaging logic.
- Single Responsibility: Each sub-manager focuses on a specific domain (Display, Dismissal, or Events).
- Reduced Cognitive Load: Files are now smaller and focused (~200-500 lines instead of 2000+).
- Testability: Independent managers can be unit-tested more effectively.
- Safe Development: Changes to dismissal logic are isolated from presentation logic, reducing the risk of regressions.
The WindowsManager has been further decoupled from text selection detection. It no longer acts as a gateway for other UI modules (like FAB). Instead, it operates as a subscriber to global selection events.
- Selection Detection:
SelectionManagerorTextFieldDoubleClickHandlerdetects text. - Broadcasting: A
GLOBAL_SELECTION_CHANGEevent is emitted viaPageEventBus. - Reaction:
WindowsManagerreceives the event and independently decides whether to show its UI based on:- User settings (onClick vs Immediate).
- Keyboard modifiers (Ctrl key requirement).
- Existing Window State: If a window is already Pinned or Docked, it performs an In-place Update (bypassing icon display).
- URL exclusions.
The translation window now supports persistent states through Pinning and Docking.
- Mechanism: Prevents automatic dismissal when clicking outside the window or when the global selection is cleared.
- Implementation:
ClickManagerandWindowsManagercheckstate.isPinnedbefore executing dismissal logic. - Persistence: Saved via
WINDOW_IS_PINNEDsetting.
- Dock Modes:
none,left,right. - Edge Snapping: Implemented in
usePositioning.js. When dragging, if the mouse pointer reaches within 30px of the viewport edge, the window automatically docks. - Breakaway Logic: To undock, the user must drag the pointer 100px away from the edge.
- Viewport Accuracy: Uses
document.documentElement.clientWidthinstead ofwindow.innerWidthto account for browser scrollbars, ensuring the window is never hidden underneath them. - Resizable Sidebar: Docked windows take 100vh height and support width resizing via an interactive handle on the inner edge.
To improve performance and eliminate UI flicker, the system now updates existing windows instead of re-creating them:
- Trigger: When a new selection occurs while a window is already visible and Pinned/Docked.
- Atomic Update: Emits an
updateWindowevent with newselectedTextandisLoading: true. - Cancellation: Automatically cancels any ongoing translation requests from the previous selection to prevent race conditions.
show-window- Request to show a translation windowdismiss-window- Request to dismiss a windowtranslation-loading- Show loading state in windowtranslation-result- Display translation resulttranslation-error- Display error messagetranslation-window-change-provider- User requested to change translation provider
show-icon- Request to show a translation icondismiss-icon- Request to dismiss an iconicon-clicked- Notify when icon is clicked
{
id: 'unique-window-id',
selectedText: 'text to translate',
position: { x: 100, y: 200 },
mode: 'window', // or 'icon'
provider: 'google_v2', // Optional: Current provider ID
targetLanguage: 'fa' // Optional: Target language code
}{
id: 'unique-icon-id',
text: 'text to translate',
position: { top: 100, left: 200 }
}- Modified
show()method to emit events instead of DOM manipulation - Updated
dismiss()method to emit dismissal events - Added event-based cross-frame communication
- Maintained backward compatibility for existing callers
- TranslationWindow.vue - Handles window rendering and management
- TranslationIcon.vue - Handles selection toolbar rendering and multi-action interactions (Translate, TTS)
- DesktopFabMenu.vue - Persistent floating menu for global actions (See Desktop FAB System)
- MobileSheet.vue - Centralized bottom sheet for mobile browsers (See Mobile Support System)
- ContentApp.vue - Root component that manages all UI elements
- Extended
PageEventBus.jswith WindowsManager-specific events - Added
WindowsManagerEventsutility for consistent event emission - Maintained existing event patterns for consistency
- Reduced DOM manipulation overhead
- Centralized UI rendering in Vue's optimized virtual DOM
- Better memory management with Vue's reactivity system
- Facade Architecture: Logic is split into specialized sub-managers (
DisplayManager,DismissalManager,EventCoordinator). - Clear separation between business logic and UI rendering.
- Consistent UI patterns across the extension.
- Easier debugging with centralized UI management and modular logic.
- Complete CSS isolation through Shadow DOM
- JavaScript isolation from host webpage
- Prevention of style conflicts with websites
- Consistent behavior across Chrome and Firefox
- Better handling of iframe scenarios
- Improved cross-frame communication
The WindowsManager system is fully integrated with the centralized Error Management System:
- Unified Classification: All errors are matched to types via
ErrorMatcherto determine if they are fatal, silent, or require settings. - Consistent UI Messages: Instead of manual error string building,
ErrorHandler.getErrorForUI()is used to provide localized, user-friendly messages. - Context-Aware Actions: The system automatically determines if a "Retry" or "Settings" button should be displayed in the translation window based on the error type (e.g., Network Error vs. Invalid API Key).
- Silent Context Handling: Extension reload/context errors are handled silently via
ExtensionContextManagerto prevent UI glitches.
// Show error with retry/settings support
const errorInfo = await errorHandler.getErrorForUI(error, 'windows-translation');
WindowsManagerEvents.updateWindow(windowId, {
isError: true,
canRetry: errorInfo.canRetry,
needsSettings: errorInfo.needsSettings,
initialTranslatedText: errorInfo.message
});// In WindowsManager
WindowsManagerEvents.showWindow({
id: 'window-123',
selectedText: 'Hello world',
position: { x: 100, y: 200 },
mode: 'window'
});// In WindowsManager
WindowsManagerEvents.showIcon({
id: 'icon-456',
text: 'Selected text',
position: { top: 150, left: 300 }
});// Show loading state
WindowsManagerEvents.translationLoading('window-123');
// Show result
WindowsManagerEvents.translationResult('window-123', {
translatedText: 'سلام دنیا',
originalText: 'Hello world',
provider: 'google_v2',
targetLanguage: 'fa'
});
// Show error
WindowsManagerEvents.translationError('window-123', {
message: 'Translation failed',
error: errorObject,
provider: 'google_v2'
});The WindowsManager now supports per-window provider selection:
- UI Interaction: The
TranslationWindow.vuecomponent includes aProviderSelector. - Event Flow: When a user changes the provider in the window, it emits a
translation-window-change-providerevent. - State Management:
WindowsManagerlistens for this event, updates its internal state (WindowsState.provider), and triggers a re-translation. - Smart Resolution:
TranslationHandleruses a prioritized resolution logic to determine the best provider (Manual Override > Mode-Specific Setting > Global Default).
// Emitted from Vue UI Host
pageEventBus.emit('translation-window-change-provider', {
id: 'window-123',
provider: 'bing'
});The system supports:
- Unit tests for event emission
- Integration tests with Vue components
- Cross-browser compatibility tests
- Performance benchmarking
The WindowsManager integration with the Vue UI Host represents a significant architectural improvement that enhances performance, maintainability, and user experience while maintaining a secure and isolated environment for the extension UI.