detached 2db2e40

fix(webkit): prevent script injection into iframes causing message spam

Changed all UserContent script injections from UserContentInjectAllFrames
to UserContentInjectTopFrame. Previously, scripts were being injected into
every iframe on a page, causing duplicate color palette requests and other
bridge messages (100+ messages per page with many iframes).

Scripts that only need to run in the top-level page:
- WebView ID and GTK theme detection
- Color palette config and color-scheme detection
- Main-world bridge (omnibox, OAuth, console capture)
- GUI controls

This fix dramatically reduces message spam and improves performance.
commit
2db2e408e0285c61ae75e853bc35c9de7eac990c
author
bamen · · 2025-10-15 05:14 UTC
parent
2217286
signature
unsigned
1 file · +6 -6
M pkg/webkit/user_content.go +6 -6
@@ -30,7 +30,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
3030 `, webviewID)
3131 ucm.AddScript(webkit.NewUserScript(
3232 webviewIDScript,
33- webkit.UserContentInjectAllFrames,
33+ webkit.UserContentInjectTopFrame, // Only top frame needs the webview ID
3434 webkit.UserScriptInjectAtDocumentStart,
3535 nil,
3636 nil,
@@ -43,7 +43,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
4343 gtkThemeScript := fmt.Sprintf(`window.__dumber_gtk_prefers_dark = %t;`, prefersDark)
4444 ucm.AddScript(webkit.NewUserScript(
4545 gtkThemeScript,
46- webkit.UserContentInjectAllFrames,
46+ webkit.UserContentInjectTopFrame, // Only top frame needs theme preference
4747 webkit.UserScriptInjectAtDocumentStart,
4848 nil,
4949 nil,
@@ -56,7 +56,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
5656 paletteScript := fmt.Sprintf(`window.__dumber_palette = %s;`, appearanceConfigJSON)
5757 ucm.AddScript(webkit.NewUserScript(
5858 paletteScript,
59- webkit.UserContentInjectAllFrames,
59+ webkit.UserContentInjectTopFrame, // Only top frame needs palette config
6060 webkit.UserScriptInjectAtDocumentStart,
6161 nil,
6262 nil,
@@ -68,7 +68,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
6868 if assets.ColorSchemeScript != "" {
6969 ucm.AddScript(webkit.NewUserScript(
7070 assets.ColorSchemeScript,
71- webkit.UserContentInjectAllFrames,
71+ webkit.UserContentInjectTopFrame, // Only top frame needs color scheme detection
7272 webkit.UserScriptInjectAtDocumentStart,
7373 nil, // whitelist (nil = all)
7474 nil, // blacklist (nil = none)
@@ -80,7 +80,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
8080 if assets.MainWorldScript != "" {
8181 ucm.AddScript(webkit.NewUserScript(
8282 assets.MainWorldScript,
83- webkit.UserContentInjectAllFrames,
83+ webkit.UserContentInjectTopFrame, // Only top frame needs bridge/UI functionality
8484 webkit.UserScriptInjectAtDocumentStart,
8585 nil,
8686 nil,
@@ -92,7 +92,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
9292 if assets.GUIScript != "" {
9393 ucm.AddScript(webkit.NewUserScript(
9494 assets.GUIScript,
95- webkit.UserContentInjectAllFrames,
95+ webkit.UserContentInjectTopFrame, // Only top frame needs GUI controls
9696 webkit.UserScriptInjectAtDocumentStart,
9797 nil,
9898 nil,
@@ -30,7 +30,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
30 `, webviewID)30 `, webviewID)
31 ucm.AddScript(webkit.NewUserScript(31 ucm.AddScript(webkit.NewUserScript(
32 webviewIDScript,32 webviewIDScript,
33- webkit.UserContentInjectAllFrames,33+ webkit.UserContentInjectTopFrame, // Only top frame needs the webview ID
34 webkit.UserScriptInjectAtDocumentStart,34 webkit.UserScriptInjectAtDocumentStart,
35 nil,35 nil,
36 nil,36 nil,
@@ -43,7 +43,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
43 gtkThemeScript := fmt.Sprintf(`window.__dumber_gtk_prefers_dark = %t;`, prefersDark)43 gtkThemeScript := fmt.Sprintf(`window.__dumber_gtk_prefers_dark = %t;`, prefersDark)
44 ucm.AddScript(webkit.NewUserScript(44 ucm.AddScript(webkit.NewUserScript(
45 gtkThemeScript,45 gtkThemeScript,
46- webkit.UserContentInjectAllFrames,46+ webkit.UserContentInjectTopFrame, // Only top frame needs theme preference
47 webkit.UserScriptInjectAtDocumentStart,47 webkit.UserScriptInjectAtDocumentStart,
48 nil,48 nil,
49 nil,49 nil,
@@ -56,7 +56,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
56 paletteScript := fmt.Sprintf(`window.__dumber_palette = %s;`, appearanceConfigJSON)56 paletteScript := fmt.Sprintf(`window.__dumber_palette = %s;`, appearanceConfigJSON)
57 ucm.AddScript(webkit.NewUserScript(57 ucm.AddScript(webkit.NewUserScript(
58 paletteScript,58 paletteScript,
59- webkit.UserContentInjectAllFrames,59+ webkit.UserContentInjectTopFrame, // Only top frame needs palette config
60 webkit.UserScriptInjectAtDocumentStart,60 webkit.UserScriptInjectAtDocumentStart,
61 nil,61 nil,
62 nil,62 nil,
@@ -68,7 +68,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
68 if assets.ColorSchemeScript != "" {68 if assets.ColorSchemeScript != "" {
69 ucm.AddScript(webkit.NewUserScript(69 ucm.AddScript(webkit.NewUserScript(
70 assets.ColorSchemeScript,70 assets.ColorSchemeScript,
71- webkit.UserContentInjectAllFrames,71+ webkit.UserContentInjectTopFrame, // Only top frame needs color scheme detection
72 webkit.UserScriptInjectAtDocumentStart,72 webkit.UserScriptInjectAtDocumentStart,
73 nil, // whitelist (nil = all)73 nil, // whitelist (nil = all)
74 nil, // blacklist (nil = none)74 nil, // blacklist (nil = none)
@@ -80,7 +80,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
80 if assets.MainWorldScript != "" {80 if assets.MainWorldScript != "" {
81 ucm.AddScript(webkit.NewUserScript(81 ucm.AddScript(webkit.NewUserScript(
82 assets.MainWorldScript,82 assets.MainWorldScript,
83- webkit.UserContentInjectAllFrames,83+ webkit.UserContentInjectTopFrame, // Only top frame needs bridge/UI functionality
84 webkit.UserScriptInjectAtDocumentStart,84 webkit.UserScriptInjectAtDocumentStart,
85 nil,85 nil,
86 nil,86 nil,
@@ -92,7 +92,7 @@ func SetupUserContentManager(view *webkit.WebView, appearanceConfigJSON string,
92 if assets.GUIScript != "" {92 if assets.GUIScript != "" {
93 ucm.AddScript(webkit.NewUserScript(93 ucm.AddScript(webkit.NewUserScript(
94 assets.GUIScript,94 assets.GUIScript,
95- webkit.UserContentInjectAllFrames,95+ webkit.UserContentInjectTopFrame, // Only top frame needs GUI controls
96 webkit.UserScriptInjectAtDocumentStart,96 webkit.UserScriptInjectAtDocumentStart,
97 nil,97 nil,
98 nil,98 nil,

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close