Add wxWebView child window handling
Add new class wxWebViewWindowInfo: This new class returned by wxWebViewEvent::GetTargetWindowInfo() allows to get information about the window that is about to be opened and to set the window that will be used to display the content.
This commit is contained in:
parent
45d5de6a26
commit
01ee3942f8
8 changed files with 483 additions and 81 deletions
|
|
@ -45,6 +45,8 @@ __CRT_UUID_DECL(ICoreWebView2Settings3, 0xfdb5ab74, 0xaf33, 0x4854, 0x84,0xf0,0x
|
|||
|
||||
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewHandler>, wxStringToWebHandlerMap);
|
||||
|
||||
class wxWebViewEdgeParentWindowInfo;
|
||||
|
||||
class wxWebViewEdgeImpl
|
||||
{
|
||||
public:
|
||||
|
|
@ -53,12 +55,15 @@ public:
|
|||
|
||||
bool Create();
|
||||
|
||||
wxWebViewEdge* CreateChildWebView(std::shared_ptr<wxWebViewEdgeParentWindowInfo> parentWindowInfo);
|
||||
|
||||
wxWebViewEdge* m_ctrl;
|
||||
|
||||
wxCOMPtr<ICoreWebView2Environment> m_webViewEnvironment;
|
||||
wxCOMPtr<ICoreWebView2_2> m_webView;
|
||||
wxCOMPtr<ICoreWebView2Controller> m_webViewController;
|
||||
wxCOMPtr<ICoreWebView2EnvironmentOptions> m_webViewEnvironmentOptions;
|
||||
std::shared_ptr<wxWebViewEdgeParentWindowInfo> m_parentWindowInfo;
|
||||
|
||||
bool m_initialized;
|
||||
bool m_isBusy;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ private:
|
|||
void OnTopLevelParentIconized(wxIconizeEvent& event);
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS(wxWebViewEdge);
|
||||
|
||||
friend class wxWebViewEdgeImpl;
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewFactoryEdge : public wxWebViewFactory
|
||||
|
|
|
|||
|
|
@ -27,12 +27,18 @@
|
|||
|
||||
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewHandler>, wxStringToWebHandlerMap);
|
||||
|
||||
class wxWebViewWindowInfoWebKit;
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWebKit : public wxWebView
|
||||
{
|
||||
public:
|
||||
wxDECLARE_DYNAMIC_CLASS(wxWebViewWebKit);
|
||||
|
||||
wxWebViewWebKit() { Init(); }
|
||||
wxWebViewWebKit(wxWebViewWindowInfoWebKit* parentWindowInfo = nullptr)
|
||||
{
|
||||
m_parentWindowInfo = parentWindowInfo;
|
||||
Init();
|
||||
}
|
||||
wxWebViewWebKit(wxWindow *parent,
|
||||
wxWindowID winID = wxID_ANY,
|
||||
const wxString& strURL = wxASCII_STR(wxWebViewDefaultURLStr),
|
||||
|
|
@ -118,6 +124,7 @@ private:
|
|||
OSXWebViewPtr m_webView;
|
||||
wxStringToWebHandlerMap m_handlers;
|
||||
wxString m_customUserAgent;
|
||||
wxWebViewWindowInfoWebKit* m_parentWindowInfo = nullptr;
|
||||
|
||||
WX_NSObject m_navigationDelegate;
|
||||
WX_NSObject m_UIDelegate;
|
||||
|
|
|
|||
|
|
@ -323,6 +323,27 @@ private:
|
|||
wxDECLARE_ABSTRACT_CLASS(wxWebView);
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWindowInfo
|
||||
{
|
||||
public:
|
||||
virtual ~wxWebViewWindowInfo() = default;
|
||||
|
||||
virtual wxPoint GetPosition() const = 0;
|
||||
|
||||
virtual wxSize GetSize() const = 0;
|
||||
|
||||
virtual bool ShouldDisplayMenuBar() const = 0;
|
||||
|
||||
virtual bool ShouldDisplayStatusBar() const = 0;
|
||||
|
||||
virtual bool ShouldDisplayToolBar() const = 0;
|
||||
|
||||
virtual bool ShouldDisplayScrollBars() const = 0;
|
||||
|
||||
virtual wxWebView* CreateChildWebView() = 0;
|
||||
};
|
||||
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewEvent : public wxNotifyEvent
|
||||
{
|
||||
public:
|
||||
|
|
@ -343,6 +364,7 @@ public:
|
|||
|
||||
wxWebViewNavigationActionFlags GetNavigationAction() const { return m_actionFlags; }
|
||||
const wxString& GetMessageHandler() const { return m_messageHandler; }
|
||||
wxWebViewWindowInfo* GetTargetWindowInfo() const { return (wxWebViewWindowInfo*)m_clientData; }
|
||||
|
||||
virtual wxEvent* Clone() const override { return new wxWebViewEvent(*this); }
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -161,6 +161,91 @@ enum wxWebViewIE_EmulationLevel
|
|||
wxWEBVIEWIE_EMU_IE11_FORCE = 11001
|
||||
};
|
||||
|
||||
/**
|
||||
A class describing the window information for a new child window.
|
||||
This class is available via wxWebViewEvent::GetTargetWindowInfo()
|
||||
while handling @c wxEVT_WEBVIEW_NEWWINDOW.
|
||||
|
||||
If the new window should be created use CreateChildWebView() while
|
||||
processing the event. This will ensure that the new web view is
|
||||
accessible from java script within the originating wxWebView.
|
||||
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWindowInfo
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Returns the position of the new window if specified by
|
||||
a @c window.open() call.
|
||||
*/
|
||||
virtual wxPoint GetPosition() const = 0;
|
||||
|
||||
/**
|
||||
Returns the size of the new window if specified by
|
||||
a @c window.open() call.
|
||||
*/
|
||||
virtual wxSize GetSize() const = 0;
|
||||
|
||||
/**
|
||||
Returns @true if the target window is expected to display
|
||||
a menu bar as specified by a @c window.open() call.
|
||||
*/
|
||||
virtual bool ShouldDisplayMenuBar() const = 0;
|
||||
|
||||
/**
|
||||
Returns @true if the target window is expected to display
|
||||
a status bar as specified by a @c window.open() call.
|
||||
*/
|
||||
virtual bool ShouldDisplayStatusBar() const = 0;
|
||||
|
||||
/**
|
||||
Returns @true if the target window is expected to display
|
||||
a tool bar as specified by a @c window.open() call.
|
||||
*/
|
||||
virtual bool ShouldDisplayToolBar() const = 0;
|
||||
|
||||
/**
|
||||
Returns @true if the target window is expected to display
|
||||
scroll bars as specified by a @c window.open() call.
|
||||
*/
|
||||
virtual bool ShouldDisplayScrollBars() const = 0;
|
||||
|
||||
/**
|
||||
Create a new child web view for the target window.
|
||||
|
||||
This @b must be created in the event handler for @c wxEVT_WEBVIEW_NEWWINDOW
|
||||
and wxWebView::Create() @b must be called directly.
|
||||
|
||||
The requested URL will be loaded automatically in the new child web view.
|
||||
|
||||
Sample C++ code handling the event:
|
||||
@code
|
||||
// Bind handler
|
||||
m_webView->Bind(wxEVT_WEBVIEW_NEWWINDOW, [](wxWebViewEvent& evt) {
|
||||
// Get target window info
|
||||
wxWebViewWindowInfo* info = evt.GetTargetWindowInfo();
|
||||
// Create a top level window for the child web view
|
||||
wxWindow* win = new wxWindow(this, wxID_ANY, info->GetPosition(), info->GetSize());
|
||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
// Create the child web view
|
||||
wxWebView* childWebView = info->CreateChildWebView();
|
||||
// Place the child web view into the window
|
||||
childWebView->Create(win, wxID_ANY);
|
||||
sizer->Add(childWebView, 1, wxEXPAND);
|
||||
});
|
||||
@endcode
|
||||
|
||||
Sample javascript opening a new window:
|
||||
@code
|
||||
window.open("http://www.wxwidgets.org", "newWindow", "width=400,height=400");
|
||||
@endcode
|
||||
|
||||
*/
|
||||
virtual wxWebView* CreateChildWebView() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@class wxWebViewHandlerRequest
|
||||
|
||||
|
|
@ -707,7 +792,8 @@ public:
|
|||
@event{EVT_WEBVIEW_NEWWINDOW(id, func)}
|
||||
Process a @c wxEVT_WEBVIEW_NEWWINDOW event, generated when a new
|
||||
window is created. You must handle this event if you want anything to
|
||||
happen, for example to load the page in a new window or tab.
|
||||
happen, for example to load the page in a new window or tab. For usage
|
||||
details see wxWebViewWindowInfo::CreateChildWebView().
|
||||
@event{wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED(id, func)}
|
||||
Process a @c wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED event, generated when
|
||||
a window is requested to be closed.
|
||||
|
|
@ -1603,7 +1689,8 @@ public:
|
|||
@event{EVT_WEBVIEW_NEWWINDOW(id, func)}
|
||||
Process a @c wxEVT_WEBVIEW_NEWWINDOW event, generated when a new
|
||||
window is created. You must handle this event if you want anything to
|
||||
happen, for example to load the page in a new window or tab.
|
||||
happen, for example to load the page in a new window or tab. For usage
|
||||
details see wxWebViewWindowInfo::CreateChildWebView().
|
||||
@event{wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED(id, func)}
|
||||
Process a @c wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED event, generated when
|
||||
a window is requested to be closed.
|
||||
|
|
@ -1669,6 +1756,17 @@ public:
|
|||
*/
|
||||
const wxString& GetMessageHandler() const;
|
||||
|
||||
/**
|
||||
Get information about the target window. Only valid for events of type
|
||||
@c wxEVT_WEBVIEW_NEWWINDOW
|
||||
|
||||
@note This is only available with the macOS and the Edge backend.
|
||||
|
||||
@see wxWebViewWindowInfo
|
||||
@since 3.3.0
|
||||
*/
|
||||
wxWebViewWindowInfo* GetTargetWindowInfo() const;
|
||||
|
||||
/**
|
||||
Returns true the script execution failed. Only valid for events of type
|
||||
@c wxEVT_WEBVIEW_SCRIPT_RESULT
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ private:
|
|||
class WebFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
WebFrame(const wxString& url);
|
||||
WebFrame(const wxString& url, bool isMain = true, wxWebViewWindowInfo* newWindowInfo = nullptr);
|
||||
virtual ~WebFrame();
|
||||
|
||||
void UpdateState();
|
||||
|
|
@ -177,6 +177,7 @@ public:
|
|||
private:
|
||||
wxTextCtrl* m_url;
|
||||
wxWebView* m_browser;
|
||||
bool m_isMainFrame;
|
||||
|
||||
wxToolBar* m_toolbar;
|
||||
wxToolBarToolBase* m_toolbar_back;
|
||||
|
|
@ -333,9 +334,11 @@ bool WebApp::OnInit()
|
|||
return true;
|
||||
}
|
||||
|
||||
WebFrame::WebFrame(const wxString& url) :
|
||||
WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowInfo* newWindowInfo) :
|
||||
wxFrame(nullptr, wxID_ANY, "wxWebView Sample")
|
||||
{
|
||||
m_isMainFrame = isMain;
|
||||
|
||||
// set the frame icon
|
||||
SetIcon(wxICON(sample));
|
||||
SetTitle("wxWebView Sample");
|
||||
|
|
@ -350,7 +353,7 @@ WebFrame::WebFrame(const wxString& url) :
|
|||
m_toolbar_forward = m_toolbar->AddTool(wxID_ANY, _("Forward"), wxArtProvider::GetBitmapBundle(wxART_GO_FORWARD, wxART_TOOLBAR));
|
||||
m_toolbar_stop = m_toolbar->AddTool(wxID_ANY, _("Stop"), wxArtProvider::GetBitmapBundle(wxART_STOP, wxART_TOOLBAR));
|
||||
m_toolbar_reload = m_toolbar->AddTool(wxID_ANY, _("Reload"), wxArtProvider::GetBitmapBundle(wxART_REFRESH, wxART_TOOLBAR));
|
||||
m_url = new wxTextCtrl(m_toolbar, wxID_ANY, "", wxDefaultPosition, FromDIP(wxSize(400, -1)), wxTE_PROCESS_ENTER );
|
||||
m_url = new wxTextCtrl(m_toolbar, wxID_ANY, "", wxDefaultPosition, FromDIP(wxSize(400, -1)), wxTE_PROCESS_ENTER);
|
||||
m_toolbar->AddControl(m_url, _("URL"));
|
||||
m_toolbar_tools = m_toolbar->AddTool(wxID_ANY, _("Menu"), wxArtProvider::GetBitmapBundle(wxART_WX_LOGO, wxART_TOOLBAR));
|
||||
|
||||
|
|
@ -401,7 +404,8 @@ WebFrame::WebFrame(const wxString& url) :
|
|||
topsizer->Add(m_info, wxSizerFlags().Expand());
|
||||
|
||||
// Create a log window
|
||||
new wxLogWindow(this, _("Logging"), true, false);
|
||||
if (m_isMainFrame)
|
||||
new wxLogWindow(this, _("Logging"), true, false);
|
||||
|
||||
#if wxUSE_WEBVIEW_EDGE
|
||||
// Check if a fixed version of edge is present in
|
||||
|
|
@ -416,30 +420,50 @@ WebFrame::WebFrame(const wxString& url) :
|
|||
}
|
||||
#endif
|
||||
// Create the webview
|
||||
m_browser = wxWebView::New();
|
||||
m_browser = (newWindowInfo) ? newWindowInfo->CreateChildWebView() : wxWebView::New();
|
||||
#ifdef __WXMAC__
|
||||
// With WKWebView handlers need to be registered before creation
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new AdvancedWebViewHandler()));
|
||||
if (m_isMainFrame)
|
||||
{
|
||||
// With WKWebView handlers need to be registered before creation
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new AdvancedWebViewHandler()));
|
||||
}
|
||||
#endif
|
||||
m_browser->Create(this, wxID_ANY, url, wxDefaultPosition, wxDefaultSize);
|
||||
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
|
||||
|
||||
// Log backend information
|
||||
wxLogMessage("Backend: %s Version: %s", m_browser->GetClassInfo()->GetClassName(),
|
||||
wxWebView::GetBackendVersionInfo().ToString());
|
||||
wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
|
||||
if (newWindowInfo)
|
||||
{
|
||||
if (newWindowInfo->GetSize().IsFullySpecified())
|
||||
SetSize(FromDIP(newWindowInfo->GetSize()));
|
||||
if (newWindowInfo->GetPosition().IsFullySpecified())
|
||||
Move(FromDIP(newWindowInfo->GetPosition()));
|
||||
if (!newWindowInfo->ShouldDisplayToolBar())
|
||||
m_toolbar->Hide();
|
||||
if (!newWindowInfo->ShouldDisplayMenuBar())
|
||||
SetMenuBar(nullptr);
|
||||
}
|
||||
|
||||
if (m_isMainFrame)
|
||||
{
|
||||
// Log backend information
|
||||
wxLogMessage("Backend: %s Version: %s", m_browser->GetClassInfo()->GetClassName(),
|
||||
wxWebView::GetBackendVersionInfo().ToString());
|
||||
wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
|
||||
|
||||
#ifndef __WXMAC__
|
||||
//We register the wxfs:// protocol for testing purposes
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
|
||||
//And the memory: file system
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new AdvancedWebViewHandler()));
|
||||
//We register the wxfs:// protocol for testing purposes
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
|
||||
//And the memory: file system
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
|
||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new AdvancedWebViewHandler()));
|
||||
#endif
|
||||
if (!m_browser->AddScriptMessageHandler("wx"))
|
||||
wxLogError("Could not add script message handler");
|
||||
if (!m_browser->AddScriptMessageHandler("wx"))
|
||||
wxLogError("Could not add script message handler");
|
||||
}
|
||||
else
|
||||
wxLogMessage("Created new window");
|
||||
|
||||
SetSizer(topsizer);
|
||||
|
||||
|
|
@ -949,11 +973,20 @@ void WebFrame::OnNewWindow(wxWebViewEvent& evt)
|
|||
}
|
||||
|
||||
wxLogMessage("%s", "New window; url='" + evt.GetURL() + "'" + flag);
|
||||
wxWebViewWindowInfo* info = evt.GetTargetWindowInfo();
|
||||
if (info)
|
||||
{
|
||||
wxLogMessage(" New window info: Position=%d,%d Size=%d,%d",
|
||||
info->GetPosition().x, info->GetPosition().y,
|
||||
info->GetSize().GetWidth(), info->GetSize().GetHeight());
|
||||
}
|
||||
|
||||
//If we handle new window events then just load them in this window as we
|
||||
//are a single window browser
|
||||
if(m_tools_handle_new_window->IsChecked())
|
||||
m_browser->LoadURL(evt.GetURL());
|
||||
//If we handle new window events then create a new frame
|
||||
if (m_tools_handle_new_window->IsChecked())
|
||||
{
|
||||
WebFrame* newFrame = new WebFrame(evt.GetURL(), false, info);
|
||||
newFrame->Show();
|
||||
}
|
||||
|
||||
UpdateState();
|
||||
}
|
||||
|
|
@ -983,9 +1016,11 @@ void WebFrame::OnScriptResult(wxWebViewEvent& evt)
|
|||
wxLogMessage("Async script result received; value = %s", evt.GetString());
|
||||
}
|
||||
|
||||
void WebFrame::OnWindowCloseRequested(wxWebViewEvent& evt)
|
||||
void WebFrame::OnWindowCloseRequested(wxWebViewEvent& WXUNUSED(evt))
|
||||
{
|
||||
wxLogMessage("Window close requested");
|
||||
if (!m_isMainFrame)
|
||||
Close();
|
||||
}
|
||||
|
||||
void WebFrame::OnSetPage(wxCommandEvent& WXUNUSED(evt))
|
||||
|
|
|
|||
|
|
@ -252,6 +252,114 @@ public:
|
|||
wxCOMPtr<ICoreWebView2WebResourceRequestedEventArgs> m_args;
|
||||
};
|
||||
|
||||
// wxWebViewNewWindowInfoEdge
|
||||
|
||||
class wxWebViewNewWindowInfoEdge : public wxWebViewWindowInfo
|
||||
{
|
||||
public:
|
||||
wxWebViewNewWindowInfoEdge(wxWebViewEdgeImpl* impl, ICoreWebView2NewWindowRequestedEventArgs* args):
|
||||
m_impl(impl),
|
||||
m_args(args)
|
||||
{
|
||||
m_args->get_WindowFeatures(&m_windowFeatures);
|
||||
}
|
||||
|
||||
virtual wxPoint GetPosition() const override
|
||||
{
|
||||
wxPoint result(-1, -1);
|
||||
BOOL hasPosition;
|
||||
if (SUCCEEDED(m_windowFeatures->get_HasPosition(&hasPosition)) && hasPosition)
|
||||
{
|
||||
UINT32 x, y;
|
||||
if (SUCCEEDED(m_windowFeatures->get_Left(&x)) &&
|
||||
SUCCEEDED(m_windowFeatures->get_Top(&y)))
|
||||
result = wxPoint(x, y);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual wxSize GetSize() const override
|
||||
{
|
||||
wxSize result(-1, -1);
|
||||
BOOL hasSize;
|
||||
if (SUCCEEDED(m_windowFeatures->get_HasSize(&hasSize)) && hasSize)
|
||||
{
|
||||
UINT32 width, height;
|
||||
if (SUCCEEDED(m_windowFeatures->get_Width(&width)) &&
|
||||
SUCCEEDED(m_windowFeatures->get_Height(&height)))
|
||||
result = wxSize(width, height);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayMenuBar() const override
|
||||
{
|
||||
BOOL result;
|
||||
if (SUCCEEDED(m_windowFeatures->get_ShouldDisplayMenuBar(&result)))
|
||||
return result;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayStatusBar() const override
|
||||
{
|
||||
BOOL result;
|
||||
if (SUCCEEDED(m_windowFeatures->get_ShouldDisplayStatus(&result)))
|
||||
return result;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
virtual bool ShouldDisplayToolBar() const override
|
||||
{
|
||||
BOOL result;
|
||||
if (SUCCEEDED(m_windowFeatures->get_ShouldDisplayToolbar(&result)))
|
||||
return result;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayScrollBars() const override
|
||||
{
|
||||
BOOL result;
|
||||
if (SUCCEEDED(m_windowFeatures->get_ShouldDisplayScrollBars(&result)))
|
||||
return result;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual wxWebView* CreateChildWebView() override
|
||||
{
|
||||
return m_impl->CreateChildWebView(
|
||||
std::make_shared<wxWebViewEdgeParentWindowInfo>(m_impl, m_args));
|
||||
}
|
||||
|
||||
private:
|
||||
wxWebViewEdgeImpl* m_impl;
|
||||
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_args;
|
||||
wxCOMPtr<ICoreWebView2WindowFeatures> m_windowFeatures;
|
||||
};
|
||||
|
||||
class wxWebViewEdgeParentWindowInfo
|
||||
{
|
||||
public:
|
||||
wxWebViewEdgeParentWindowInfo(wxWebViewEdgeImpl* impl,
|
||||
ICoreWebView2NewWindowRequestedEventArgs* args):
|
||||
m_impl(impl),
|
||||
m_args(args)
|
||||
{
|
||||
HRESULT hr = m_args->GetDeferral(&m_deferral);
|
||||
if (FAILED(hr))
|
||||
wxLogApiError("GetDeferral", hr);
|
||||
}
|
||||
|
||||
virtual ~wxWebViewEdgeParentWindowInfo() = default;
|
||||
|
||||
wxWebViewEdgeImpl* m_impl;
|
||||
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_args;
|
||||
wxCOMPtr<ICoreWebView2Deferral> m_deferral;
|
||||
};
|
||||
|
||||
|
||||
#define wxWEBVIEW_EDGE_EVENT_HANDLER_METHOD \
|
||||
m_inEventCallback = true; \
|
||||
wxON_BLOCK_EXIT_SET(m_inEventCallback, false);
|
||||
|
|
@ -299,19 +407,34 @@ bool wxWebViewEdgeImpl::Create()
|
|||
|
||||
wxString userDataPath = wxStandardPaths::Get().GetUserLocalDataDir();
|
||||
|
||||
HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions(
|
||||
ms_browserExecutableDir.wc_str(),
|
||||
userDataPath.wc_str(),
|
||||
m_webViewEnvironmentOptions,
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
|
||||
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get());
|
||||
if (FAILED(hr))
|
||||
if (m_parentWindowInfo)
|
||||
{
|
||||
wxLogApiError("CreateWebView2EnvironmentWithOptions", hr);
|
||||
return false;
|
||||
OnEnvironmentCreated(S_OK, m_parentWindowInfo->m_impl->m_webViewEnvironment);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
{
|
||||
HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions(
|
||||
ms_browserExecutableDir.wc_str(),
|
||||
userDataPath.wc_str(),
|
||||
m_webViewEnvironmentOptions,
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
|
||||
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wxLogApiError("CreateWebView2EnvironmentWithOptions", hr);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
wxWebViewEdge* wxWebViewEdgeImpl::CreateChildWebView(std::shared_ptr<wxWebViewEdgeParentWindowInfo> parentWindowInfo)
|
||||
{
|
||||
wxWebViewEdge* childWebView = new wxWebViewEdge();
|
||||
childWebView->m_impl->m_parentWindowInfo = parentWindowInfo;
|
||||
return childWebView;
|
||||
}
|
||||
|
||||
HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated(
|
||||
|
|
@ -494,6 +617,7 @@ HRESULT wxWebViewEdgeImpl::OnNavigationCompleted(ICoreWebView2* WXUNUSED(sender)
|
|||
|
||||
HRESULT wxWebViewEdgeImpl::OnNewWindowRequested(ICoreWebView2* WXUNUSED(sender), ICoreWebView2NewWindowRequestedEventArgs* args)
|
||||
{
|
||||
wxWEBVIEW_EDGE_EVENT_HANDLER_METHOD
|
||||
wxCoTaskMemPtr<wchar_t> uri;
|
||||
wxString evtURL;
|
||||
if (SUCCEEDED(args->get_Uri(&uri)))
|
||||
|
|
@ -504,8 +628,10 @@ HRESULT wxWebViewEdgeImpl::OnNewWindowRequested(ICoreWebView2* WXUNUSED(sender),
|
|||
if (SUCCEEDED(args->get_IsUserInitiated(&isUserInitiated)) && isUserInitiated)
|
||||
navFlags = wxWEBVIEW_NAV_ACTION_USER;
|
||||
|
||||
wxWebViewEvent evt(wxEVT_WEBVIEW_NEWWINDOW, m_ctrl->GetId(), evtURL, wxString(), navFlags);
|
||||
m_ctrl->GetEventHandler()->AddPendingEvent(evt);
|
||||
wxWebViewNewWindowInfoEdge windowInfo(this, args);
|
||||
wxWebViewEvent evt(wxEVT_WEBVIEW_NEWWINDOW, m_ctrl->GetId(), evtURL, wxString(), navFlags, "");
|
||||
evt.SetClientData(&windowInfo);
|
||||
m_ctrl->HandleWindowEvent(evt);
|
||||
args->put_Handled(true);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -734,6 +860,17 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
|
|||
m_pendingUserScripts.clear();
|
||||
}
|
||||
|
||||
if (m_parentWindowInfo)
|
||||
{
|
||||
if (FAILED(m_parentWindowInfo->m_args->put_NewWindow(baseWebView)))
|
||||
wxLogApiError("WebView2::WebViewCreated (put_NewWindow)", hr);
|
||||
if (FAILED(m_parentWindowInfo->m_deferral->Complete()))
|
||||
wxLogApiError("WebView2::WebViewCreated (Complete)", hr);
|
||||
m_parentWindowInfo.reset();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!m_pendingURL.empty())
|
||||
{
|
||||
m_ctrl->LoadURL(m_pendingURL);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,86 @@ wxVersionInfo wxWebViewFactoryWebKit::GetVersionInfo()
|
|||
return wxVersionInfo("WKWebView", verMaj, verMin, verMicro);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxWebViewWindowInfoWebKit
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class wxWebViewWindowInfoWebKit: public wxWebViewWindowInfo
|
||||
{
|
||||
public:
|
||||
wxWebViewWindowInfoWebKit(WKWebViewConfiguration* configuration,
|
||||
WKNavigationAction* navigationAction,
|
||||
WKWindowFeatures* windowFeatures):
|
||||
m_configuration(configuration),
|
||||
m_navigationAction(navigationAction),
|
||||
m_windowFeatures(windowFeatures)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual wxPoint GetPosition() const override
|
||||
{
|
||||
wxPoint pos(-1, -1);
|
||||
if (m_windowFeatures.y)
|
||||
pos.y = m_windowFeatures.y.intValue;
|
||||
if (m_windowFeatures.x)
|
||||
pos.x = m_windowFeatures.x.intValue;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
virtual wxSize GetSize() const override
|
||||
{
|
||||
wxSize size(-1, -1);
|
||||
if (m_windowFeatures.height)
|
||||
size.y = m_windowFeatures.height.intValue;
|
||||
if (m_windowFeatures.width)
|
||||
size.x = m_windowFeatures.width.intValue;
|
||||
return size;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayMenuBar() const override
|
||||
{
|
||||
if (m_windowFeatures.menuBarVisibility)
|
||||
return m_windowFeatures.menuBarVisibility.boolValue;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayStatusBar() const override
|
||||
{
|
||||
if (m_windowFeatures.statusBarVisibility)
|
||||
return m_windowFeatures.statusBarVisibility.boolValue;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayToolBar() const override
|
||||
{
|
||||
if (m_windowFeatures.toolbarsVisibility)
|
||||
return m_windowFeatures.toolbarsVisibility.boolValue;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayScrollBars() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual wxWebView* CreateChildWebView() override
|
||||
{
|
||||
m_childWebView = new wxWebViewWebKit(this);
|
||||
return m_childWebView;
|
||||
}
|
||||
|
||||
wxWebView* m_childWebView = nullptr;
|
||||
WKWebViewConfiguration* m_configuration;
|
||||
WKNavigationAction* m_navigationAction;
|
||||
WKWindowFeatures* m_windowFeatures;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// creation/destruction
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -130,9 +210,10 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
wxControl::Create(parent, winID, pos, size, style, wxDefaultValidator, name);
|
||||
|
||||
NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
|
||||
WKWebViewConfiguration* webViewConfig = (WKWebViewConfiguration*) m_webViewConfiguration;
|
||||
WKWebViewConfiguration* webViewConfig = (m_parentWindowInfo) ?
|
||||
m_parentWindowInfo->m_configuration : (WKWebViewConfiguration*) m_webViewConfiguration;
|
||||
|
||||
if (!m_handlers.empty())
|
||||
if (!m_handlers.empty() && !m_parentWindowInfo)
|
||||
{
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
||||
if ( WX_IS_MACOS_AVAILABLE(10, 13) )
|
||||
|
|
@ -154,9 +235,12 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
|
||||
MacPostControlCreate(pos, size);
|
||||
|
||||
// WKWebView configuration is only used during creation
|
||||
[m_webViewConfiguration release];
|
||||
m_webViewConfiguration = nil;
|
||||
if (!m_parentWindowInfo)
|
||||
{
|
||||
// WKWebView configuration is only used during creation
|
||||
[m_webViewConfiguration release];
|
||||
m_webViewConfiguration = nil;
|
||||
}
|
||||
|
||||
if (!m_customUserAgent.empty())
|
||||
SetUserAgent(m_customUserAgent);
|
||||
|
|
@ -178,45 +262,51 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
|
||||
[m_webView setUIDelegate:uiDelegate];
|
||||
|
||||
// Implement javascript fullscreen interface with user script and message handler
|
||||
AddUserScript("\
|
||||
document.__wxToggleFullscreen = function (elem) { \
|
||||
if (!document.__wxStylesAdded) { \
|
||||
function createClass(name,rules) { \
|
||||
var style= document.createElement('style'); style.type = 'text/css'; \
|
||||
document.getElementsByTagName('head')[0].appendChild(style); \
|
||||
style.sheet.addRule(name, rules); \
|
||||
if (!m_parentWindowInfo)
|
||||
{
|
||||
// Implement javascript fullscreen interface with user script and message handler
|
||||
AddUserScript("\
|
||||
document.__wxToggleFullscreen = function (elem) { \
|
||||
if (!document.__wxStylesAdded) { \
|
||||
function createClass(name,rules) { \
|
||||
var style= document.createElement('style'); style.type = 'text/css'; \
|
||||
document.getElementsByTagName('head')[0].appendChild(style); \
|
||||
style.sheet.addRule(name, rules); \
|
||||
} \
|
||||
createClass(\"body.wxfullscreen\", \"padding: 0; margin: 0; height: 100%;\"); \
|
||||
createClass(\".wxfullscreen\", \"position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0;\"); \
|
||||
createClass(\".wxfullscreenelem\", \"width: 100% !important; height: 100% !important; padding-top: 0 !important;\"); \
|
||||
document.__wxStylesAdded = true; \
|
||||
} \
|
||||
createClass(\"body.wxfullscreen\", \"padding: 0; margin: 0; height: 100%;\"); \
|
||||
createClass(\".wxfullscreen\", \"position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0;\"); \
|
||||
createClass(\".wxfullscreenelem\", \"width: 100% !important; height: 100% !important; padding-top: 0 !important;\"); \
|
||||
document.__wxStylesAdded = true; \
|
||||
} \
|
||||
if (elem) { \
|
||||
elem.classList.add(\"wxfullscreen\"); \
|
||||
elem.classList.add(\"wxfullscreenelem\"); \
|
||||
document.body.classList.add(\"wxfullscreen\"); \
|
||||
} else if (document.webkitFullscreenElement) { \
|
||||
document.webkitFullscreenElement.classList.remove(\"wxfullscreen\"); \
|
||||
document.webkitFullscreenElement.classList.remove(\"wxfullscreenelem\"); \
|
||||
document.body.classList.remove(\"wxfullscreen\"); \
|
||||
} \
|
||||
document.webkitFullscreenElement = elem; \
|
||||
window.webkit.messageHandlers.__wxfullscreen.postMessage((elem) ? 1: 0); \
|
||||
document.dispatchEvent(new Event('webkitfullscreenchange')); \
|
||||
if (document.onwebkitfullscreenchange) document.onwebkitfullscreenchange(); \
|
||||
}; \
|
||||
Element.prototype.webkitRequestFullscreen = function() {document.__wxToggleFullscreen(this);}; \
|
||||
document.webkitExitFullscreen = function() {document.__wxToggleFullscreen(undefined);}; \
|
||||
document.onwebkitfullscreenchange = null; \
|
||||
document.webkitFullscreenEnabled = true; \
|
||||
");
|
||||
[m_webView.configuration.userContentController addScriptMessageHandler:
|
||||
[[WebViewScriptMessageHandler alloc] initWithWxWindow:this] name:@"__wxfullscreen"];
|
||||
if (elem) { \
|
||||
elem.classList.add(\"wxfullscreen\"); \
|
||||
elem.classList.add(\"wxfullscreenelem\"); \
|
||||
document.body.classList.add(\"wxfullscreen\"); \
|
||||
} else if (document.webkitFullscreenElement) { \
|
||||
document.webkitFullscreenElement.classList.remove(\"wxfullscreen\"); \
|
||||
document.webkitFullscreenElement.classList.remove(\"wxfullscreenelem\"); \
|
||||
document.body.classList.remove(\"wxfullscreen\"); \
|
||||
} \
|
||||
document.webkitFullscreenElement = elem; \
|
||||
window.webkit.messageHandlers.__wxfullscreen.postMessage((elem) ? 1: 0); \
|
||||
document.dispatchEvent(new Event('webkitfullscreenchange')); \
|
||||
if (document.onwebkitfullscreenchange) document.onwebkitfullscreenchange(); \
|
||||
}; \
|
||||
Element.prototype.webkitRequestFullscreen = function() {document.__wxToggleFullscreen(this);}; \
|
||||
document.webkitExitFullscreen = function() {document.__wxToggleFullscreen(undefined);}; \
|
||||
document.onwebkitfullscreenchange = null; \
|
||||
document.webkitFullscreenEnabled = true; \
|
||||
");
|
||||
[m_webView.configuration.userContentController addScriptMessageHandler:
|
||||
[[WebViewScriptMessageHandler alloc] initWithWxWindow:this] name:@"__wxfullscreen"];
|
||||
}
|
||||
|
||||
m_UIDelegate = uiDelegate;
|
||||
|
||||
LoadURL(strURL);
|
||||
if (m_parentWindowInfo)
|
||||
[m_webView loadRequest:m_parentWindowInfo->m_navigationAction.request];
|
||||
else
|
||||
LoadURL(strURL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1013,15 +1103,21 @@ WX_API_AVAILABLE_MACOS(10, 13)
|
|||
wxWEBVIEW_NAV_ACTION_USER :
|
||||
wxWEBVIEW_NAV_ACTION_OTHER;
|
||||
|
||||
wxWebViewWindowInfoWebKit windowInfo(configuration, navigationAction, windowFeatures);
|
||||
|
||||
wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW,
|
||||
webKitWindow->GetId(),
|
||||
wxCFStringRef::AsString( navigationAction.request.URL.absoluteString ),
|
||||
"", navFlags);
|
||||
event.SetClientData(&windowInfo);
|
||||
|
||||
if (webKitWindow && webKitWindow->GetEventHandler())
|
||||
webKitWindow->GetEventHandler()->ProcessEvent(event);
|
||||
|
||||
return nil;
|
||||
if (windowInfo.m_childWebView)
|
||||
return (WKWebView*) windowInfo.m_childWebView->GetNativeBackend();
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)webViewDidClose:(WKWebView *)webView
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue