Browser Extension Overview
Relevant source files
The following files were used as context for generating this wiki page:- apps/extensions/src/manifest.json
- apps/extensions/src/background.ts
- apps/extensions/webpack.config.js
- apps/extensions/package.json
- README.md
- apps/extensions/src/content/utilities/screen.ts
- apps/extensions/src/app/messagess.ts
- apps/extensions/src/content/popup/popup.tsx
- apps/extensions/src/content/panel/panel.tsx
- apps/portal/pages/authorize.tsx
The Ever Rec browser extension is a core component of the Ever Rec platform, providing users with the ability to capture their screen, record video, and manage their media directly from the browser. It is designed to integrate seamlessly with the user's workflow, offering features like visible part capture, full-page screenshots, screen/window recording, and camera-only recording. The extension is built as a standalone module within the ever-rec monorepo.
The extension's architecture is composed of several key parts: a background service worker for core logic, content scripts for interacting with web pages, a popup for quick actions, and a set of panel pages for more complex user interactions like editing and media management. These components communicate through a message-passing system, enabling a decoupled yet powerful set of functionalities.
Architecture
The browser extension follows a standard, event-driven architecture common to modern browser extensions. It consists of four primary components that work together to provide its features.
- Background Script: The central nervous system of the extension. It's a persistent service worker that handles events, manages state, and coordinates actions between other components.
- Content Scripts: JavaScript files injected into web pages. They have access to the DOM and are used for tasks like selecting an area for a screenshot or displaying recording controls on the active tab.
- Popup: A small UI window that appears when the user clicks the extension's icon in the browser toolbar. It serves as the main entry point for capture and record actions.
- Panel Pages: Full-page HTML documents bundled with the extension. They provide rich user interfaces for tasks such as image/video editing, viewing media libraries, managing settings, and handling authentication.
This diagram illustrates the high-level architecture and communication paths between the components.
Manifest (manifest.json)
The manifest.json file is the entry point and configuration file for the extension. It defines the extension's capabilities, permissions, and core components.
| Key | Description |
|---|---|
manifest_version | Specifies the manifest version, which is 3. |
name | The full name of the extension displayed in the browser's extension management page. |
version | The version of the extension, populated during the build process from package.json. |
permissions | A list of permissions the extension requires, such as activeTab, storage, desktopCapture, and cookies. |
host_permissions | Grants access to all URLs (<all_urls>), allowing the content script to be injected anywhere. |
action | Defines the browser action, which is the popup UI (popup/popup.html) that opens when the extension icon is clicked. |
background | Configures the background service worker (background.js). |
content_scripts | Defines the content scripts (content/content.js) to be injected into web pages matching <all_urls>. |
web_accessible_resources | Exposes certain extension resources (like HTML pages and images) to web pages. |
externally_connectable | Allows the web application (e.g., app.rec.so, localhost:4200) to communicate with the extension. |
Sources: apps/extensions/src/manifest.json
Build Process
The extension is built using Webpack, as configured in webpack.config.js. This file defines the entry points for the different parts of the extension.
| Entry Point | Output File | Description |
|---|---|---|
content/content | content/content.js | The content script injected into web pages. |
background | background.js | The background service worker. |
popup/popup | popup/popup.js | The script for the main popup UI. |
panel/panel | panel/panel.js | The script for the main panel UI. |
recording/recording | recording/recording.js | The script for recording-specific UIs. |
The build process also uses CopyPlugin to copy static assets and generate multiple HTML files (e.g., edit.html, video.html, settings/profile.html) from a single template, which are used for the various panel pages. The manifest.json is also transformed to inject the correct version number.
Sources: apps/extensions/webpack.config.js:14-22, apps/extensions/webpack.config.js:154-160
Core Components
Background Script (background.ts)
The background script is the central controller. It listens for various browser and extension events and orchestrates the application's logic.
Key Responsibilities:
- Lifecycle Management: Handles
onInstalledevents to set up initial storage, inject content scripts into existing tabs, and open a login/welcome page. - State Management: Uses
chrome.storage.localandchrome.storage.syncto store user authentication tokens (idToken), recording status, and user preferences. - Message Handling: Contains the main message listener (
chrome.runtime.onMessage.addListener) that routes incoming messages from other parts of the extension to the appropriate handlers. - Authentication Flow: Listens for external messages (
onMessageExternal) from the web portal to receive and store user credentials after a successful login. It also handles sign-out events. - Capture & Recording Orchestration: Initiates capture and recording processes by communicating with content scripts and using Chrome APIs like
chrome.tabs.captureVisibleTabandchrome.desktopCapture. - UI Management: Creates and manages new tabs or windows for the editor, video player, and other panel pages.
Sources: apps/extensions/src/background.ts:20-49, apps/extensions/src/background.ts:54-61, apps/extensions/src/background.ts:413-455
Content Scripts
A content script (content/content.js) is injected into every webpage (<all_urls>). Its primary role is to interact with the DOM of the host page, which the background script cannot do directly.
Key Responsibilities:
- DOM Manipulation: Hides scrollbars during a full-page capture and manipulates
position: fixedelements to ensure a clean screenshot. - Selected Area Capture: Overlays a selection tool on the page, allowing the user to draw a rectangle for a partial screenshot.
- UI Injection: Injects and manages the recording controller UI on the page during tab or screen recording.
- Communication: Listens for messages from the background script (e.g., to start a capture) and sends messages back (e.g., with the coordinates of a selected area).
The logic for full-page capture, for instance, involves programmatically scrolling the page, capturing the visible part at each step, and then stitching the images together.
// Example of full-page capture logic
export async function fullPageCapture() {
// ...
const visibleHeight = window.visualViewport?.height || window.innerHeight;
const numberOfScrolls = pageHeight / visibleHeight;
window.scrollTo(0, 0);
for (let i = 0; i <= numberOfScrolls; i++) {
if (i > 0) window.scrollBy({ top: visibleHeight });
// ...
manipulateFixedElements(false);
// ...
const data = await getVisibleBase64();
imgsBase64.push(data);
// ...
}
// ... stitch images together
}
Sources: apps/extensions/src/content/utilities/screen.ts:19-67, apps/extensions/src/manifest.json:34-43
UI Components (Popup & Panel)
The extension has two main types of user interfaces, both built with React.
- Popup (
popup.tsx): This is the quick-action menu. It presents the user with the primary options: different types of screenshots and recordings. When a user clicks an option, the popup sends a message to the background script to initiate the action. - Panel (
panel.tsx): These are full-page UIs for more complex interactions. Thewebpack.config.jsshows that many HTML files (edit.html,video.html,settings/profile.html, etc.) are created, all pointing to the samepanel/panel.jsbundle. This indicates a single-page application (SPA) architecture where routing is handled internally to display the correct view (e.g., image editor, video trimmer, user settings). These pages are opened in new tabs by the background script.
Sources: apps/extensions/src/manifest.json:29-32, apps/extensions/webpack.config.js:23-26, apps/extensions/webpack.config.js:161-267
Communication Protocol
Communication between the extension's components is asynchronous and relies on a message-passing system provided by the chrome.runtime and chrome.tabs APIs.
The message structure is defined by the IAppMessage interface, which includes an action (of type AppMessagesEnum) and an optional payload.
This diagram shows the flow for a "Visible Part Capture" action.
Key Message Actions
The AppMessagesEnum defines the vocabulary for inter-component communication.
| Action | Sender -> Receiver | Description |
|---|---|---|
createLoginTabSW | Popup/Content -> Background | Requests the background script to open a new tab for user login. |
visiblePartCaptureSW | Popup -> Background | Initiates a capture of the currently visible part of the active tab. |
selectedAreaCaptureSW | Popup -> Background | Initiates a selected area capture, which is then delegated to the content script. |
stopRecordingSW | Popup/Content -> Background | Signals the end of a recording session. |
sendImageToEditorPage | Background -> Panel | Sends the captured image data (as base64) to the newly opened editor page. |
startVideo | Background -> Background | Handles the setup for starting a video recording, creating the necessary UI windows. |
stopVideo | Content -> Background | Sends the recorded video blobs to the background script to be processed and opened in the video editor. |
Sources: apps/extensions/src/background.ts
Authentication and External Communication
The extension authenticates users via the main web portal. The flow is as follows:
- The extension opens a login tab on the web portal (
app.rec.soorlocalhost:4200). - The user logs in on the web page (e.g., using Google OAuth).
- The web portal uses
chrome.runtime.sendMessageto send the authentication tokens (idToken,refreshToken, etc.) to the extension. This is possible because the portal's URL is listed inexternally_connectablein the manifest. - The background script's
onMessageExternallistener catches this message and securely stores the user's credentials inchrome.storage.local.
A similar flow exists on the authorize.tsx page, which handles OAuth redirects and uses a custom protocol (ever-rec://) to pass tokens to the desktop application.
Sources: apps/extensions/src/manifest.json:56-63, apps/extensions/src/background.ts:413-417, apps/extensions/src/background.ts:457-483, apps/portal/pages/authorize.tsx
Summary
The Ever Rec browser extension is a well-structured module that leverages standard browser extension APIs to deliver its functionality. Its architecture separates concerns effectively between the background script (logic), content scripts (DOM interaction), and React-based UI components (popup and panels). Communication is handled via a robust message-passing system, and it integrates with the broader Ever Rec ecosystem for authentication and data synchronization. The use of Webpack for the build process allows for a modern development workflow with TypeScript and React, compiling everything into a distributable package for various browsers.