Hello,
im using wxWebView with Edge backend. Is it possible to execute javascript code and getting elements inside an iframe?
I can do this with EnableAccessToDevTools(), switch context and write code in console.
With RunScriptAsync() i get error message: TypeError: Cannot read properties of undefined (reading 'children')
(im using wxWidgets 3.2.2.1)
Greets
wxWebView run JavaScript code in iframes? Topic is solved
wxWebView run JavaScript code in iframes?
OS: Windows 11
Compiler: mingw-w64-i686
wxWidgets: 3.2.2.1
Compiler: mingw-w64-i686
wxWidgets: 3.2.2.1
Re: wxWebView run JavaScript code in iframes?
That should be possible. I guess you're executing the JS code too early, but without seeing code, i can't tell more.
Use the source, Luke!
Re: wxWebView run JavaScript code in iframes?
Hey, thank you for fast reply!
Here is my main frame code:
Here are my Handlers:
Here im running RunScriptAsync() from another dialog when i press a button:
I cant show the website URL unfortunately as its for my work, but it looks something like this:
The website is completly loaded when i try to run the script.
Inside dev tools i can just switch the context to example-iframe.com and run my JS code from console.
To be honest I dont have much knowledge about web development, i hope my question is not too stupid
Best regards
Here is my main frame code:
Code: Select all
WebViewFrame::WebViewFrame(wxWindow* parent,wxWindowID id)
{
...
...
WebView = wxWebView::New(this, wxID_ANY);
WebView -> LoadURL("https://www.example.com/en/smtng/");
BoxSizer1 -> Add(WebView, 1, wxALL|wxEXPAND);
WebView -> EnableAccessToDevTools();
WebView -> Bind(wxEVT_WEBVIEW_LOADED, &WebViewFrame::Loaded, this);
WebView -> Bind(wxEVT_WEBVIEW_SCRIPT_RESULT, &WebViewFrame::ScriptHandler, this);
}
Code: Select all
void WebViewFrame::ScriptHandler(wxWebViewEvent& event){
std::cout << event.GetString() << "\nError: " << event.IsError() << std::endl;
}
void WebViewFrame::Loaded(wxWebViewEvent& event){
std::cout << "Document loaded\n";
}
Code: Select all
void Dia::OnButton1Click(wxCommandEvent& event){
main -> WebView -> RunScriptAsync("document.getElementsByClassName(\"btn\")[0].children[0].children[0].innerHTML", data);
}
The website is completly loaded when i try to run the script.
Inside dev tools i can just switch the context to example-iframe.com and run my JS code from console.
To be honest I dont have much knowledge about web development, i hope my question is not too stupid
Best regards
OS: Windows 11
Compiler: mingw-w64-i686
wxWidgets: 3.2.2.1
Compiler: mingw-w64-i686
wxWidgets: 3.2.2.1
Re: wxWebView run JavaScript code in iframes?
I don't know too much about web dev either, but Google lets me believe that you can't access elements in an iframe directly that way.
Try this:
https://www.w3schools.com/howto/howto_j ... iframe.asp
Try this:
https://www.w3schools.com/howto/howto_j ... iframe.asp
Use the source, Luke!
Re: wxWebView run JavaScript code in iframes?
Im getting Uncaught DOMException: Blocked a frame with origin "https://example.com" from accessing a cross-origin frame.
probably because i cant switch to right execution context!
But i found something in Win32 api:
https://learn.microsoft.com/en-us/micro ... cutescript
https://learn.microsoft.com/en-us/micro ... cutescript
This code looks terrible, but i think i have to switch to native windows api unfortunately.
Maybe wxDevs can push something like this in next major update
best regards
Edit: actually it works with win api
probably because i cant switch to right execution context!
But i found something in Win32 api:
https://learn.microsoft.com/en-us/micro ... cutescript
It should be possible to call ICoreWebView2Frame2::ExecuteScript and run JS code inside the right context.A WebView2 app can run any JavaScript in a frame, by using ExecuteScript.
In order for script to be run in an iframe, an execution context must be created. An execution context is created after the ContentLoading event, that's why if ExecuteScript is called before the ContentLoading event is raised, the script will not be run and the string null will be returned.
For information about the ContentLoading event, see Navigation events for WebView2 apps, which is valid for frames as well as webpages.
https://learn.microsoft.com/en-us/micro ... cutescript
Code: Select all
wil::com_ptr<ICoreWebView2_4> webview2_4 = m_webView.try_query<ICoreWebView2_4>();
if (webview2_4)
{
CHECK_FAILURE(webview2_4->add_FrameCreated(
Callback<ICoreWebView2FrameCreatedEventHandler>(
[](ICoreWebView2* sender, ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT {
wil::com_ptr<ICoreWebView2Frame> webviewFrame;
CHECK_FAILURE(args->get_Frame(&webviewFrame));
wil::com_ptr<ICoreWebView2Frame2> frame2 =
webviewFrame.try_query<ICoreWebView2Frame2>();
if (frame2)
{
frame2->add_DOMContentLoaded(
Callback<ICoreWebView2FrameDOMContentLoadedEventHandler>(
[](ICoreWebView2Frame* frame,
ICoreWebView2DOMContentLoadedEventArgs* args) -> HRESULT {
wil::com_ptr<ICoreWebView2Frame2> frame2;
frame->QueryInterface(IID_PPV_ARGS(&frame2));
frame2->ExecuteScript(
LR"~(
let content = document.createElement("h2");
content.style.color = 'blue';
content.textContent = "This text was added to the iframe by the host app";
document.body.appendChild(content);
)~",
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
[](HRESULT error, PCWSTR result) -> HRESULT {
// Handle ExecuteScript error and result here if needed
// or pass nullptr as callback parametr otherwise.
return S_OK;
})
.Get());
return S_OK;
})
.Get(),
NULL);
}
return S_OK;
})
.Get(),
&m_frameCreatedToken));
}
Maybe wxDevs can push something like this in next major update
best regards
Edit: actually it works with win api
OS: Windows 11
Compiler: mingw-w64-i686
wxWidgets: 3.2.2.1
Compiler: mingw-w64-i686
wxWidgets: 3.2.2.1