538 lines
19 KiB
C++
538 lines
19 KiB
C++
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is mozilla.org.
|
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Mark Hammond (initial development)
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
// "Module" is such an overloaded term! This file serves as both the xpcom
|
|
// component module and the implicit Python "_nsdom" module. The _nsdom module
|
|
// is implicit in that it is automatically imported as this component
|
|
// initializes even though it does not exist as a regular python module.
|
|
|
|
#include "nsIGenericFactory.h"
|
|
#include "nsPyRuntime.h"
|
|
|
|
#include "nsPyContext.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsIScriptGlobalObject.h"
|
|
#include "nsIScriptObjectPrincipal.h"
|
|
#include "nsIAtomService.h"
|
|
#include "nsIEventListenerManager.h"
|
|
#include "nsIScriptTimeoutHandler.h"
|
|
#include "nsPIDOMEventTarget.h"
|
|
#include "nsIArray.h"
|
|
#include "jscntxt.h"
|
|
#include "nsPIDOMWindow.h"
|
|
#include "nsDOMScriptObjectHolder.h"
|
|
|
|
// just for constants...
|
|
#include "nsIScriptContext.h"
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPythonRuntime)
|
|
|
|
static const nsModuleComponentInfo components[] = {
|
|
{"Python Script Language", NS_SCRIPT_LANGUAGE_PYTHON_CID,
|
|
NS_SCRIPT_LANGUAGE_PYTHON_CONTRACTID_NAME,
|
|
nsPythonRuntimeConstructor,},
|
|
// And again with the contract ID including the language ID
|
|
{"Python Script Language", NS_SCRIPT_LANGUAGE_PYTHON_CID,
|
|
NS_SCRIPT_LANGUAGE_PYTHON_CONTRACTID_ID,
|
|
nsPythonRuntimeConstructor,},
|
|
};
|
|
|
|
// Implementation of the module object.
|
|
NS_IMPL_NSGETMODULE(nsPyDOMModule, components)
|
|
|
|
// The Python '_nsdom' module
|
|
////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
PyObject *PyJSExec(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obGlobal;
|
|
char *code;
|
|
char *url = "<python JSExec script>";
|
|
PRUint32 lineNo = 0;
|
|
PRUint32 version = 0;
|
|
if (!PyArg_ParseTuple(args, "Os|sii", &obGlobal, &code, &url, &lineNo, &version))
|
|
return NULL;
|
|
nsCOMPtr<nsISupports> isup;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obGlobal,
|
|
NS_GET_IID(nsISupports),
|
|
getter_AddRefs(isup),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal = do_QueryInterface(isup);
|
|
if (scriptGlobal == nsnull)
|
|
return PyErr_Format(PyExc_TypeError, "Object is not an nsIScriptGlobal");
|
|
nsIScriptContext *scriptContext =
|
|
scriptGlobal->GetScriptContext(nsIProgrammingLanguage::JAVASCRIPT);
|
|
if (!scriptContext)
|
|
return PyErr_Format(PyExc_RuntimeError, "No javascript context available");
|
|
|
|
// get the principal
|
|
nsIPrincipal *principal = nsnull;
|
|
nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(scriptGlobal);
|
|
if (globalData)
|
|
principal = globalData->GetPrincipal();
|
|
if (!principal)
|
|
return PyErr_Format(PyExc_RuntimeError, "No nsIPrincipal available");
|
|
|
|
nsresult rv;
|
|
void *scope = scriptGlobal->GetScriptGlobal(nsIProgrammingLanguage::JAVASCRIPT);
|
|
nsScriptObjectHolder scriptObject(scriptContext);
|
|
JSContext *ctx = (JSContext *)scriptContext->GetNativeContext();
|
|
|
|
nsAutoString str;
|
|
PRBool bIsUndefined;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
rv = scriptContext->CompileScript( NS_ConvertASCIItoUTF16(code).get(),
|
|
strlen(code),
|
|
scope,
|
|
principal, // no principal??
|
|
url,
|
|
lineNo,
|
|
version,
|
|
scriptObject);
|
|
if (NS_SUCCEEDED(rv) && scriptObject)
|
|
rv = scriptContext->ExecuteScript(scriptObject, scope, &str,
|
|
&bIsUndefined);
|
|
Py_END_ALLOW_THREADS
|
|
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
return Py_BuildValue("NN", PyObject_FromNSString(str), PyBool_FromLong(bIsUndefined));
|
|
// XXX - cleanup scriptObject???
|
|
}
|
|
|
|
// Various helpers to avoid exposing non-scriptable interfaces when we only
|
|
// need one or 2 functions.
|
|
static PyObject *PyIsOuterWindow(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obTarget;
|
|
if (!PyArg_ParseTuple(args, "O", &obTarget))
|
|
return NULL;
|
|
|
|
// target
|
|
nsCOMPtr<nsPIDOMWindow> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsPIDOMWindow),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
return PyBool_FromLong(target->IsOuterWindow());
|
|
}
|
|
|
|
static PyObject *PyGetCurrentInnerWindow(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obTarget;
|
|
if (!PyArg_ParseTuple(args, "O", &obTarget))
|
|
return NULL;
|
|
|
|
// target
|
|
nsCOMPtr<nsPIDOMWindow> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsPIDOMWindow),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
// Use the script global object to fetch the context.
|
|
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(target));
|
|
if (!sgo)
|
|
return PyErr_Format(PyExc_ValueError, "Object does not supports nsIScriptGlobalObject");
|
|
nsIScriptContext *ctx = sgo->GetScriptContext(nsIProgrammingLanguage::PYTHON);
|
|
if (!ctx)
|
|
return PyErr_Format(PyExc_ValueError, "Object not initialized for Python");
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> innerGlobal(
|
|
do_QueryInterface(target->GetCurrentInnerWindow()));
|
|
if (!innerGlobal)
|
|
return PyErr_Format(PyExc_ValueError, "Result object does not supports nsIScriptGlobalObject");
|
|
nsPythonContext *pyctx = (nsPythonContext *)ctx;
|
|
return pyctx->PyObject_FromInterface(innerGlobal,
|
|
NS_GET_IID(nsIScriptGlobalObject));
|
|
}
|
|
|
|
static PyObject *PySetTimeoutOrInterval(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obTarget;
|
|
PyObject *obHandler;
|
|
PyObject *obArgs;
|
|
int interval;
|
|
int isInterval;
|
|
if (!PyArg_ParseTuple(args, "OiOO!i:SetTimeoutOrInterval", &obTarget,
|
|
&interval, &obHandler,
|
|
&PyTuple_Type, &obArgs,
|
|
&isInterval))
|
|
return NULL;
|
|
|
|
if (!PySequence_Check(obArgs))
|
|
return PyErr_Format(PyExc_TypeError, "args param must be a sequence (got %s)",
|
|
obArgs->ob_type->tp_name);
|
|
|
|
PyObject *funObject = NULL;
|
|
nsAutoString strExpr;
|
|
if (PyCallable_Check(obHandler)) {
|
|
funObject = obHandler;
|
|
} else {
|
|
if (!PyObject_AsNSString(obHandler, strExpr))
|
|
return NULL;
|
|
}
|
|
|
|
// target
|
|
nsCOMPtr<nsPIDOMWindow> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsPIDOMWindow),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
nsCOMPtr<nsIScriptTimeoutHandler> handler;
|
|
nsresult rv;
|
|
rv = CreatePyTimeoutHandler(strExpr, funObject, obArgs,
|
|
getter_AddRefs(handler));
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
PRInt32 ret;
|
|
Py_BEGIN_ALLOW_THREADS;
|
|
rv = target->SetTimeoutOrInterval(handler, interval, isInterval, &ret);
|
|
Py_END_ALLOW_THREADS;
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
return PyInt_FromLong(ret);
|
|
}
|
|
|
|
static PyObject *PyClearTimeoutOrInterval(PyObject *self, PyObject *args)
|
|
{
|
|
int tid;
|
|
PyObject *obTarget;
|
|
if (!PyArg_ParseTuple(args, "Oi", &obTarget, &tid))
|
|
return NULL;
|
|
|
|
// target
|
|
nsCOMPtr<nsPIDOMWindow> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsPIDOMWindow),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
nsresult rv;
|
|
Py_BEGIN_ALLOW_THREADS;
|
|
rv = target->ClearTimeoutOrInterval((PRInt32)tid);
|
|
Py_END_ALLOW_THREADS;
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
// Avoid exposing the entire non-scriptable event listener interface
|
|
// We are exposing:
|
|
//
|
|
//nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
|
|
// nsIAtom *aName,
|
|
// const nsAString& aBody,
|
|
// PRUint32 aLanguage,
|
|
// PRBool aDeferCompilation,
|
|
// PRBool aPermitUntrustedEvents)
|
|
//
|
|
// Implementation of the above seems strange - if !aDeferCompilation then
|
|
// aBody is ignored (presumably to later be fetched via GetAttr
|
|
|
|
static PyObject *PyAddScriptEventListener(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obTarget, *obBody;
|
|
char *name;
|
|
int lang = nsIProgrammingLanguage::PYTHON;
|
|
int defer, untrusted;
|
|
if (!PyArg_ParseTuple(args, "OsOii|i", &obTarget, &name, &obBody,
|
|
&defer, &untrusted, &lang))
|
|
return NULL;
|
|
|
|
// target
|
|
nsCOMPtr<nsISupports> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsISupports),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
nsAutoString body;
|
|
if (!PyObject_AsNSString(obBody, body))
|
|
return NULL;
|
|
|
|
// The receiver, to get the manager.
|
|
nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(target));
|
|
if (!piTarget) return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
|
|
|
|
nsCOMPtr<nsIEventListenerManager> manager;
|
|
piTarget->GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
|
if (!manager) return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
|
|
|
|
// avoid do_GetAtom - its not part of the XPCOM glue.
|
|
nsresult rv;
|
|
nsCOMPtr<nsIAtomService> atomService =
|
|
do_GetService(NS_ATOMSERVICE_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
nsCOMPtr<nsIAtom> atom;
|
|
rv = atomService->GetAtomUTF8(name, getter_AddRefs(atom));
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
rv = manager->AddScriptEventListener(target, atom, body, lang, defer,
|
|
untrusted);
|
|
Py_END_ALLOW_THREADS
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
// NS_IMETHOD RegisterScriptEventListener(nsIScriptContext *aContext,
|
|
// void *aScopeObject,
|
|
// nsISupports *aObject,
|
|
// nsIAtom* aName) = 0;
|
|
static PyObject *PyRegisterScriptEventListener(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obTarget, *obGlobal, *obScope;
|
|
char *name;
|
|
if (!PyArg_ParseTuple(args, "OOOs", &obGlobal, &obScope, &obTarget, &name))
|
|
return NULL;
|
|
|
|
nsCOMPtr<nsISupports> isup;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obGlobal,
|
|
NS_GET_IID(nsISupports),
|
|
getter_AddRefs(isup),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal = do_QueryInterface(isup);
|
|
if (scriptGlobal == nsnull)
|
|
return PyErr_Format(PyExc_TypeError, "Object is not an nsIScriptGlobal");
|
|
nsIScriptContext *scriptContext =
|
|
scriptGlobal->GetScriptContext(nsIProgrammingLanguage::PYTHON);
|
|
if (!scriptContext)
|
|
return PyErr_Format(PyExc_RuntimeError, "Can't find my context??");
|
|
|
|
// target
|
|
nsCOMPtr<nsISupports> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsISupports),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
// sob - I don't quite understand this, but things get upset when
|
|
// an outer window gets the event.
|
|
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(target));
|
|
if (win != nsnull && win->IsOuterWindow()) {
|
|
target = win->GetCurrentInnerWindow();
|
|
}
|
|
// The receiver, to get the manager.
|
|
nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(target));
|
|
if (!piTarget) return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
|
|
|
|
nsCOMPtr<nsIEventListenerManager> manager;
|
|
piTarget->GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
|
if (!manager) return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIAtomService> atomService =
|
|
do_GetService(NS_ATOMSERVICE_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
nsCOMPtr<nsIAtom> atom;
|
|
rv = atomService->GetAtomUTF8(name, getter_AddRefs(atom));
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
rv = manager->RegisterScriptEventListener(scriptContext, obScope,
|
|
target, atom);
|
|
Py_END_ALLOW_THREADS
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
// NS_IMETHOD CompileScriptEventListener(nsIScriptContext *aContext,
|
|
// void *aScopeObject,
|
|
// nsISupports *aObject,
|
|
// nsIAtom* aName,
|
|
// PRBool *aDidCompile) = 0;
|
|
static PyObject *PyCompileScriptEventListener(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *obTarget, *obGlobal, *obScope;
|
|
char *name;
|
|
if (!PyArg_ParseTuple(args, "OOOs", &obGlobal, &obScope, &obTarget, &name))
|
|
return NULL;
|
|
|
|
nsCOMPtr<nsISupports> isup;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obGlobal,
|
|
NS_GET_IID(nsISupports),
|
|
getter_AddRefs(isup),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal = do_QueryInterface(isup);
|
|
if (scriptGlobal == nsnull)
|
|
return PyErr_Format(PyExc_TypeError, "Object is not an nsIScriptGlobal");
|
|
nsIScriptContext *scriptContext =
|
|
scriptGlobal->GetScriptContext(nsIProgrammingLanguage::PYTHON);
|
|
if (!scriptContext)
|
|
return PyErr_Format(PyExc_RuntimeError, "Can't find my context??");
|
|
|
|
// target
|
|
nsCOMPtr<nsISupports> target;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(
|
|
obTarget,
|
|
NS_GET_IID(nsISupports),
|
|
getter_AddRefs(target),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
// sob - I don't quite understand this, but things get upset when
|
|
// an outer window gets the event.
|
|
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(target));
|
|
if (win != nsnull && win->IsOuterWindow()) {
|
|
target = win->GetCurrentInnerWindow();
|
|
}
|
|
// The receiver, to get the manager.
|
|
nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(target));
|
|
if (!piTarget) return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
|
|
|
|
nsCOMPtr<nsIEventListenerManager> manager;
|
|
piTarget->GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
|
if (!manager) return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIAtomService> atomService =
|
|
do_GetService(NS_ATOMSERVICE_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
nsCOMPtr<nsIAtom> atom;
|
|
rv = atomService->GetAtomUTF8(name, getter_AddRefs(atom));
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
|
|
PRBool didCompile;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
rv = manager->CompileScriptEventListener(scriptContext, obScope,
|
|
target, atom, &didCompile);
|
|
Py_END_ALLOW_THREADS
|
|
if (NS_FAILED(rv))
|
|
return PyXPCOM_BuildPyException(rv);
|
|
return PyBool_FromLong(didCompile);
|
|
}
|
|
|
|
static PyObject *PyMakeArray(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *ob;
|
|
if (!PyArg_ParseTuple(args, "O!:MakeArray", &PyTuple_Type, &ob))
|
|
return NULL;
|
|
|
|
nsCOMPtr<nsIArray> array;
|
|
nsresult rv = NS_CreatePyArgv(ob, getter_AddRefs(array));
|
|
if (NS_FAILED(rv) || array == nsnull)
|
|
return PyXPCOM_BuildPyException(rv);
|
|
return PyObject_FromNSInterface(array, NS_GET_IID(nsIArray));
|
|
}
|
|
|
|
static PyObject *PyMakeDOMObject(PyObject *self, PyObject *args)
|
|
{
|
|
PyObject *ob, *obContext;
|
|
if (!PyArg_ParseTuple(args, "OO:MakeDOMObject", &obContext, &ob))
|
|
return NULL;
|
|
|
|
nsCOMPtr<nsISupports> sup;
|
|
if (!Py_nsISupports::InterfaceFromPyObject(ob, NS_GET_IID(nsISupports),
|
|
getter_AddRefs(sup),
|
|
PR_FALSE, PR_FALSE))
|
|
return NULL;
|
|
|
|
return PyObject_FromNSDOMInterface(obContext, sup, NS_GET_IID(nsISupports));
|
|
}
|
|
|
|
static struct PyMethodDef methods[]=
|
|
{
|
|
{"JSExec", PyJSExec, 1},
|
|
{"AddScriptEventListener", PyAddScriptEventListener, 1},
|
|
{"RegisterScriptEventListener", PyRegisterScriptEventListener, 1},
|
|
{"CompileScriptEventListener", PyCompileScriptEventListener, 1},
|
|
{"GetCurrentInnerWindow", PyGetCurrentInnerWindow, 1},
|
|
{"IsOuterWindow", PyIsOuterWindow, 1},
|
|
{"SetTimeoutOrInterval", PySetTimeoutOrInterval, 1},
|
|
{"ClearTimeoutOrInterval", PyClearTimeoutOrInterval, 1},
|
|
{"MakeArray", PyMakeArray, 1},
|
|
{"MakeDOMObject", PyMakeDOMObject, 1},
|
|
{ NULL }
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// The module init code.
|
|
//
|
|
#define REGISTER_IID(t) { \
|
|
PyObject *iid_ob = Py_nsIID::PyObjectFromIID(NS_GET_IID(t)); \
|
|
PyDict_SetItemString(dict, "IID_"#t, iid_ob); \
|
|
Py_DECREF(iid_ob); \
|
|
}
|
|
|
|
// *NOT* called by Python - this is not a regular Python module.
|
|
// Caller must ensure only called once!
|
|
void
|
|
init_nsdom() {
|
|
CEnterLeavePython _celp;
|
|
// Create the module and add the functions
|
|
PyObject *oModule = Py_InitModule("_nsdom", methods);
|
|
PyObject *dict = PyModule_GetDict(oModule);
|
|
REGISTER_IID(nsIScriptGlobalObject);
|
|
}
|