From bb508dc347f1fc7459cd35506b6507795f04553c Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Thu, 16 Jan 2020 20:50:26 +0100 Subject: [PATCH] Implement text selection in wxWebViewEdge Text selection/copy/paste etc implemented via javascript --- include/wx/msw/webview_edge.h | 3 ++ interface/wx/webview.h | 2 +- src/msw/webview_edge.cpp | 54 +++++++++++++++++++++-------------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/include/wx/msw/webview_edge.h b/include/wx/msw/webview_edge.h index 6a77065a3b..e1ccdcefab 100644 --- a/include/wx/msw/webview_edge.h +++ b/include/wx/msw/webview_edge.h @@ -111,6 +111,9 @@ public: virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE; virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE; + bool QueryCommandEnabled(const wxString& command) const; + void ExecCommand(const wxString& command); + virtual bool RunScript(const wxString& javascript, wxString* output = NULL) wxOVERRIDE; virtual void RegisterHandler(wxSharedPtr handler) wxOVERRIDE; diff --git a/interface/wx/webview.h b/interface/wx/webview.h index c816200dd2..6c5a2b0ad6 100644 --- a/interface/wx/webview.h +++ b/interface/wx/webview.h @@ -285,7 +285,7 @@ public: Edge WebView2. It is available for Windows 7 and newer. The following features are currently unsupported with this backend: - virtual filesystems, custom urls, text selection, find, source code. + virtual filesystems, custom urls, find, source code. This backend is not enabled by default, to build it follow these steps: - Visual Studio 2015, or newer, is required diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index d44914ebb4..88ff6c13a2 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -598,57 +598,52 @@ void wxWebViewEdge::SetZoom(wxWebViewZoom zoom) bool wxWebViewEdge::CanCut() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return false; + return QueryCommandEnabled("cut"); } bool wxWebViewEdge::CanCopy() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return false; + return QueryCommandEnabled("copy"); } bool wxWebViewEdge::CanPaste() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return false; + return QueryCommandEnabled("paste"); } void wxWebViewEdge::Cut() { - // TODO: not implemented in SDK (could probably be implemented by script) + ExecCommand("cut"); } void wxWebViewEdge::Copy() { - // TODO: not implemented in SDK (could probably be implemented by script) + ExecCommand("copy"); } void wxWebViewEdge::Paste() { - // TODO: not implemented in SDK (could probably be implemented by script) + ExecCommand("paste"); } bool wxWebViewEdge::CanUndo() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return false; + return QueryCommandEnabled("undo"); } bool wxWebViewEdge::CanRedo() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return false; + return QueryCommandEnabled("redo"); } void wxWebViewEdge::Undo() { - // TODO: not implemented in SDK (could probably be implemented by script) + ExecCommand("undo"); } void wxWebViewEdge::Redo() { - // TODO: not implemented in SDK (could probably be implemented by script) + ExecCommand("redo"); } long wxWebViewEdge::Find(const wxString& WXUNUSED(text), int WXUNUSED(flags)) @@ -670,24 +665,26 @@ bool wxWebViewEdge::IsEditable() const void wxWebViewEdge::SelectAll() { - // TODO: not implemented in SDK (could probably be implemented by script) + RunScript("window.getSelection().selectAllChildren(document);"); } bool wxWebViewEdge::HasSelection() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return false; + wxString rangeCountStr; + const_cast(this)->RunScript("window.getSelection().rangeCount;", &rangeCountStr); + return rangeCountStr != "0"; } void wxWebViewEdge::DeleteSelection() { - // TODO: not implemented in SDK (could probably be implemented by script) + ExecCommand("delete"); } wxString wxWebViewEdge::GetSelectedText() const { - // TODO: not implemented in SDK (could probably be implemented by script) - return wxString(); + wxString selectedText; + const_cast(this)->RunScript("window.getSelection().toString();", &selectedText); + return selectedText; } wxString wxWebViewEdge::GetSelectedSource() const @@ -698,7 +695,7 @@ wxString wxWebViewEdge::GetSelectedSource() const void wxWebViewEdge::ClearSelection() { - // TODO: not implemented in SDK (could probably be implemented by script) + RunScript("window.getSelection().empty();"); } void wxWebViewEdge::EnableContextMenu(bool enable) @@ -749,6 +746,19 @@ void* wxWebViewEdge::GetNativeBackend() const return m_impl->m_webView; } +bool wxWebViewEdge::QueryCommandEnabled(const wxString& command) const +{ + wxString resultStr; + const_cast(this)->RunScript( + wxString::Format("function f(){ return document.queryCommandEnabled('%s'); } f();", command), &resultStr); + return resultStr.IsSameAs("true", false); +} + +void wxWebViewEdge::ExecCommand(const wxString& command) +{ + RunScript(wxString::Format("document.execCommand('%s');", command)); +} + bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) { bool scriptExecuted = false;