Skip to content

Commit 9f429c8

Browse files
jvillegasdclaude
andauthored
feat: iframe-and-UI: iframe detection and UI/UX refactor (#27)
* feat: modern dark-first UI redesign with Inter font and teal accent Replace generic system fonts and Google Blue aesthetic with a cohesive design system: Inter typeface, blue-tinted dark surfaces, teal accent, semantic color tokens, and consistent spacing/radius variables. Remove 3 duplicated bottom bars (~180 lines), add compact header with theme toggle and settings, rich empty states with SVG icons, left-border warning cards, unified progress bars (shimmer animation for both download and recording states), and section-level clear buttons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: detect videos inside iframes Enable content script in all frames (all_frames: true) so videos embedded in iframes are detected. Popup queries all frames via webNavigation.getAllFrames and deduplicates by normalized URL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 71873c2 commit 9f429c8

File tree

11 files changed

+1202
-1389
lines changed

11 files changed

+1202
-1389
lines changed

manifest.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"downloads",
1313
"tabs",
1414
"activeTab",
15-
"offscreen"
15+
"offscreen",
16+
"webNavigation"
1617
],
1718
"host_permissions": [
1819
"http://*/*",
@@ -40,7 +41,7 @@
4041
"content.js"
4142
],
4243
"run_at": "document_idle",
43-
"all_frames": false
44+
"all_frames": true
4445
}
4546
],
4647
"options_page": "options/options.html",

public/fonts/inter-medium.woff2

23.8 KB
Binary file not shown.

public/fonts/inter-regular.woff2

23.3 KB
Binary file not shown.

public/fonts/inter-semibold.woff2

23.9 KB
Binary file not shown.

src/content.ts

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ let detectedVideos: Record<string, VideoMetadata> = {};
1313
let detectionManager: DetectionManager;
1414
let sentToPopup = new Set<string>();
1515
let lastUrl = location.href;
16-
17-
function isInIframe(): boolean {
18-
return window.location !== window.parent.location;
19-
}
16+
const inIframe = window.self !== window.top;
2017

2118
/**
2219
* Send message to popup with error handling for extension context invalidation
@@ -162,10 +159,12 @@ function addDetectedVideo(video: VideoMetadata) {
162159
* Sets up detection manager, performs initial scan, and monitors DOM changes
163160
*/
164161
function init() {
165-
// Reset icon to gray on page load
166-
safeSendMessage({
167-
type: MessageType.SET_ICON_GRAY,
168-
});
162+
// Reset icon to gray on page load (only from top frame)
163+
if (!inIframe) {
164+
safeSendMessage({
165+
type: MessageType.SET_ICON_GRAY,
166+
});
167+
}
169168

170169
detectionManager = new DetectionManager({
171170
onVideoDetected: (video) => {
@@ -204,30 +203,27 @@ function handleNavigation(): void {
204203
init();
205204
}
206205

207-
// Listen for SPA navigations (History API)
208-
window.addEventListener("popstate", handleNavigation);
209-
210-
// Intercept pushState/replaceState since they don't fire popstate
211-
const origPushState = history.pushState.bind(history);
212-
const origReplaceState = history.replaceState.bind(history);
213-
history.pushState = function (...args) {
214-
origPushState(...args);
215-
handleNavigation();
216-
};
217-
history.replaceState = function (...args) {
218-
origReplaceState(...args);
219-
handleNavigation();
220-
};
206+
// Listen for SPA navigations (History API) — only in top frame
207+
if (!inIframe) {
208+
window.addEventListener("popstate", handleNavigation);
209+
210+
// Intercept pushState/replaceState since they don't fire popstate
211+
const origPushState = history.pushState.bind(history);
212+
const origReplaceState = history.replaceState.bind(history);
213+
history.pushState = function (...args) {
214+
origPushState(...args);
215+
handleNavigation();
216+
};
217+
history.replaceState = function (...args) {
218+
origReplaceState(...args);
219+
handleNavigation();
220+
};
221+
}
221222

222223
/**
223224
* Listen for messages from popup and service worker
224225
*/
225226
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
226-
if (isInIframe()) {
227-
console.debug("In iframe context");
228-
return true;
229-
}
230-
231227
// Check if extension context is still valid
232228
if (chrome.runtime.lastError) {
233229
const errorMessage = chrome.runtime.lastError.message || "";
@@ -263,10 +259,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
263259
}
264260
});
265261

266-
if (!isInIframe()) {
267-
if (document.readyState === "loading") {
268-
document.addEventListener("DOMContentLoaded", init);
269-
} else {
270-
init();
271-
}
262+
if (document.readyState === "loading") {
263+
document.addEventListener("DOMContentLoaded", init);
264+
} else {
265+
init();
272266
}

0 commit comments

Comments
 (0)