1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
Patch status: *should* be fixed in qtwebengine-6.8.2
Somewhat annoying issue for qutebrowser users[1][2] resulting in hints
not always being usable on some google-based sites (e.g. youtube).
Note: as of the writing of this, [3] hasn't been merged upstream (yet)
and so the final version of this patch may differ. Was added here early
to avoid revbumping qtwebengine post-6.8.1 release, final version will
likely land in 6.8.2 instead.
[1] https://github.com/qutebrowser/qutebrowser/issues/8197
[2] https://bugreports.qt.io/browse/QTBUG-131156
[3] https://codereview.qt-project.org/c/qt/qtwebengine/+/604899
--- a/src/core/renderer_host/user_resource_controller_host.cpp
+++ b/src/core/renderer_host/user_resource_controller_host.cpp
@@ -43,8 +43,7 @@
void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameCreated(content::RenderFrameHost *renderFrameHost)
{
- content::WebContents *contents = web_contents();
auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(renderFrameHost);
- const QList<UserScript> scripts = m_controllerHost->m_perContentsScripts.value(contents);
- for (const UserScript &script : scripts)
+ const auto scripts = m_controllerHost->m_perContentsScripts.constFind(web_contents());
+ for (const UserScript &script : *scripts)
remote->AddScript(script.data());
}
@@ -57,4 +56,10 @@
remote->ClearScripts();
}
+ if (newHost) {
+ auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(newHost);
+ const auto scripts = m_controllerHost->m_perContentsScripts.constFind(web_contents());
+ for (const UserScript &script : *scripts)
+ remote->AddScript(script.data());
+ }
}
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -108,4 +108,14 @@
}
+void WebChannelIPCTransportHost::RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost)
+{
+ if (oldHost) {
+ if (oldHost->IsRenderFrameLive())
+ GetWebChannelIPCTransportRemote(oldHost)->ResetWorldId();
+ }
+ if (newHost) // this might set it again, but that is harmless
+ setWorldId(newHost, m_worldId);
+}
+
void WebChannelIPCTransportHost::RenderFrameDeleted(content::RenderFrameHost *rfh)
{
--- a/src/core/renderer_host/web_channel_ipc_transport_host.h
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.h
@@ -46,4 +46,5 @@
// WebContentsObserver
void RenderFrameCreated(content::RenderFrameHost *frame) override;
+ void RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost) override;
void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -70,4 +70,5 @@
void webChannelWithExistingQtObject();
void navigation();
+ void navigation2();
void webChannelWithBadString();
void webChannelWithJavaScriptDisabled();
@@ -578,4 +579,79 @@
}
+void tst_QWebEngineScript::navigation2()
+{
+ QWebEngineProfile profile("navigation2");
+ QWebEnginePage page(&profile, nullptr);
+ QWebChannel channel;
+ page.setWebChannel(&channel);
+ QWebEngineScript s1;
+ s1.setInjectionPoint(QWebEngineScript::DocumentCreation);
+ // Check webchannel is installed before DocumentCreation scripts are run
+ // onload shouldn't have run, and neither should wasready
+ s1.setWorldId(QWebEngineScript::MainWorld);
+ s1.setSourceCode("document.passCreation = 0;" \
+ "if (typeof qt !== undefined) document.passCreation++;" \
+ "if (document.onloadran) document.passCreation++;" \
+ "if (document.wasready) document.passCreation++;");
+ page.scripts().insert(s1);
+ QWebEngineScript s2;
+ s2.setInjectionPoint(QWebEngineScript::DocumentReady);
+ // onload shouldn't have run
+ s2.setWorldId(QWebEngineScript::MainWorld);
+ s2.setSourceCode("document.passReady = 0;" \
+ "if (typeof qt !== undefined) document.passReady++;" \
+ "if (document.passCreation > 0) document.passReady++;" \
+ "if (document.passDeferred > 0) document.passReady++;" \
+ "if (document.onloadran) document.passReady++;" \
+ "if (document.wasready) document.passReady++;");
+ page.scripts().insert(s2);
+ QWebEngineScript s3;
+ s3.setInjectionPoint(QWebEngineScript::Deferred);
+ // all should have run
+ s3.setWorldId(QWebEngineScript::MainWorld);
+ s3.setSourceCode("document.passDeferred = 0;" \
+ "if (typeof qt !== undefined) document.passDeferred++;" \
+ "if (document.passCreation > 0) document.passDeferred++;" \
+ "if (document.passReady > 0) document.passDeferred++;" \
+ "if (document.onloadran) document.passDeferred++;" \
+ "if (document.wasready) document.passDeferred++;");
+ page.scripts().insert(s3);
+
+
+ QString html("<html><head><script>" \
+ " document.onloadran = false; document.wasready = false;"\
+ " document.addEventListener(\"readystatechange\", (x) => { "\
+ " if (x.target.readyState === \"interactive\") document.wasready= true;"\
+ " });"\
+ " function bodyload() { document.onloadran = true; };"\
+ "</script></head>" \
+ "<body onload='bodyload()'><p>hello world</p></body></html>");
+ page.setHtml(html, QUrl("about:blank"));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passCreation", QWebEngineScript::MainWorld),
+ QVariant(1));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passReady", QWebEngineScript::MainWorld),
+ QVariant(3));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passDeferred", QWebEngineScript::MainWorld),
+ QVariant(5));
+
+ QString url2 = QStringLiteral("chrome://gpu/");
+ page.setUrl(url2);
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passCreation", QWebEngineScript::MainWorld),
+ QVariant(1));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passReady", QWebEngineScript::MainWorld),
+ QVariant(2));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passDeferred", QWebEngineScript::MainWorld),
+ QVariant(3));
+
+ QString url3 = QStringLiteral("qrc:/resources/test_iframe_main.html");
+ page.setUrl(url3);
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passCreation", QWebEngineScript::MainWorld),
+ QVariant(1));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passReady", QWebEngineScript::MainWorld),
+ QVariant(2));
+ QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passDeferred", QWebEngineScript::MainWorld),
+ QVariant(3));
+}
+
// Try to set TestObject::text to an invalid UTF-16 string.
//
|