1+ // Listen for messages from the background script or popup
2+ chrome . runtime . onMessage . addListener ( ( request , sender , sendResponse ) => {
3+ if ( request . action === 'detectTheme' ) {
4+ const theme = detectPageTheme ( ) ;
5+ console . log ( `Detecting theme: ${ theme } ` ) ;
6+ sendResponse ( { theme } ) ;
7+ }
8+ if ( request . action === 'getTheme' ) {
9+ const theme = detectPageTheme ( ) ;
10+ console . log ( `Getting theme: ${ theme } ` ) ;
11+ sendResponse ( { theme } ) ;
12+ }
13+ return true ; // Keep the message channel open for asynchronous response
14+ } ) ;
15+ 16+ // Function to detect the theme of the current LeetCode page
17+ function detectPageTheme ( ) {
18+ console . log ( 'Starting theme detection on leetcode page...' ) ;
19+ 20+ // Force a quick check to see if this is a LeetCode page
21+ const url = window . location . href ;
22+ const isLeetCodePage = url . includes ( 'leetcode.com' ) ;
23+ console . log ( 'Is LeetCode page:' , isLeetCodePage , url ) ;
24+ 25+ // Method 1: Check for LeetCode's light theme indicator (most reliable)
26+ // In light mode LeetCode specifically has a white background for these elements
27+ const mainContent = document . querySelector ( '.content__1YWu' ) ||
28+ document . querySelector ( '.problem-description' ) ||
29+ document . querySelector ( '.content-wrapper' ) ;
30+ 31+ if ( mainContent ) {
32+ const bgColor = window . getComputedStyle ( mainContent ) . backgroundColor ;
33+ console . log ( 'Main content background color:' , bgColor ) ;
34+ 35+ // LeetCode light mode has white or very light background
36+ if ( bgColor . includes ( '255, 255, 255' ) || bgColor . includes ( 'rgb(255, 255, 255)' ) ) {
37+ console . log ( 'Theme detected from content: LIGHT (white background)' ) ;
38+ return 'light' ;
39+ }
40+ }
41+ 42+ // Method 2: Check for LeetCode-specific selectors
43+ const darkModeSwitcher = document . querySelector ( '[data-cy="navbar-dark-mode-switcher"]' ) ;
44+ if ( darkModeSwitcher ) {
45+ // If the dark mode switcher has a sun icon, it means we're in light mode
46+ const sunIcon = darkModeSwitcher . querySelector ( 'svg[data-icon="sun"]' ) ;
47+ if ( sunIcon ) {
48+ console . log ( 'Theme detected from dark mode switcher: LIGHT (sun icon visible)' ) ;
49+ return 'light' ;
50+ }
51+ // If the dark mode switcher has a moon icon, it means we're in dark mode
52+ const moonIcon = darkModeSwitcher . querySelector ( 'svg[data-icon="moon"]' ) ;
53+ if ( moonIcon ) {
54+ console . log ( 'Theme detected from dark mode switcher: dark (moon icon visible)' ) ;
55+ return 'dark' ;
56+ }
57+ }
58+ 59+ // Method 3: Check HTML tag class for 'dark' or 'light'
60+ const htmlElement = document . documentElement ;
61+ if ( htmlElement . classList . contains ( 'dark' ) ) {
62+ console . log ( 'Theme detected from HTML class: dark' ) ;
63+ return 'dark' ;
64+ } else if ( htmlElement . classList . contains ( 'light' ) ) {
65+ console . log ( 'Theme detected from HTML class: LIGHT' ) ;
66+ return 'light' ;
67+ }
68+ 69+ // Method 4: Check data-theme attribute
70+ const dataTheme = htmlElement . getAttribute ( 'data-theme' ) ;
71+ if ( dataTheme === 'dark' ) {
72+ console . log ( 'Theme detected from data-theme: dark' ) ;
73+ return 'dark' ;
74+ } else if ( dataTheme === 'light' ) {
75+ console . log ( 'Theme detected from data-theme: LIGHT' ) ;
76+ return 'light' ;
77+ }
78+ 79+ // Method 5: Check header/navbar background color (very reliable for LeetCode)
80+ const header = document . querySelector ( 'header' ) || document . querySelector ( 'nav' ) ;
81+ if ( header ) {
82+ const headerBgColor = window . getComputedStyle ( header ) . backgroundColor ;
83+ console . log ( 'Header background color:' , headerBgColor ) ;
84+ 85+ // LeetCode light mode header is usually white or very light
86+ if ( headerBgColor . includes ( '255, 255, 255' ) ||
87+ headerBgColor . includes ( 'rgb(255, 255, 255)' ) ||
88+ ! isColorDark ( headerBgColor ) ) {
89+ console . log ( 'Theme detected from header: LIGHT' ) ;
90+ return 'light' ;
91+ } else {
92+ console . log ( 'Theme detected from header: dark' ) ;
93+ return 'dark' ;
94+ }
95+ }
96+ 97+ // Method 6: Check the code editor background (LeetCode specific)
98+ const codeEditor = document . querySelector ( '.monaco-editor' ) ;
99+ if ( codeEditor ) {
100+ const editorBgColor = window . getComputedStyle ( codeEditor ) . backgroundColor ;
101+ console . log ( 'Code editor background color:' , editorBgColor ) ;
102+ if ( isColorDark ( editorBgColor ) ) {
103+ console . log ( 'Theme detected from code editor: dark' ) ;
104+ return 'dark' ;
105+ } else {
106+ console . log ( 'Theme detected from code editor: LIGHT' ) ;
107+ return 'light' ;
108+ }
109+ }
110+ 111+ // Method 7: Check background color to determine if dark or light
112+ const backgroundColor = window . getComputedStyle ( document . body ) . backgroundColor ;
113+ console . log ( 'Body background color:' , backgroundColor ) ;
114+ if ( isColorDark ( backgroundColor ) ) {
115+ console . log ( 'Theme detected from body bg: dark' ) ;
116+ return 'dark' ;
117+ } else {
118+ console . log ( 'Theme detected from body bg: LIGHT' ) ;
119+ return 'light' ;
120+ }
121+ }
122+ 123+ // Helper function to determine if a color is dark based on luminance
124+ function isColorDark ( color ) {
125+ // Extract RGB values
126+ const rgb = color . match ( / \d + / g) ;
127+ if ( ! rgb || rgb . length < 3 ) {
128+ console . log ( 'Could not extract RGB values from color:' , color ) ;
129+ return true ; // Default to dark if can't extract
130+ }
131+ 132+ // Calculate relative luminance
133+ const r = parseInt ( rgb [ 0 ] ) / 255 ;
134+ const g = parseInt ( rgb [ 1 ] ) / 255 ;
135+ const b = parseInt ( rgb [ 2 ] ) / 255 ;
136+ 137+ // Weighted luminance formula (human eye is more sensitive to green)
138+ const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b ;
139+ console . log ( `Color luminance: ${ luminance } (< 0.5 is dark)` ) ;
140+ 141+ // Return true for dark colors (lower luminance)
142+ return luminance < 0.5 ;
143+ }
0 commit comments