Add wxWebViewWindowFeatures and event
This replaces the previously implemented wxWebViewWindowInfo. It explicitly breaks the previous API to enable WebKitGTK integration and to make the usage in application code less error prone. A new event wxEVT_WEBVIEW_NEWWINDOW_FEATURES is added to allow access to the window features and the child web view.
This commit is contained in:
parent
8d0685ee08
commit
e15a1ac18e
10 changed files with 323 additions and 160 deletions
|
|
@ -35,6 +35,7 @@ public:
|
|||
wxWebViewWebKit();
|
||||
|
||||
#if wxUSE_WEBVIEW_WEBKIT2
|
||||
wxWebViewWebKit(WebKitWebView* parentWebView, wxWebViewWebKit* parentWebViewCtrl);
|
||||
wxWebViewWebKit(const wxWebViewConfiguration& config);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ __CRT_UUID_DECL(ICoreWebView2WindowCloseRequestedEventHandler, 0x5c19e9e0,0x092f
|
|||
|
||||
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewHandler>, wxStringToWebHandlerMap);
|
||||
|
||||
class wxWebViewEdgeParentWindowInfo;
|
||||
class wxWebViewWindowFeaturesEdge;
|
||||
|
||||
class wxWebViewEdgeImpl
|
||||
{
|
||||
|
|
@ -57,15 +57,15 @@ public:
|
|||
|
||||
bool Create();
|
||||
|
||||
wxWebViewEdge* CreateChildWebView(std::shared_ptr<wxWebViewEdgeParentWindowInfo> parentWindowInfo);
|
||||
|
||||
wxWebViewEdge* m_ctrl;
|
||||
wxWebViewConfiguration m_config;
|
||||
|
||||
wxCOMPtr<ICoreWebView2Environment> m_webViewEnvironment;
|
||||
wxCOMPtr<ICoreWebView2_2> m_webView;
|
||||
wxCOMPtr<ICoreWebView2Controller> m_webViewController;
|
||||
std::shared_ptr<wxWebViewEdgeParentWindowInfo> m_parentWindowInfo;
|
||||
|
||||
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_newWindowArgs;
|
||||
wxCOMPtr<ICoreWebView2Deferral> m_newWindowDeferral;
|
||||
|
||||
bool m_initialized;
|
||||
bool m_isBusy;
|
||||
|
|
|
|||
|
|
@ -27,13 +27,12 @@
|
|||
|
||||
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewHandler>, wxStringToWebHandlerMap);
|
||||
|
||||
class wxWebViewWindowInfoWebKit;
|
||||
class wxWebViewConfigurationImplWebKit;
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWebKit : public wxWebView
|
||||
{
|
||||
public:
|
||||
explicit wxWebViewWebKit(const wxWebViewConfiguration& config, wxWebViewWindowInfoWebKit* parentWindowInfo = nullptr);
|
||||
explicit wxWebViewWebKit(const wxWebViewConfiguration& config, WX_NSObject request = nullptr);
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID winID = wxID_ANY,
|
||||
|
|
@ -109,7 +108,7 @@ private:
|
|||
OSXWebViewPtr m_webView;
|
||||
wxStringToWebHandlerMap m_handlers;
|
||||
wxString m_customUserAgent;
|
||||
wxWebViewWindowInfoWebKit* m_parentWindowInfo = nullptr;
|
||||
WX_NSObject m_request;
|
||||
|
||||
WX_NSObject m_navigationDelegate;
|
||||
WX_NSObject m_UIDelegate;
|
||||
|
|
|
|||
|
|
@ -344,10 +344,14 @@ private:
|
|||
wxDECLARE_ABSTRACT_CLASS(wxWebView);
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWindowInfo
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWindowFeatures
|
||||
{
|
||||
public:
|
||||
virtual ~wxWebViewWindowInfo() = default;
|
||||
wxWebViewWindowFeatures(wxWebView* childWebView);
|
||||
|
||||
virtual ~wxWebViewWindowFeatures();
|
||||
|
||||
wxWebView* GetChildWebView() const;
|
||||
|
||||
virtual wxPoint GetPosition() const = 0;
|
||||
|
||||
|
|
@ -361,10 +365,11 @@ public:
|
|||
|
||||
virtual bool ShouldDisplayScrollBars() const = 0;
|
||||
|
||||
virtual wxWebView* CreateChildWebView() = 0;
|
||||
protected:
|
||||
mutable bool m_childWebViewWasUsed;
|
||||
std::unique_ptr<wxWebView> m_childWebView;
|
||||
};
|
||||
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewEvent : public wxNotifyEvent
|
||||
{
|
||||
public:
|
||||
|
|
@ -385,7 +390,7 @@ public:
|
|||
|
||||
wxWebViewNavigationActionFlags GetNavigationAction() const { return m_actionFlags; }
|
||||
const wxString& GetMessageHandler() const { return m_messageHandler; }
|
||||
wxWebViewWindowInfo* GetTargetWindowInfo() const { return (wxWebViewWindowInfo*)m_clientData; }
|
||||
wxWebViewWindowFeatures* GetTargetWindowFeatures() const { return (wxWebViewWindowFeatures*)m_clientData; }
|
||||
|
||||
virtual wxEvent* Clone() const override { return new wxWebViewEvent(*this); }
|
||||
private:
|
||||
|
|
@ -402,6 +407,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NAVIGATED, wxWebVie
|
|||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_LOADED, wxWebViewEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_ERROR, wxWebViewEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NEWWINDOW_FEATURES, wxWebViewEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED, wxWebViewEvent);
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
||||
|
|
|
|||
|
|
@ -163,19 +163,63 @@ enum wxWebViewIE_EmulationLevel
|
|||
|
||||
/**
|
||||
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 JavaScript within the originating wxWebView.
|
||||
An object of this class can be obtained using wxWebViewEvent::GetTargetWindowFeatures()
|
||||
while handling @c wxEVT_WEBVIEW_NEWWINDOW_FEATURES.
|
||||
|
||||
If a @c wxEVT_WEBVIEW_NEWWINDOW is not vetoed, a @c wxEVT_WEBVIEW_NEWWINDOW_FEATURES
|
||||
event will be sent to the application. The application can then create a new
|
||||
window and call wxWebViewEvent::GetTargetWindowInfo() to get this class providing
|
||||
information about the new window. A new child web view will be available
|
||||
via GetChildWebView(). The application can then place the child web view into
|
||||
the new window by calling wxWebView::Create() on the child web view.
|
||||
|
||||
Sample JavaScript opening a new window:
|
||||
@code
|
||||
window.open("http://www.wxwidgets.org", "newWindow", "width=400,height=400");
|
||||
@endcode
|
||||
|
||||
Sample C++ code handling a new window request:
|
||||
@code
|
||||
// Bind new window handler
|
||||
m_webView->Bind(wxEVT_WEBVIEW_NEWWINDOW, [](wxWebViewEvent& evt) {
|
||||
if (evt.GetURL() == "http://badwebsite.com")
|
||||
evt.Veto(); // Disallow new window for badwebsite.com
|
||||
else
|
||||
evt.Skip(); // Allow new window for all other websites
|
||||
});
|
||||
|
||||
// Bind new window features handler
|
||||
m_webView->Bind(wxEVT_WEBVIEW_NEWWINDOW_FEATURES, [](wxWebViewEvent& evt) {
|
||||
// Get target window features
|
||||
wxWebViewWindowFeatures* features = evt.GetTargetWindowFeatures();
|
||||
// Create a top level window for the child web view
|
||||
wxWindow* win = new wxWindow(this, wxID_ANY, features->GetPosition(), features->GetSize());
|
||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
win->SetSizer(sizer);
|
||||
// Get the child web view
|
||||
wxWebView* childWebView = features->GetChildWebView();
|
||||
// Place the child web view into the window
|
||||
childWebView->Create(win, wxID_ANY);
|
||||
sizer->Add(childWebView, 1, wxEXPAND);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWindowInfo
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewWindowFeatures
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Get the child web view for the target window.
|
||||
|
||||
This is available in the event handler for @c wxEVT_WEBVIEW_NEWWINDOW_FEATURES
|
||||
and wxWebView::Create() @b must be called on the child web view directly.
|
||||
|
||||
The requested URL will be loaded automatically in the child web view.
|
||||
*/
|
||||
wxWebView* GetChildWebView();
|
||||
|
||||
/**
|
||||
Returns the position of the new window if specified by
|
||||
a @c window.open() call.
|
||||
|
|
@ -211,39 +255,6 @@ public:
|
|||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -912,7 +923,12 @@ public:
|
|||
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. For usage
|
||||
details see wxWebViewWindowInfo::CreateChildWebView().
|
||||
details see wxWebViewWindowFeatures.
|
||||
@event{EVT_WEBVIEW_NEWWINDOW_FEATURES(id, func)}
|
||||
Process a @c wxEVT_WEBVIEW_NEWWINDOW_FEATURES event, generated when
|
||||
window features are available for the new window. For usage
|
||||
details see wxWebViewWindowFeatures.
|
||||
only available in wxWidgets 3.3.0 or later.
|
||||
@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.
|
||||
|
|
@ -1784,7 +1800,12 @@ public:
|
|||
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. For usage
|
||||
details see wxWebViewWindowInfo::CreateChildWebView().
|
||||
details see wxWebViewWindowFeatures.
|
||||
@event{EVT_WEBVIEW_NEWWINDOW_FEATURES(id, func)}
|
||||
Process a @c wxEVT_WEBVIEW_NEWWINDOW_FEATURES event, generated when
|
||||
window features are available for the new window. For usage
|
||||
details see wxWebViewWindowFeatures.
|
||||
only available in wxWidgets 3.3.0 or later.
|
||||
@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.
|
||||
|
|
@ -1852,14 +1873,14 @@ public:
|
|||
|
||||
/**
|
||||
Get information about the target window. Only valid for events of type
|
||||
@c wxEVT_WEBVIEW_NEWWINDOW
|
||||
@c wxEVT_WEBVIEW_NEWWINDOW_FEATURES
|
||||
|
||||
@note This is only available with the macOS and the Edge backend.
|
||||
@note This function is not implemented and always returns @NULL when using WebKit1 or Internet Explorer backend.
|
||||
|
||||
@see wxWebViewWindowInfo
|
||||
@see wxWebViewWindowFeatures
|
||||
@since 3.3.0
|
||||
*/
|
||||
wxWebViewWindowInfo* GetTargetWindowInfo() const;
|
||||
wxWebViewWindowFeatures* GetTargetWindowFeatures() const;
|
||||
|
||||
/**
|
||||
Returns true the script execution failed. Only valid for events of type
|
||||
|
|
@ -1886,6 +1907,7 @@ wxEventType wxEVT_WEBVIEW_NAVIGATED;
|
|||
wxEventType wxEVT_WEBVIEW_LOADED;
|
||||
wxEventType wxEVT_WEBVIEW_ERROR;
|
||||
wxEventType wxEVT_WEBVIEW_NEWWINDOW;
|
||||
wxEventType wxEVT_WEBVIEW_NEWWINDOW_FEATURES;
|
||||
wxEventType wxEVT_WEBVIEW_TITLE_CHANGED;
|
||||
wxEventType wxEVT_WEBVIEW_FULLSCREEN_CHANGED;
|
||||
wxEventType wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ private:
|
|||
class WebFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
WebFrame(const wxString& url, bool isMain = true, wxWebViewWindowInfo* newWindowInfo = nullptr);
|
||||
WebFrame(const wxString& url, bool isMain = true, wxWebViewWindowFeatures* windowFeatures = nullptr);
|
||||
virtual ~WebFrame();
|
||||
|
||||
void UpdateState();
|
||||
|
|
@ -114,6 +114,7 @@ public:
|
|||
void OnNavigationComplete(wxWebViewEvent& evt);
|
||||
void OnDocumentLoaded(wxWebViewEvent& evt);
|
||||
void OnNewWindow(wxWebViewEvent& evt);
|
||||
void OnNewWindowFeatures(wxWebViewEvent& evt);
|
||||
void OnTitleChanged(wxWebViewEvent& evt);
|
||||
void OnFullScreenChanged(wxWebViewEvent& evt);
|
||||
void OnScriptMessage(wxWebViewEvent& evt);
|
||||
|
|
@ -334,7 +335,7 @@ bool WebApp::OnInit()
|
|||
return true;
|
||||
}
|
||||
|
||||
WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowInfo* newWindowInfo) :
|
||||
WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowFeatures* windowFeatures):
|
||||
wxFrame(nullptr, wxID_ANY, "wxWebView Sample")
|
||||
{
|
||||
m_isMainFrame = isMain;
|
||||
|
|
@ -420,7 +421,7 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowInfo* newWin
|
|||
}
|
||||
#endif
|
||||
// Create the webview
|
||||
m_browser = (newWindowInfo) ? newWindowInfo->CreateChildWebView() : wxWebView::New();
|
||||
m_browser = (windowFeatures) ? windowFeatures->GetChildWebView() : wxWebView::New();
|
||||
#ifdef __WXMAC__
|
||||
if (m_isMainFrame)
|
||||
{
|
||||
|
|
@ -433,18 +434,6 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowInfo* newWin
|
|||
m_browser->Create(this, wxID_ANY, url, wxDefaultPosition, wxDefaultSize);
|
||||
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
|
||||
|
||||
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
|
||||
|
|
@ -470,6 +459,18 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowInfo* newWin
|
|||
//Set a more sensible size for web browsing
|
||||
SetSize(FromDIP(wxSize(800, 600)));
|
||||
|
||||
if (windowFeatures)
|
||||
{
|
||||
if (windowFeatures->GetSize().IsFullySpecified())
|
||||
SetSize(FromDIP(windowFeatures->GetSize()));
|
||||
if (windowFeatures->GetPosition().IsFullySpecified())
|
||||
Move(FromDIP(windowFeatures->GetPosition()));
|
||||
if (!windowFeatures->ShouldDisplayToolBar())
|
||||
m_toolbar->Hide();
|
||||
if (!windowFeatures->ShouldDisplayMenuBar())
|
||||
SetMenuBar(nullptr);
|
||||
}
|
||||
|
||||
// Create the Tools menu
|
||||
m_tools_menu = new wxMenu();
|
||||
wxMenuItem* print = m_tools_menu->Append(wxID_ANY , _("Print"));
|
||||
|
|
@ -602,6 +603,7 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowInfo* newWin
|
|||
Bind(wxEVT_WEBVIEW_LOADED, &WebFrame::OnDocumentLoaded, this, m_browser->GetId());
|
||||
Bind(wxEVT_WEBVIEW_ERROR, &WebFrame::OnError, this, m_browser->GetId());
|
||||
Bind(wxEVT_WEBVIEW_NEWWINDOW, &WebFrame::OnNewWindow, this, m_browser->GetId());
|
||||
Bind(wxEVT_WEBVIEW_NEWWINDOW_FEATURES, &WebFrame::OnNewWindowFeatures, this, m_browser->GetId());
|
||||
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &WebFrame::OnTitleChanged, this, m_browser->GetId());
|
||||
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &WebFrame::OnFullScreenChanged, this, m_browser->GetId());
|
||||
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &WebFrame::OnScriptMessage, this, m_browser->GetId());
|
||||
|
|
@ -973,24 +975,41 @@ 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 create a new frame
|
||||
if (m_tools_handle_new_window->IsChecked())
|
||||
{
|
||||
WebFrame* newFrame = new WebFrame(evt.GetURL(), false, info);
|
||||
newFrame->Show();
|
||||
}
|
||||
if (!m_tools_handle_new_window->IsChecked())
|
||||
evt.Veto();
|
||||
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
void WebFrame::OnNewWindowFeatures(wxWebViewEvent &evt)
|
||||
{
|
||||
wxWebViewWindowFeatures* features = evt.GetTargetWindowFeatures();
|
||||
if (!features)
|
||||
return;
|
||||
|
||||
wxString featureDescription;
|
||||
if (features->GetPosition().IsFullySpecified())
|
||||
featureDescription += wxString::Format(" Position: %d, %d; ", features->GetPosition().x, features->GetPosition().y);
|
||||
if (features->GetSize().IsFullySpecified())
|
||||
featureDescription += wxString::Format(" Size: %d, %d; ", features->GetSize().x, features->GetSize().y);
|
||||
if (features->ShouldDisplayMenuBar())
|
||||
featureDescription += " MenuBar; ";
|
||||
if (features->ShouldDisplayStatusBar())
|
||||
featureDescription += " StatusBar; ";
|
||||
if (features->ShouldDisplayToolBar())
|
||||
featureDescription += " ToolBar; ";
|
||||
if (features->ShouldDisplayScrollBars())
|
||||
featureDescription += " ScrollBars; ";
|
||||
|
||||
wxLogMessage("Window features of child webview are available." + featureDescription);
|
||||
|
||||
// Create child frame with the features specified by window.open() call
|
||||
WebFrame* newFrame = new WebFrame(evt.GetURL(), false, features);
|
||||
newFrame->Show();
|
||||
}
|
||||
|
||||
void WebFrame::OnTitleChanged(wxWebViewEvent& evt)
|
||||
{
|
||||
SetTitle(evt.GetString());
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ wxDEFINE_EVENT( wxEVT_WEBVIEW_NAVIGATED, wxWebViewEvent );
|
|||
wxDEFINE_EVENT( wxEVT_WEBVIEW_LOADED, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_ERROR, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_NEWWINDOW_FEATURES, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_WINDOW_CLOSE_REQUESTED, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
||||
|
|
@ -86,6 +87,24 @@ wxString wxWebViewConfiguration::GetDataPath() const
|
|||
return m_impl->GetDataPath();
|
||||
}
|
||||
|
||||
// wxWebViewWindowFeatures
|
||||
wxWebViewWindowFeatures::wxWebViewWindowFeatures(wxWebView * childWebView):
|
||||
m_childWebViewWasUsed(false),
|
||||
m_childWebView(childWebView)
|
||||
{ }
|
||||
|
||||
wxWebViewWindowFeatures::~wxWebViewWindowFeatures()
|
||||
{
|
||||
if (m_childWebViewWasUsed)
|
||||
m_childWebView.release();
|
||||
}
|
||||
|
||||
wxWebView *wxWebViewWindowFeatures::GetChildWebView() const
|
||||
{
|
||||
m_childWebViewWasUsed = true;
|
||||
return m_childWebView.get();
|
||||
}
|
||||
|
||||
// wxWebViewHandlerRequest
|
||||
wxString wxWebViewHandlerRequest::GetDataString(const wxMBConv& conv) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,6 +88,62 @@ bool wxGetStringFromJSResult(WebKitJavascriptResult* js_result, wxString* output
|
|||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxWebViewWindowFeaturesWebKit
|
||||
//-----------------------------------------------------------------------------
|
||||
class wxWebViewWindowFeaturesWebKit : public wxWebViewWindowFeatures
|
||||
{
|
||||
public:
|
||||
wxWebViewWindowFeaturesWebKit(wxWebView* webViewCtrl, WebKitWebView *web_view):
|
||||
wxWebViewWindowFeatures(webViewCtrl)
|
||||
{
|
||||
m_properties = webkit_web_view_get_window_properties(web_view);
|
||||
webkit_window_properties_get_geometry(m_properties, &m_geometry);
|
||||
// Treat 0 as -1 to indicate that the value is not set
|
||||
if (m_geometry.width == 0)
|
||||
m_geometry.width = -1;
|
||||
if (m_geometry.height == 0)
|
||||
m_geometry.height = -1;
|
||||
if (m_geometry.x == 0)
|
||||
m_geometry.x = -1;
|
||||
if (m_geometry.y == 0)
|
||||
m_geometry.y = -1;
|
||||
}
|
||||
|
||||
virtual wxPoint GetPosition() const override
|
||||
{
|
||||
return wxPoint(m_geometry.x, m_geometry.y);
|
||||
}
|
||||
|
||||
virtual wxSize GetSize() const override
|
||||
{
|
||||
return wxSize(m_geometry.width, m_geometry.height);
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayMenuBar() const override
|
||||
{
|
||||
return webkit_window_properties_get_toolbar_visible(m_properties);
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayStatusBar() const override
|
||||
{
|
||||
return webkit_window_properties_get_statusbar_visible(m_properties);
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayToolBar() const override
|
||||
{
|
||||
return webkit_window_properties_get_toolbar_visible(m_properties);
|
||||
}
|
||||
|
||||
virtual bool ShouldDisplayScrollBars() const override
|
||||
{
|
||||
return webkit_window_properties_get_scrollbars_visible(m_properties);
|
||||
}
|
||||
|
||||
GdkRectangle m_geometry;
|
||||
WebKitWindowProperties *m_properties;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GTK callbacks
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -378,6 +434,27 @@ static void wxgtk_webview_webkit_close (WebKitWebView *WXUNUSED(web_view),
|
|||
webKitCtrl->HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
class wxReadyToShowParams
|
||||
{
|
||||
public:
|
||||
wxWebViewWebKit* childWebView;
|
||||
wxWebViewWebKit* parentWebView;
|
||||
};
|
||||
|
||||
static void wxgtk_webview_webkit_ready_to_show (WebKitWebView *web_view,
|
||||
wxReadyToShowParams *params)
|
||||
{
|
||||
wxWebViewWindowFeaturesWebKit features(params->childWebView, web_view);
|
||||
wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW_FEATURES,
|
||||
params->parentWebView->GetId(),
|
||||
params->childWebView->GetCurrentURL(),
|
||||
"");
|
||||
event.SetEventObject(params->parentWebView);
|
||||
event.SetClientData(&features);
|
||||
params->parentWebView->HandleWindowEvent(event);
|
||||
delete params;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wxgtk_webview_webkit_decide_policy(WebKitWebView *web_view,
|
||||
WebKitPolicyDecision *decision,
|
||||
|
|
@ -478,13 +555,25 @@ wxgtk_webview_webkit_context_menu(WebKitWebView *,
|
|||
|
||||
static WebKitWebView*
|
||||
wxgtk_webview_webkit_create_webview(WebKitWebView *web_view,
|
||||
WebKitNavigationAction *,
|
||||
WebKitNavigationAction *navigation_action,
|
||||
wxWebViewWebKit *webKitCtrl)
|
||||
{
|
||||
//As we do not know the uri being loaded at this point allow the load to
|
||||
//continue and catch it in navigation-policy-decision-requested
|
||||
webKitCtrl->m_creating = true;
|
||||
return web_view;
|
||||
auto request = webkit_navigation_action_get_request(navigation_action);
|
||||
wxString url = wxString::FromUTF8(webkit_uri_request_get_uri(request));
|
||||
wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW,
|
||||
webKitCtrl->GetId(),
|
||||
url,
|
||||
"");
|
||||
event.SetEventObject(webKitCtrl);
|
||||
webKitCtrl->HandleWindowEvent(event);
|
||||
|
||||
if ( event.IsAllowed() )
|
||||
{
|
||||
wxWebView* childWebView = new wxWebViewWebKit(web_view, webKitCtrl);
|
||||
return (WebKitWebView*)childWebView->GetNativeBackend();
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -738,6 +827,21 @@ wxWebViewWebKit::wxWebViewWebKit():
|
|||
m_extension = nullptr;
|
||||
}
|
||||
|
||||
wxWebViewWebKit::wxWebViewWebKit(WebKitWebView* parentWebView, wxWebViewWebKit* parentWebViewCtrl):
|
||||
m_config(parentWebViewCtrl->m_config)
|
||||
{
|
||||
m_web_view = (WebKitWebView*) webkit_web_view_new_with_related_view(parentWebView);
|
||||
m_dbusServer = nullptr;
|
||||
m_extension = nullptr;
|
||||
|
||||
wxReadyToShowParams* params = new wxReadyToShowParams();
|
||||
params->childWebView = this;
|
||||
params->parentWebView = parentWebViewCtrl;
|
||||
|
||||
g_signal_connect(m_web_view, "ready-to-show",
|
||||
G_CALLBACK(wxgtk_webview_webkit_ready_to_show), params);
|
||||
}
|
||||
|
||||
wxWebViewWebKit::wxWebViewWebKit(const wxWebViewConfiguration &config):
|
||||
m_config(config)
|
||||
{
|
||||
|
|
@ -754,7 +858,6 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
long style,
|
||||
const wxString& name)
|
||||
{
|
||||
m_web_view = nullptr;
|
||||
m_dbusServer = nullptr;
|
||||
m_extension = nullptr;
|
||||
m_busy = false;
|
||||
|
|
@ -762,6 +865,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
m_creating = false;
|
||||
FindClear();
|
||||
|
||||
bool isChildWebView = m_web_view != nullptr;
|
||||
|
||||
// We currently unconditionally impose scrolling in both directions as it's
|
||||
// necessary to show arbitrary pages.
|
||||
style |= wxHSCROLL | wxVSCROLL;
|
||||
|
|
@ -779,6 +884,7 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
G_CALLBACK(wxgtk_initialize_web_extensions),
|
||||
m_dbusServer);
|
||||
|
||||
if (!isChildWebView)
|
||||
#ifdef wxHAVE_WEBKIT_WEBSITE_DATA_MANAGER
|
||||
m_web_view = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(WEBKIT_WEB_CONTEXT(m_config.GetNativeConfiguration())));
|
||||
#else
|
||||
|
|
@ -825,7 +931,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
PostCreation(size);
|
||||
|
||||
/* Open a webpage */
|
||||
webkit_web_view_load_uri(m_web_view, url.utf8_str());
|
||||
if (!isChildWebView)
|
||||
webkit_web_view_load_uri(m_web_view, url.utf8_str());
|
||||
|
||||
// last to avoid getting signal too early
|
||||
g_signal_connect(m_web_view, "load-changed",
|
||||
|
|
|
|||
|
|
@ -320,13 +320,13 @@ public:
|
|||
|
||||
wxString wxWebViewConfigurationImplEdge::ms_browserExecutableDir;
|
||||
|
||||
// wxWebViewNewWindowInfoEdge
|
||||
// wxWebViewWindowFeaturesEdge
|
||||
|
||||
class wxWebViewNewWindowInfoEdge : public wxWebViewWindowInfo
|
||||
class wxWebViewWindowFeaturesEdge : public wxWebViewWindowFeatures
|
||||
{
|
||||
public:
|
||||
wxWebViewNewWindowInfoEdge(wxWebViewEdgeImpl* impl, ICoreWebView2NewWindowRequestedEventArgs* args):
|
||||
m_impl(impl),
|
||||
wxWebViewWindowFeaturesEdge(wxWebView* childWebView, ICoreWebView2NewWindowRequestedEventArgs* args):
|
||||
wxWebViewWindowFeatures(childWebView),
|
||||
m_args(args)
|
||||
{
|
||||
m_args->get_WindowFeatures(&m_windowFeatures);
|
||||
|
|
@ -395,36 +395,11 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual wxWebView* CreateChildWebView() override
|
||||
{
|
||||
return m_impl->CreateChildWebView(
|
||||
std::make_shared<wxWebViewEdgeParentWindowInfo>(m_args));
|
||||
}
|
||||
|
||||
private:
|
||||
wxWebViewEdgeImpl* m_impl;
|
||||
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_args;
|
||||
wxCOMPtr<ICoreWebView2WindowFeatures> m_windowFeatures;
|
||||
};
|
||||
|
||||
class wxWebViewEdgeParentWindowInfo
|
||||
{
|
||||
public:
|
||||
wxWebViewEdgeParentWindowInfo(ICoreWebView2NewWindowRequestedEventArgs* args):
|
||||
m_args(args)
|
||||
{
|
||||
HRESULT hr = m_args->GetDeferral(&m_deferral);
|
||||
if (FAILED(hr))
|
||||
wxLogApiError("GetDeferral", hr);
|
||||
}
|
||||
|
||||
virtual ~wxWebViewEdgeParentWindowInfo() = default;
|
||||
|
||||
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_args;
|
||||
wxCOMPtr<ICoreWebView2Deferral> m_deferral;
|
||||
};
|
||||
|
||||
|
||||
#define wxWEBVIEW_EDGE_EVENT_HANDLER_METHOD \
|
||||
m_inEventCallback = true; \
|
||||
wxON_BLOCK_EXIT_SET(m_inEventCallback, false);
|
||||
|
|
@ -476,13 +451,6 @@ bool wxWebViewEdgeImpl::Create()
|
|||
CreateOrGetEnvironment(this);
|
||||
}
|
||||
|
||||
wxWebViewEdge* wxWebViewEdgeImpl::CreateChildWebView(std::shared_ptr<wxWebViewEdgeParentWindowInfo> parentWindowInfo)
|
||||
{
|
||||
wxWebViewEdge* childWebView = new wxWebViewEdge(m_config);
|
||||
childWebView->m_impl->m_parentWindowInfo = parentWindowInfo;
|
||||
return childWebView;
|
||||
}
|
||||
|
||||
void wxWebViewEdgeImpl::EnvironmentAvailable(ICoreWebView2Environment* environment)
|
||||
{
|
||||
environment->QueryInterface(IID_PPV_ARGS(&m_webViewEnvironment));
|
||||
|
|
@ -684,11 +652,24 @@ HRESULT wxWebViewEdgeImpl::OnNewWindowRequested(ICoreWebView2* WXUNUSED(sender),
|
|||
if (SUCCEEDED(args->get_IsUserInitiated(&isUserInitiated)) && isUserInitiated)
|
||||
navFlags = wxWEBVIEW_NAV_ACTION_USER;
|
||||
|
||||
wxWebViewNewWindowInfoEdge windowInfo(this, args);
|
||||
wxWebViewEvent evt(wxEVT_WEBVIEW_NEWWINDOW, m_ctrl->GetId(), evtURL, wxString(), navFlags, "");
|
||||
evt.SetClientData(&windowInfo);
|
||||
m_ctrl->HandleWindowEvent(evt);
|
||||
wxWebViewEvent newWindowEvent(wxEVT_WEBVIEW_NEWWINDOW, m_ctrl->GetId(), evtURL, wxString(), navFlags, "");
|
||||
m_ctrl->HandleWindowEvent(newWindowEvent);
|
||||
args->put_Handled(true);
|
||||
|
||||
if (newWindowEvent.IsAllowed())
|
||||
{
|
||||
wxWebViewEdge* childWebView = new wxWebViewEdge(m_config);
|
||||
childWebView->m_impl->m_newWindowArgs = args;
|
||||
HRESULT hr = args->GetDeferral(&childWebView->m_impl->m_newWindowDeferral);
|
||||
if (FAILED(hr))
|
||||
wxLogApiError("GetDeferral", hr);
|
||||
|
||||
wxWebViewWindowFeaturesEdge windowFeatures(childWebView, args);
|
||||
wxWebViewEvent featuresEvent(wxEVT_WEBVIEW_NEWWINDOW_FEATURES, m_ctrl->GetId(), evtURL, wxString(), navFlags, "");
|
||||
featuresEvent.SetClientData(&windowFeatures);
|
||||
m_ctrl->HandleWindowEvent(featuresEvent);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -916,13 +897,14 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
|
|||
m_pendingUserScripts.clear();
|
||||
}
|
||||
|
||||
if (m_parentWindowInfo)
|
||||
if (m_newWindowArgs)
|
||||
{
|
||||
if (FAILED(m_parentWindowInfo->m_args->put_NewWindow(baseWebView)))
|
||||
if (FAILED(m_newWindowArgs->put_NewWindow(baseWebView)))
|
||||
SendErrorEventForAPI("WebView2::WebViewCreated (put_NewWindow)", hr);
|
||||
if (FAILED(m_parentWindowInfo->m_deferral->Complete()))
|
||||
if (FAILED(m_newWindowDeferral->Complete()))
|
||||
SendErrorEventForAPI("WebView2::WebViewCreated (Complete)", hr);
|
||||
m_parentWindowInfo.reset();
|
||||
m_newWindowArgs.reset();
|
||||
m_newWindowDeferral.reset();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,15 +140,17 @@ wxWebViewConfiguration wxWebViewFactoryWebKit::CreateConfiguration()
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxWebViewWindowInfoWebKit
|
||||
// wxWebViewWindowFeaturesWebKit
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class wxWebViewWindowInfoWebKit: public wxWebViewWindowInfo
|
||||
class wxWebViewWindowFeaturesWebKit: public wxWebViewWindowFeatures
|
||||
{
|
||||
public:
|
||||
wxWebViewWindowInfoWebKit(WKWebViewConfiguration* configuration,
|
||||
WKNavigationAction* navigationAction,
|
||||
WKWindowFeatures* windowFeatures):
|
||||
wxWebViewWindowFeaturesWebKit(wxWebView* childWebView,
|
||||
WKWebViewConfiguration* configuration,
|
||||
WKNavigationAction* navigationAction,
|
||||
WKWindowFeatures* windowFeatures):
|
||||
wxWebViewWindowFeatures(childWebView),
|
||||
m_configuration(configuration),
|
||||
m_navigationAction(navigationAction),
|
||||
m_windowFeatures(windowFeatures)
|
||||
|
|
@ -206,14 +208,6 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual wxWebView* CreateChildWebView() override
|
||||
{
|
||||
m_childWebView = new wxWebViewWebKit(wxWebViewConfiguration(wxWebViewBackendWebKit,
|
||||
new wxWebViewConfigurationImplWebKit(m_configuration)), this);
|
||||
return m_childWebView;
|
||||
}
|
||||
|
||||
wxWebView* m_childWebView = nullptr;
|
||||
WKWebViewConfiguration* m_configuration;
|
||||
WKNavigationAction* m_navigationAction;
|
||||
WKWindowFeatures* m_windowFeatures;
|
||||
|
|
@ -224,9 +218,9 @@ public:
|
|||
// creation/destruction
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxWebViewWebKit::wxWebViewWebKit(const wxWebViewConfiguration& config, wxWebViewWindowInfoWebKit* parentWindowInfo):
|
||||
wxWebViewWebKit::wxWebViewWebKit(const wxWebViewConfiguration& config, WX_NSObject request):
|
||||
m_configuration(config),
|
||||
m_parentWindowInfo(parentWindowInfo)
|
||||
m_request(request)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -240,10 +234,12 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
DontCreatePeer();
|
||||
wxControl::Create(parent, winID, pos, size, style, wxDefaultValidator, name);
|
||||
|
||||
bool isChildWebView = m_request != nil;
|
||||
|
||||
NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
|
||||
WKWebViewConfiguration* webViewConfig = (WKWebViewConfiguration*) m_configuration.GetNativeConfiguration();
|
||||
|
||||
if (!m_handlers.empty() && !m_parentWindowInfo)
|
||||
if (!m_handlers.empty() && !isChildWebView)
|
||||
{
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
||||
if ( WX_IS_MACOS_AVAILABLE(10, 13) )
|
||||
|
|
@ -285,7 +281,7 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
|
||||
[m_webView setUIDelegate:uiDelegate];
|
||||
|
||||
if (!m_parentWindowInfo)
|
||||
if (!isChildWebView)
|
||||
{
|
||||
// Implement javascript fullscreen interface with user script and message handler
|
||||
AddUserScript("\
|
||||
|
|
@ -326,8 +322,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||
|
||||
m_UIDelegate = uiDelegate;
|
||||
|
||||
if (m_parentWindowInfo)
|
||||
[m_webView loadRequest:m_parentWindowInfo->m_navigationAction.request];
|
||||
if (m_request)
|
||||
[m_webView loadRequest:(NSURLRequest*)m_request];
|
||||
else
|
||||
LoadURL(strURL);
|
||||
return true;
|
||||
|
|
@ -1126,19 +1122,31 @@ WX_API_AVAILABLE_MACOS(10, 13)
|
|||
wxWEBVIEW_NAV_ACTION_USER :
|
||||
wxWEBVIEW_NAV_ACTION_OTHER;
|
||||
|
||||
wxWebViewWindowInfoWebKit windowInfo(configuration, navigationAction, windowFeatures);
|
||||
|
||||
wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW,
|
||||
wxWebViewEvent newWinEvent(wxEVT_WEBVIEW_NEWWINDOW,
|
||||
webKitWindow->GetId(),
|
||||
wxCFStringRef::AsString( navigationAction.request.URL.absoluteString ),
|
||||
"", navFlags);
|
||||
event.SetClientData(&windowInfo);
|
||||
|
||||
if (webKitWindow && webKitWindow->GetEventHandler())
|
||||
webKitWindow->GetEventHandler()->ProcessEvent(event);
|
||||
webKitWindow->GetEventHandler()->ProcessEvent(newWinEvent);
|
||||
|
||||
if (windowInfo.m_childWebView)
|
||||
return (WKWebView*) windowInfo.m_childWebView->GetNativeBackend();
|
||||
if (newWinEvent.IsAllowed())
|
||||
{
|
||||
wxWebView* childWebView = new wxWebViewWebKit(wxWebViewConfiguration(wxWebViewBackendWebKit,
|
||||
new wxWebViewConfigurationImplWebKit(configuration)), navigationAction.request);
|
||||
wxWebViewWindowFeaturesWebKit childWindowFeatures(childWebView, configuration, navigationAction, windowFeatures);
|
||||
|
||||
wxWebViewEvent featuresEvent(wxEVT_WEBVIEW_NEWWINDOW_FEATURES,
|
||||
webKitWindow->GetId(),
|
||||
wxCFStringRef::AsString( navigationAction.request.URL.absoluteString ),
|
||||
"", navFlags);
|
||||
featuresEvent.SetClientData(&childWindowFeatures);
|
||||
if (webKitWindow && webKitWindow->GetEventHandler())
|
||||
webKitWindow->GetEventHandler()->ProcessEvent(featuresEvent);
|
||||
|
||||
return (WKWebView*) childWebView->GetNativeBackend();
|
||||
}
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue