Moving JSCall to be a separate library from AspNetEdit. AspNetEdit will
be broken for an hour or so. svn path=/trunk/aspeditor/; revision=62248
This commit is contained in:
Родитель
7634fd87c2
Коммит
586bfa5b84
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* CommandManager.cs - The C# side of the JSCall Gecko#/C# glue layer
|
||||
*
|
||||
* Authors:
|
||||
* Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2005 Michael Hutchinson
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Gecko;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AspNetEdit.JSCall
|
||||
{
|
||||
public class CommandManager
|
||||
{
|
||||
[DllImport ("jscallglue.dll")]
|
||||
static extern int PlaceFunctionCall (IntPtr embed,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string call,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string returnto,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string args);
|
||||
|
||||
[DllImport ("jscallglue.dll")]
|
||||
static extern int ExecuteScript (IntPtr embed,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string script);
|
||||
|
||||
private Hashtable functions = new Hashtable ();
|
||||
private WebControl webControl;
|
||||
|
||||
public CommandManager (WebControl control)
|
||||
{
|
||||
if (control == null)
|
||||
throw new ArgumentNullException ("The Command Manager must be bound to a WebControl instance.", "control");
|
||||
|
||||
webControl = control;
|
||||
webControl.TitleChange += new EventHandler (webControl_ECMAStatus);
|
||||
}
|
||||
|
||||
private void webControl_ECMAStatus (object sender, EventArgs e)
|
||||
{
|
||||
if (!webControl.Title.StartsWith ("JSCall"))
|
||||
return;
|
||||
|
||||
string[] call = webControl.Title.Split ((char)234);
|
||||
if (call.Length < 2)
|
||||
throw new Exception ("Too few parameters in call from JavaScript.");
|
||||
|
||||
string function = call[1];
|
||||
string returnTo = call[2];
|
||||
|
||||
string[] args = (string[]) System.Array.CreateInstance (typeof(String), (call.Length - 3));
|
||||
System.Array.Copy (call, 3, args, 0, (call.Length - 3));
|
||||
|
||||
if (!functions.Contains (function))
|
||||
throw new Exception ("Unknown function name called from JavaScript.");
|
||||
|
||||
ClrCall clrCall = (ClrCall) functions[function];
|
||||
|
||||
|
||||
if (returnTo.Length == 0)
|
||||
{
|
||||
clrCall (args);
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] result = { clrCall (args) };
|
||||
JSCall(returnTo, null, result);
|
||||
}
|
||||
}
|
||||
|
||||
public void JSEval (string script)
|
||||
{
|
||||
if ((script == null) || (script.Length < 1))
|
||||
throw new ArgumentNullException ("A null or empty script cannot be executed.", "script");
|
||||
|
||||
int result = ExecuteScript (webControl.Handle, script);
|
||||
string err;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case 0:
|
||||
return;
|
||||
|
||||
case 1:
|
||||
err = "Could not obtain IDOMDocument from GtkMozEmbed. Have you shown the window yet?";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
err = "Could not create script element.";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
err = "Could not cast script element to nsIDOMHTMLScriptElement.";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
err = "Could not locate body element.";
|
||||
break;
|
||||
|
||||
case 5:
|
||||
err = "Could not append script element to body.";
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Exception ("Glue function ExecuteScript: " + err);
|
||||
}
|
||||
|
||||
public void JSCall (string function, string returnTo, params string[] args)
|
||||
{
|
||||
if ((function==null) || (function.Length < 1))
|
||||
throw new ArgumentException ("A function name must be specified.", "function");
|
||||
|
||||
if (returnTo == null) returnTo = string.Empty;
|
||||
|
||||
string argsOut = String.Empty;
|
||||
|
||||
if (args != null) {
|
||||
argsOut += args[0];
|
||||
for (int i = 1; i <= args.Length - 1; i++) {
|
||||
argsOut += (char)234 + args[i];
|
||||
}
|
||||
}
|
||||
|
||||
int result = PlaceFunctionCall (webControl.Handle, function, returnTo, argsOut);
|
||||
|
||||
string err;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case 0:
|
||||
return;
|
||||
|
||||
case 1:
|
||||
err = "Could not obtain IDOMDocument from GtkMozEmbed. Have you shown the window yet?";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
err = "Error finding 'jscall' nodes.";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
err = "Error getting number of 'jscall' nodes.";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
err = "More or fewer than one 'jscall' node.";
|
||||
break;
|
||||
|
||||
case 5:
|
||||
err = "Error getting 'jscall' node.";
|
||||
break;
|
||||
|
||||
case 6:
|
||||
err = "Error adding 'infunction' node.";
|
||||
break;
|
||||
|
||||
case 7:
|
||||
err = "Error setting attributes on 'infunction' node.";
|
||||
break;
|
||||
|
||||
case 8:
|
||||
err = "Error getting nsIDOMNode interface on 'infunction' node.";
|
||||
break;
|
||||
|
||||
case 9:
|
||||
err = "Error appending 'infunction' node to 'jscall' node.";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = "The glue wrapper returned an unknown error.";
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Exception ("Glue function PlaceFunctionCall: "+err);
|
||||
}
|
||||
|
||||
public void RegisterJSHandler (string name, ClrCall handler)
|
||||
{
|
||||
if (!functions.Contains (name))
|
||||
{
|
||||
functions.Add (name, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception ("A handler with this name already exists.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void UnregisterJSHandler (string name)
|
||||
{
|
||||
if (functions.Contains (name))
|
||||
{
|
||||
functions.Remove (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfRangeException ("A function with this name has not been registered.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public delegate string ClrCall (string[] args);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* InvalidJSArgumentException.cs - The exception to be thrown when an argument from a call from JavaScript is invalid
|
||||
*
|
||||
* Authors:
|
||||
* Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2005 Michael Hutchinson
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace AspNetEdit.JSCall
|
||||
{
|
||||
public class InvalidJSArgumentException : Exception
|
||||
{
|
||||
public InvalidJSArgumentException (string function, int argument, Exception e)
|
||||
:base ("Invalid argument " + argument.ToString () + " in JavaScript call to \"" + function + "\".", e)
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidJSArgumentException (string function, int argument)
|
||||
:base ("Invalid argument " + argument.ToString () + " in JavaScript call to \"" + function + "\".")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
//
|
||||
// AssemblyInfo.cs.in for jscall.dll in aspnetedit
|
||||
//
|
||||
// Authors:
|
||||
// Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
//
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: AssemblyTitle ("AspNetEdit JSCall")]
|
||||
[assembly: AssemblyDescription ("JSCall library for AspNetEdit Graphical ASP.NET Editor ")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AspNetEdit")]
|
||||
[assembly: AssemblyCopyright ("Copyright © 2005 Michael Hutchinson")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
|
||||
[assembly: AssemblyVersion("@VERSION@")]
|
||||
[assembly: AssemblyFileVersion("@VERSION@")]
|
|
@ -1,17 +0,0 @@
|
|||
2006-06-24 Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
|
||||
* jscallglue/jscallglue.cpp: Fix build on Gecko 1.8+ browsers. Not a
|
||||
long-term solution -- need to re-work Mozilla string conversions to use
|
||||
the new frozen interfaces, but that will break backwards compatibility.
|
||||
|
||||
2006-06-14 Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
|
||||
* AspNetEdit.JSCall/CommandManager.cs: Null input checking to avoid
|
||||
segfaults, general cleanup.
|
||||
|
||||
2006-06-14 Chris Howie <cdhowie@nerdshack.com>
|
||||
|
||||
* jscallglue/jscallglue.cpp,
|
||||
AspNetEdit.JSCall/CommandManager.cs:
|
||||
|
||||
Add a method "JSEval" to execute arbitrary JavaScript in the browser.
|
|
@ -1,29 +0,0 @@
|
|||
SUBDIRS = jscallglue
|
||||
|
||||
ASSEMBLY_NAME = jscall
|
||||
ASSEMBLY = $(top_builddir)/build/lib/$(ASSEMBLY_NAME).dll
|
||||
TARGET = $(ASSEMBLY)
|
||||
|
||||
jscalldir=$(pkglibdir)
|
||||
jscall_SCRIPTS = $(ASSEMBLY)
|
||||
jscall_DATA = $(ASSEMBLY).mdb
|
||||
|
||||
JSCALL_CSFILES = \
|
||||
$(srcdir)/AssemblyInfo.cs \
|
||||
$(srcdir)/AspNetEdit.JSCall/CommandManager.cs \
|
||||
$(srcdir)/AspNetEdit.JSCall/InvalidJSArgumentException.cs
|
||||
|
||||
JSCALL_REFERENCES = \
|
||||
$(GTKSHARP_LIBS) \
|
||||
$(GECKOSHARP_LIBS)
|
||||
|
||||
|
||||
$(ASSEMBLY): $(JSCALL_CSFILES)
|
||||
$(MCS) $(MCS_OPTIONS) $(JSCALL_REFERENCES) -debug -target:library -out:$@ $(JSCALL_CSFILES)
|
||||
|
||||
$(ASSEMBLY).mdb: $(ASSEMBLY)
|
||||
|
||||
all: $(ASSEMBLY)
|
||||
|
||||
EXTRA_DIST = $(JSCALL_CSFILES) $(srcdir)/README $(srcdir)/Resources/JSCall.js
|
||||
CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb
|
|
@ -1,25 +0,0 @@
|
|||
INTRODUCTION
|
||||
============
|
||||
This is the AspNetEdit.JSGlue layer for calling C# functions from JavaScript in a Gecko# control, and vice versa. It should work with any .NET language but I've referrred to C# for simplicity. I don't expect many people to use this, so the documentation is little more than minimal; please contact me <m.j.hutchinson@gmail.com> if you need help working out how it works.
|
||||
|
||||
BUILDING
|
||||
========
|
||||
Use automake (./autogen.sh --prefix=/usr/local) at the application level.
|
||||
|
||||
USAGE
|
||||
=====
|
||||
On the CLR side of things, create an instance of AspNetEdit.JSGlue.CommandManager by passing the constructor the Gecko# control. This object has the following methods:
|
||||
RegisterJSHandler(string name, ClrCall handler)
|
||||
Register a ClrCall delegate as the handler when JS calls the named 'name' function.
|
||||
UnregisterJSHandler(string name)
|
||||
Unregister the 'name' function.
|
||||
JSCall(string function, string returnTo, string[] args)
|
||||
Call the 'function' JS function, with 'returnTo' as the callback for any return value. Arguments as a string array.
|
||||
|
||||
On the JS side, load the JSGlue.js file into your document and call JSGlueInit(). You then have the following functions available, mirroring the C# functions but a bit more "javascripty".
|
||||
JSGluePlaceClrCall(fn, returnTo, args)
|
||||
Call the 'fn' C# function, with 'returnTo' as the callback for any return value. Arguments as a string array.
|
||||
JSGlueRegisterClrHandler(n, fn)
|
||||
Register a the 'fn' function as the handler when C# calls the named 'n' function.
|
||||
JSGlueUnregisterClrHandler()
|
||||
Unregister the 'name' function.
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* JSCall.js - The JS side of the JSCall Gecko#/C# glue layer
|
||||
*
|
||||
* Authors:
|
||||
* Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2005 Michael Hutchinson
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
var JSCallFunctions;
|
||||
var delimiter = unescape ("%ea");
|
||||
|
||||
function JSCallInit()
|
||||
{
|
||||
JSCallFunctions = Array();
|
||||
|
||||
if (document.getElementsByTagName("jscall").length == 0) {
|
||||
el = document.createElement("jscall");
|
||||
document.documentElement.appendChild(el);
|
||||
}
|
||||
|
||||
if (document.getElementsByTagName("jscall").length != 1) {
|
||||
throw "Error: the document already contains a <jscall> element";
|
||||
}
|
||||
|
||||
el = document.getElementsByTagName("jscall")[0];
|
||||
el.addEventListener( "DOMNodeInserted", JSCallHandler, false );
|
||||
|
||||
//JSCallRegisterClrHandler("Redo", Redo);
|
||||
}
|
||||
|
||||
|
||||
//function Redo()
|
||||
//{
|
||||
// alert("Yay!");
|
||||
//}
|
||||
|
||||
|
||||
function JSCallHandler(e)
|
||||
{
|
||||
if ( e.target.nodeName == "infunction" && e.target.nodeType == 1 ){
|
||||
fn = e.target.attributes[0].value;
|
||||
returnTo = e.target.attributes[1].value;
|
||||
args = e.target.attributes[2].value.split(delimiter);
|
||||
|
||||
try {
|
||||
if(JSCallFunctions[fn]) {
|
||||
f = JSCallFunctions[fn];
|
||||
result = f(args);
|
||||
}
|
||||
else {
|
||||
throw "JSCall: The '"+fn+"' function has not been registered";
|
||||
}
|
||||
|
||||
|
||||
if (returnTo.length != 0) {
|
||||
JSCallPlaceClrCall(returnTo, "", new Array(result));
|
||||
}
|
||||
|
||||
}
|
||||
catch(e) {
|
||||
alert(e)
|
||||
}
|
||||
e.target.parentNode.removeChild(e.target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function JSCallPlaceClrCall(fn, returnTo, args) {
|
||||
str = "JSCall" + delimiter + fn + delimiter + returnTo + delimiter;
|
||||
|
||||
if (args && args.length > 0)
|
||||
{
|
||||
str += args.join(delimiter);
|
||||
}
|
||||
document.title= str;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function JSCallUnregisterClrHandler() {
|
||||
if(JSCallFunctions[n]) {
|
||||
delete JSCallFunctions[n];
|
||||
}
|
||||
else {
|
||||
throw "Function with that name not registered";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function JSCallRegisterClrHandler(n, fn) {
|
||||
if((typeof fn) != "function") {
|
||||
throw "The fn argument must be a function";
|
||||
}
|
||||
if(JSCallFunctions[n]) {
|
||||
throw "Function with that name already registered";
|
||||
}
|
||||
else {
|
||||
JSCallFunctions[n] = fn;
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<Project name="jscall" fileversion="2.0" newfilesearch="OnLoad" language="C#" clr-version="Net_1_1" ctype="DotNetProject">
|
||||
<Configurations active="Debug">
|
||||
<Configuration name="Debug" ctype="DotNetProjectConfiguration">
|
||||
<Output directory="../../build/lib" assembly="jscall" />
|
||||
<Build debugmode="True" target="Library" />
|
||||
<Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_1_1" />
|
||||
<CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
|
||||
</Configuration>
|
||||
<Configuration name="Release" ctype="DotNetProjectConfiguration">
|
||||
<Output directory="../../build/lib" assembly="jscall" />
|
||||
<Build debugmode="False" target="Library" />
|
||||
<Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_1_1" />
|
||||
<CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<DeploymentInformation strategy="File">
|
||||
<excludeFiles>
|
||||
<ExcludeFile file="./AssemblyInfo.cs.in" />
|
||||
<ExcludeFile file="./ChangeLog" />
|
||||
<ExcludeFile file="./Resources/ChangeLog" />
|
||||
<ExcludeFile file="./jscallglue/ChangeLog" />
|
||||
<ExcludeFile file="./AspNetEdit.JSCall/ChangeLog" />
|
||||
</excludeFiles>
|
||||
</DeploymentInformation>
|
||||
<Contents>
|
||||
<File name="./AssemblyInfo.cs" subtype="Code" buildaction="Compile" />
|
||||
<File name="./AssemblyInfo.cs.in" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./README" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./AspNetEdit.JSCall/CommandManager.cs" subtype="Code" buildaction="Compile" />
|
||||
<File name="./AspNetEdit.JSCall/InvalidJSArgumentException.cs" subtype="Code" buildaction="Compile" />
|
||||
<File name="./Resources/JSCall.js" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./jscallglue/README" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./jscallglue/jscallglue.cpp" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./ChangeLog" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./AspNetEdit.JSCall/ChangeLog" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./Resources/ChangeLog" subtype="Code" buildaction="Exclude" />
|
||||
<File name="./jscallglue/ChangeLog" subtype="Code" buildaction="Exclude" />
|
||||
</Contents>
|
||||
<References>
|
||||
<ProjectReference type="Gac" localcopy="True" refto="System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.6.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
<ProjectReference type="Gac" localcopy="True" refto="glib-sharp, Version=2.6.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
<ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.6.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
<ProjectReference type="Gac" localcopy="True" refto="gecko-sharp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=ccf7d78a55e9f021" />
|
||||
<ProjectReference type="Gac" localcopy="True" refto="atk-sharp, Version=2.6.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
</References>
|
||||
</Project>
|
|
@ -1,16 +0,0 @@
|
|||
jscallgluedir=$(pkglibdir)
|
||||
dllfile = $(top_builddir)/build/lib/libjscallglue.dll.so
|
||||
jscallglue_SCRIPTS = $(dllfile)
|
||||
|
||||
CXXFLAGS = -shared -g -fPIC -fno-rtti $(JSGLUEDEPS_CFLAGS)
|
||||
|
||||
LDFLAGS = $(JSGLUEDEPS_CFLAGS)
|
||||
|
||||
all: $(dllfile)
|
||||
|
||||
$(dllfile): jscallglue.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
CLEANFILES = $(dllfile)
|
||||
|
||||
EXTRA_DIST = README
|
|
@ -1,22 +0,0 @@
|
|||
The AspNetEdit XPCOM DOM Wrappers
|
||||
=================================
|
||||
A word of warning - this is a bit hacky, but will have to do until someone comes up with an XPConnect interface for Mono. The aim for now is to use a minimum of Gtk and XPCOM interop code to reuse existing components and simplify debugging.
|
||||
|
||||
We have two functions, PlaceFunctionCall and CollectFunctionCall. The document must contain a single node in the root called <aspnetcomm>, which contains the data to be communicated between C# and JavaScript, and these functions modify and read its contents.
|
||||
|
||||
The mechanism of invoking a C# method from JavaScript is as follows:
|
||||
1. A JavaScript function representing the C# method is called. If it has a return value, it registers a callback function with a handler.
|
||||
2. It calls a helper function that puts the data in the <aspnetcomm> node and sets the window 'status'. As Gecko# has no status bar this misuse doesn't adversely affect anything and is not visible to the user.
|
||||
3. The modified Gecko# control catches the ECMAStatus event that is raised, reads and deletes the function call from the DOM using CollectFunctionCall, and calls the relevant C# method.
|
||||
4. If there is a return value, a callback is placed in the reverse direction.
|
||||
|
||||
The reverse call is simple too:
|
||||
1. A C# method of the modified Gecko# control representing a JavaScript function is called, and it writes to the DOM using PlaceFunctionCall. If it has a return value, it registers a callback delegate with a handler.
|
||||
2. This raises the DOMNodeInserted event in JavaScript, which is caught by a handler.
|
||||
3. The handler passes the arguments to the appropriate function.
|
||||
4. If there is a return value, a callback is placed in the reverse direction.
|
||||
|
||||
Outbound (JS->C#) method calls are represented as a child of <aspnetcomm>, and are of the following form:
|
||||
<outfunction call="functionName" args="encodedListOfArguments" >
|
||||
Inbound calls are of the form:
|
||||
<infunction call="functionName" args="encodedListOfArguments" >
|
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
* jscallglue.cpp - XPCOM DOM interop for communication between JavaScript and Mono/Gecko#
|
||||
*
|
||||
* Authors:
|
||||
* Michael Hutchinson <m.j.hutchinson@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2005 Michael Hutchinson
|
||||
*
|
||||
* This sourcecode is licenced under The MIT License:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//FIXME: uses internal string functions, so have to define this in newer Mozillas
|
||||
//But we can only migrate to nsStringAPI.h in FF1.5/Mozilla 1.7+
|
||||
#define MOZILLA_INTERNAL_API
|
||||
|
||||
#include <gtkmozembed.h>
|
||||
#include <gtkmozembed_internal.h>
|
||||
|
||||
#include <nsCOMPtr.h>
|
||||
#include <nsString.h>
|
||||
#include <nsIWebBrowser.h>
|
||||
#include <nsIDOMWindow.h>
|
||||
#include <nsIDOMDocument.h>
|
||||
#include <nsIDOMElement.h>
|
||||
#include <nsIDOMNode.h>
|
||||
#include <nsIDOMNodeList.h>
|
||||
|
||||
#include <nsIDOMHTMLScriptElement.h>
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int PlaceFunctionCall(GtkMozEmbed *embed, const PRUnichar *call, const PRUnichar *returnto, const PRUnichar *args);
|
||||
int ExecuteScript(GtkMozEmbed *embed, const PRUnichar *script);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Gets the browser's IDomDocument.
|
||||
*/
|
||||
nsCOMPtr<nsIDOMDocument> GetIDOMDocument(GtkMozEmbed *embed)
|
||||
{
|
||||
//Get browser
|
||||
nsCOMPtr<nsIWebBrowser> browser;
|
||||
gtk_moz_embed_get_nsIWebBrowser(embed, getter_AddRefs(browser));
|
||||
if(!browser) return NULL;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
browser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
domWindow->GetDocument(getter_AddRefs(domDocument));
|
||||
return domDocument;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Places a <outfunction call="..." args="..." returnto="..." />
|
||||
function call element in the <jscall> element.
|
||||
*/
|
||||
int PlaceFunctionCall(GtkMozEmbed *embed, const PRUnichar *call, const PRUnichar *returnto, const PRUnichar *args)
|
||||
{
|
||||
nsresult result;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc = GetIDOMDocument(embed);
|
||||
|
||||
if(doc == NULL) return 1;
|
||||
|
||||
//get the "jscall" node
|
||||
nsCOMPtr<nsIDOMNodeList> nodes;
|
||||
result = doc->GetElementsByTagName(NS_ConvertUTF8toUTF16("jscall"), getter_AddRefs(nodes));
|
||||
if(NS_FAILED(result) || !nodes) return 2;
|
||||
|
||||
PRUint32 length = 0;
|
||||
result = nodes -> GetLength(&length);
|
||||
if(NS_FAILED(result)) return 3;
|
||||
if(length != 1) return 4;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> jscall;
|
||||
result = nodes->Item(0, getter_AddRefs(jscall));
|
||||
if(NS_FAILED(result) || !jscall) return 5;
|
||||
|
||||
//add an "infunction" node
|
||||
nsCOMPtr<nsIDOMElement> infunction;
|
||||
result = doc->CreateElement(NS_ConvertUTF8toUTF16("infunction"), getter_AddRefs(infunction));
|
||||
if(NS_FAILED(result) || !infunction) return 6;
|
||||
|
||||
//add the properties
|
||||
result = infunction->SetAttribute(NS_ConvertUTF8toUTF16("call"), nsDependentString(call));
|
||||
result = infunction->SetAttribute(NS_ConvertUTF8toUTF16("returnto"), nsDependentString(returnto));
|
||||
result = infunction->SetAttribute(NS_ConvertUTF8toUTF16("args"), nsDependentString(args));
|
||||
if(NS_FAILED(result)) return 7;
|
||||
|
||||
//append it to the jscall node
|
||||
nsCOMPtr<nsIDOMNode> domNodeInfunction = do_QueryInterface(infunction);
|
||||
if(!domNodeInfunction) return 8;
|
||||
nsCOMPtr<nsIDOMNode> outchild;
|
||||
result = jscall->AppendChild(domNodeInfunction, getter_AddRefs(outchild));
|
||||
if(NS_FAILED(result) || !jscall) return 9;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Inspiration from
|
||||
// http://kmeleon.cvs.sourceforge.net/kmeleon/k-meleon/BrowserViewUtils.cpp?revision=1.53&view=markup
|
||||
int ExecuteScript(GtkMozEmbed *embed, const PRUnichar *script)
|
||||
{
|
||||
nsresult result;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc = GetIDOMDocument(embed);
|
||||
|
||||
if (doc == NULL)
|
||||
return 1;
|
||||
|
||||
// Create the script node
|
||||
nsCOMPtr<nsIDOMElement> scriptDOMElement;
|
||||
result = doc->CreateElement(NS_ConvertUTF8toUTF16("script"), getter_AddRefs(scriptDOMElement));
|
||||
if (NS_FAILED(result) || !scriptDOMElement)
|
||||
return 2;
|
||||
|
||||
// and the content
|
||||
nsCOMPtr<nsIDOMHTMLScriptElement> scriptE = do_QueryInterface(scriptDOMElement);
|
||||
if (!scriptE)
|
||||
return 3;
|
||||
|
||||
scriptE->SetText(nsDependentString(script));
|
||||
scriptE->SetType(NS_ConvertUTF8toUTF16("text/javascript"));
|
||||
|
||||
// find the body node.
|
||||
nsCOMPtr<nsIDOMElement> body;
|
||||
result = doc->GetDocumentElement(getter_AddRefs(body));
|
||||
if (NS_FAILED(result) || !body)
|
||||
return 4;
|
||||
|
||||
// add the element to the body
|
||||
nsCOMPtr<nsIDOMNode> unused;
|
||||
result = body->AppendChild(scriptE, getter_AddRefs(unused));
|
||||
if (NS_FAILED(result))
|
||||
return 5;
|
||||
|
||||
// gecko has executed the element, we can remove it now
|
||||
result = body->RemoveChild(scriptE, getter_AddRefs(unused));
|
||||
|
||||
return 0;
|
||||
}
|
Загрузка…
Ссылка в новой задаче