我有一个使用在 mono c# 中运行的 webkit 制作的 webbrowser。我想允许页面在浏览器中调用一个函数,然后浏览器根据传递的参数执行操作。我似乎无法做到。
html页面是下一个
<html>
<head>
<title>ola</title>
</head>
<body>
<button onclick="window.external.Test('called from script code');">test</button>
</body>
</html>
webkit.cs
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Gtk;
using GLib;
namespace WebKit
{
class DOMDocument : GLib.Object
{
public DOMDocument (IntPtr raw) : base (raw) {}
[DllImport ("webkit-1.0")]
private static extern IntPtr webkit_dom_document_get_elements_by_tag_name (IntPtr raw, IntPtr str1ng);
public DOMNodeList get_elements_by_tag_name (string tag)
{
IntPtr intPtr = Marshaller.StringToPtrGStrdup (tag);
IntPtr result = webkit_dom_document_get_elements_by_tag_name(base.Handle, intPtr);
Marshaller.Free (intPtr);
return new DOMNodeList(result);
}
}
// http://www.opensource.apple.com/source/WebKit/WebKit-7533.16/gtk/tests/testdomdocument.c
class DOMNodeList: GLib.Object, IEnumerable
{
public DOMNodeList (IntPtr raw) : base (raw) {}
[DllImport ("webkit-1.0")]
private static extern IntPtr webkit_dom_node_list_item (IntPtr raw, int element);
[DllImport ("webkit-1.0")]
private static extern int webkit_dom_node_list_get_length (IntPtr raw);
public IEnumerator GetEnumerator ()
{
for (int i = 0; i < webkit_dom_node_list_get_length(base.Handle); i++) {
yield return new DOMNode(webkit_dom_node_list_item(base.Handle, i));
}
}
}
class DOMNode : GLib.Object
{
public DOMNode (IntPtr raw) : base (raw) {}
}
class DOMElement : GLib.Object
{
public DOMElement (IntPtr raw) : base (raw) {}
}
class DOMHTMLElement : GLib.Object
{
public DOMHTMLElement (IntPtr raw) : base (raw) {}
[DllImport ("webkit-1.0")]
private static extern IntPtr webkit_dom_html_element_get_inner_text(IntPtr raw);
public string get_inner_text ()
{
IntPtr data = webkit_dom_html_element_get_inner_text(base.Handle);
return Marshaller.PtrToStringGFree(data);
}
}
class ExtendedWebSettings : WebKit.WebSettings {
public void g_object_set(string name, GLib.Value value) {
SetProperty(name, value);
}
public GLib.Value g_object_get(string name) {
return GetProperty(name);
}
}
class ExtendedWebView : WebKit.WebView {
[DllImport ("webkit-1.0")]
private static extern IntPtr webkit_web_view_get_dom_document (IntPtr raw);
public DOMDocument get_dom_document()
{
return new DOMDocument(webkit_web_view_get_dom_document(base.Handle));
}
public event CreateWebViewHandler CreateWebView
{
add
{
Signal signal = Signal.Lookup (this, "create-web-view", typeof(CreateWebViewArgs));
signal.AddDelegate (value);
}
remove
{
Signal signal = Signal.Lookup (this, "create-web-view", typeof(CreateWebViewArgs));
signal.RemoveDelegate (value);
}
}
public event WebViewReadyHandler WebViewReady
{
add
{
Signal signal = Signal.Lookup (this, "web-view-ready", typeof(WebViewReadyArgs));
signal.AddDelegate (value);
}
remove
{
Signal signal = Signal.Lookup (this, "web-view-ready", typeof(WebViewReadyArgs));
signal.RemoveDelegate (value);
}
}
public event NewWindowPolicyDecisionRequestedHandler NewWindowPolicyDecisionRequested
{
add
{
Signal signal = Signal.Lookup (this, "new-window-policy-decision-requested", typeof(NewWindowPolicyDecisionRequestedArgs));
signal.AddDelegate (value);
}
remove
{
Signal signal = Signal.Lookup (this, "new-window-policy-decision-requested", typeof(NewWindowPolicyDecisionRequestedArgs));
signal.RemoveDelegate (value);
}
}
[DefaultSignalHandler (Type = typeof(WebView), ConnectionMethod = "OverrideCreateWebView")]
protected virtual WebView OnCreateWebView (WebFrame frame)
{
ExtendedWebView webView = new ExtendedWebView();
Value empty = Value.Empty;
ValueArray valueArray = new ValueArray (2u);
Value[] array = new Value[2];
array [0] = new Value (this);
valueArray.Append (array [0]);
array [1] = new Value (frame);
valueArray.Append (array [1]);
GLib.Object.g_signal_chain_from_overridden (valueArray.ArrayPtr, ref empty);
Value[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
Value value = array2 [i];
value.Dispose ();
}
return webView;
}
[DefaultSignalHandler (Type = typeof(WebView), ConnectionMethod = "OverrideNewWindowPolicyDecisionRequested")]
protected virtual int OnNewWindowPolicyDecisionRequested (WebFrame frame, NetworkRequest request, WebNavigationAction navigation_action, WebPolicyDecision policy_decision)
{
Value val = new Value (GType.Int);
ValueArray valueArray = new ValueArray (3u);
Value[] array = new Value[5];
array [0] = new Value (this);
valueArray.Append (array [0]);
array [1] = new Value (frame);
valueArray.Append (array [1]);
array [2] = new Value (request);
valueArray.Append (array [2]);
array [3] = new Value (navigation_action);
valueArray.Append (array [3]);
array [4] = new Value (policy_decision);
valueArray.Append (array [4]);
GLib.Object.g_signal_chain_from_overridden (valueArray.ArrayPtr, ref val);
Value[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
Value value = array2 [i];
value.Dispose ();
}
int result = (int)val;
val.Dispose ();
return result;
}
[DefaultSignalHandler (Type = typeof(WebView), ConnectionMethod = "OverrideWebViewReady")]
protected virtual bool OnWebViewReady (WebFrame frame)
{
Value empty = Value.Empty;
ValueArray valueArray = new ValueArray (2u);
Value[] array = new Value[2];
array [0] = new Value (this);
valueArray.Append (array [0]);
array [1] = new Value (frame);
valueArray.Append (array [1]);
GLib.Object.g_signal_chain_from_overridden (valueArray.ArrayPtr, ref empty);
Value[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
Value value = array2 [i];
value.Dispose ();
}
return true;
}
}
public delegate void WebViewReadyHandler (object o, WebViewReadyArgs args);
public class WebViewReadyArgs : SignalArgs
{
//
// Properties
//
public WebFrame Frame
{
get
{
return (WebFrame)base.Args [0];
}
}
}
public delegate void CreateWebViewHandler (object o, CreateWebViewArgs args);
public class CreateWebViewArgs : SignalArgs
{
//
// Properties
//
public WebFrame Frame
{
get
{
return (WebFrame)base.Args [0];
}
}
}
public delegate void NewWindowPolicyDecisionRequestedHandler (object o, NewWindowPolicyDecisionRequestedArgs args);
public class NewWindowPolicyDecisionRequestedArgs : SignalArgs
{
//
// Properties
//
public WebFrame Frame
{
get
{
return (WebFrame)base.Args [0];
}
}
public NetworkRequest Request
{
get
{
return (NetworkRequest)base.Args [1];
}
}
public WebNavigationAction NavigationAction
{
get
{
return (WebNavigationAction)base.Args [2];
}
}
public WebPolicyDecision PolicyDecision
{
get
{
return (WebPolicyDecision)base.Args [3];
}
}
}
}
和 Main.cs
using System;
using Gtk;
using GLib;
using WebKit;
using System.Timers;
//using Notifications;
using System.Text.RegularExpressions;
public partial class MainWindow: Gtk.Window
{
private Timer notifications = new Timer(2000);
private ExtendedWebView webView;
private bool recent_notification = false;
public MainWindow (string url): base (Gtk.WindowType.Toplevel)
{
Build ();
url ="http://127.0.0.1/csharp/";
webView = new ExtendedWebView ();
ExtendedWebSettings settings = new ExtendedWebSettings ();
settings.g_object_set ("user-agent", new GLib.Value ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0"));
settings.g_object_set ("enable-spell-checking", new GLib.Value (true));
webView.TitleChanged += HandleTitleChanged;
webView.Settings = settings;
webView.NewWindowPolicyDecisionRequested += HandleNewWindowPolicyDecisionRequested;
webView.CreateWebView += HandleCreateWebView;
webView.Open(url);
webView.LoadFinished += new LoadFinishedHandler (OnLoadFinished);
VBox vbox1 = new VBox();
vbox1.PackStart(webView);
this.Add(vbox1);
this.ShowAll();
}
private void OnLoadFinished (object o, LoadFinishedArgs args)
{
String testVar = "[ { \"id\" : \"4578\" },{ \"id\" : \"4579\" }]";
Console.WriteLine("Executei isto por aqui....");
webView.ExecuteScript("scriptTeste(" + testVar + ");");
Console.WriteLine("Executei isto por aqui....");
}
void HandleCreateWebView (object o, CreateWebViewArgs args)
{
Window info = new Window("");
info.DefaultWidth = 1000;
info.DefaultHeight = 700;
VBox vbox2 = new VBox();
WebView child = new WebView();
child.NavigationRequested += HandleNavigationRequested1;
vbox2.PackStart(child);
info.Add (vbox2);
info.ShowAll();
args.RetVal = child;
}
void HandleNavigationRequested1 (object o, NavigationRequestedArgs args)
{
// Destroy the window if it was already opened in the browser
if (args.Request.Uri.Contains ("&URL=")) {
WebView self = (WebView)o;
VBox container = (VBox)self.Parent;
Window parent = (Window)container.Parent;
parent.Destroy();
args.RetVal = 1;
}
}
void HandleNewWindowPolicyDecisionRequested (object o, NewWindowPolicyDecisionRequestedArgs args)
{
string URL = System.Web.HttpUtility.UrlDecode(Regex.Split(args.Request.Uri, "&URL=")[1]);
System.Diagnostics.Process.Start(URL);
}
void HandleElapsed (object sender, ElapsedEventArgs e)
{
if (recent_notification) {
notifications.Interval = 5000;
recent_notification = false;
}
/* if (!recent_notification && webView.SearchText ("Reminders", true, true, true)) {
Notification notify = new Notification ("Outlook Notification", "");
notify.Urgency = Urgency.Normal;
notify.Show ();
recent_notification = true;
notifications.Interval = 30000;
}*/
}
void HandleTitleChanged (object o, TitleChangedArgs args)
{
this.Title = args.Title;
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}
}
如果你想要 c# 项目,它在这里https://github.com/dmulder/owa_browse/
提前致谢。