First cut at python breaking the JS grip on the DOM.

git-svn-id: svn://10.0.0.236/branches/DOM_AGNOSTIC_BRANCH@179621 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mhammond%skippinet.com.au
2005-09-04 13:23:30 +00:00
parent 066d447808
commit 008fd07a69
16 changed files with 1487 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
# ***** 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: author
#
# 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 *****
DEPTH =../../..
DIRS = \
src \
test \
$(NULL)
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
pyexecdir = @libdir@/python$(PYTHON_VER_DOTTED)/site-packages
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,36 @@
# todo - add license.
# The Python DOM ScriptLanguage implementation.
DEPTH=../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = pydom
IS_COMPONENT = 1
REQUIRES = pyxpcom xpcom string xpcom_obsolete dom widget $(NULL)
MOZILLA_INTERNAL_API = 1
FORCE_SHARED_LIB = 1
FORCE_USE_PIC = 1
LOCAL_INCLUDES = $(PYTHON_INCLUDES)
EXTRA_LIBS += $(PYTHON_LIBS) $(DIST)/lib/pyxpcom.lib
CPPSRCS = \
nsPyContext.cpp \
nsPyRuntime.cpp \
nsPyDOMModule.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk
CXXFLAGS += -DPYTHON_SO=\"libpython$(PYTHON_VER_DOTTED).so\"
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
clobber::
rm -f *.ilk

View File

@@ -0,0 +1,643 @@
/* ***** 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 (original author)
*
* 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 ***** */
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsITimer.h"
#include "nsIArray.h"
#include "prtime.h"
#include "nsString.h"
#include "nsPyContext.h"
#include "compile.h"
#include "eval.h"
static PRInt32 sContextCount;
#ifdef NS_DEBUG
class nsPyDOMObjectLeakStats
{
public:
nsPyDOMObjectLeakStats()
: mEventHandlerCount(0), mScriptObjectCount(0), mBindingCount(0) {}
~nsPyDOMObjectLeakStats()
{
printf("nsPyDOMObjectLeakStats lost object counts\n");
printf(" => mEventHandlerCount: % 10d\n", mEventHandlerCount);
printf(" => mScriptObjectCount: % 10d\n", mScriptObjectCount);
printf(" => mBindingCount: % 10d\n", mBindingCount);
}
PRInt32 mEventHandlerCount;
PRInt32 mScriptObjectCount;
PRInt32 mBindingCount;
};
static nsPyDOMObjectLeakStats gLeakStats;
#define PYLEAK_STAT_INCREMENT(_s) PR_AtomicIncrement(&gLeakStats.m ## _s ## Count)
#define PYLEAK_STAT_XINCREMENT(_what, _s) if (_what) PR_AtomicIncrement(&gLeakStats.m ## _s ## Count)
#define PYLEAK_STAT_DECREMENT(_s) PR_AtomicDecrement(&gLeakStats.m ## _s ## Count)
#define PYLEAK_STAT_XDECREMENT(_what, _s) if (_what) PR_AtomicDecrement(&gLeakStats.m ## _s ## Count)
#else
#define PYLEAK_STAT_INCREMENT(_s)
#define PYLEAK_STAT_XINCREMENT(_what, _s)
#define PYLEAK_STAT_DECREMENT(_s)
#define PYLEAK_STAT_XDECREMENT(_what, _s)
#endif
#ifndef NS_DEBUG
// non debug build store it once. Debug builds refetch, allowing someone
// to reload(mod) to get new versions)
static PyObject *delegateModule = NULL;
#endif
nsPythonContext::nsPythonContext()
: mGlobal(NULL)
{
++sContextCount;
mIsInitialized = PR_FALSE;
mNumEvaluations = 0;
mOwner = nsnull;
mScriptsEnabled = PR_TRUE;
mProcessingScriptTag=PR_FALSE;
}
nsPythonContext::~nsPythonContext()
{
// Unregister our "javascript.options.*" pref-changed callback.
// nsContentUtils::UnregisterPrefCallback(js_options_dot_str,
// JSOptionChangedCallback,
// this);
--sContextCount;
}
// QueryInterface implementation for nsPythonContext
NS_INTERFACE_MAP_BEGIN(nsPythonContext)
NS_INTERFACE_MAP_ENTRY(nsIScriptContext)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptContext)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsPythonContext)
NS_IMPL_RELEASE(nsPythonContext)
/*static*/ nsresult nsPythonContext::HandlePythonError()
{
// need to raise an exception
NS_WARNING("Python error");
PyErr_Print(); // for now.
return PyXPCOM_SetCOMErrorFromPyException();
}
nsresult
nsPythonContext::InitContext(nsIScriptGlobalObject *aGlobalObject)
{
// Make sure callers of this use
// WillInitializeContext/DidInitializeContext around this call?
// We don't really care though.
NS_ENSURE_TRUE(!mIsInitialized, NS_ERROR_ALREADY_INITIALIZED);
CEnterLeavePython _celp;
// Setup our global dict.
Py_XDECREF(mGlobal);
PyObject *obGlobal;
if (aGlobalObject) {
// must build the object with nsISupports, so it gets the automagic
// interface flattening (I guess that is a bug in pyxpcom?)
obGlobal = Py_nsISupports::PyObjectFromInterface(aGlobalObject,
NS_GET_IID(nsISupports),
PR_TRUE);
if (!obGlobal)
return HandlePythonError();
} else {
obGlobal = Py_None;
Py_INCREF(Py_None);
}
mGlobal = Py_BuildValue("{s:N}", "this", obGlobal);
if (!mGlobal)
return HandlePythonError();
// Add builtins to globals (not necessary if .py code does an exec ??)
PyObject *bimod = PyImport_ImportModule("__builtin__");
if (bimod == NULL || PyDict_SetItemString(mGlobal, "__builtins__", bimod) != 0) {
NS_ERROR("can't add __builtins__ to __main__");
return NS_ERROR_UNEXPECTED;
}
Py_DECREF(bimod);
return NS_OK;
}
nsresult
nsPythonContext::EvaluateStringWithValue(const nsAString& aScript,
void *aScopeObject,
nsIPrincipal *aPrincipal,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
void* aRetValue,
PRBool* aIsUndefined)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
if (!mScriptsEnabled) {
if (aIsUndefined) {
*aIsUndefined = PR_TRUE;
}
return NS_OK;
}
NS_ERROR("Not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsPythonContext::EvaluateString(const nsAString& aScript,
void *aScopeObject,
nsIPrincipal *aPrincipal,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
nsAString *aRetValue,
PRBool* aIsUndefined)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
if (!mScriptsEnabled) {
*aIsUndefined = PR_TRUE;
if (aRetValue) {
aRetValue->Truncate();
}
return NS_OK;
}
NS_ERROR("Not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsPythonContext::ExecuteScript(void* aScriptObject,
void *aScopeObject,
nsAString* aRetValue,
PRBool* aIsUndefined)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
if (!mScriptsEnabled) {
if (aIsUndefined) {
*aIsUndefined = PR_TRUE;
}
if (aRetValue) {
aRetValue->Truncate();
}
return NS_OK;
}
NS_ENSURE_TRUE(aScriptObject, NS_ERROR_NULL_POINTER);
NS_ASSERTION(aScopeObject == nsnull || aScopeObject == mGlobal,
"Global was changed??");
PyObject *pyScopeObject = (PyObject *)aScopeObject;
CEnterLeavePython _celp;
if (pyScopeObject) {
NS_ASSERTION(PyDict_Check(pyScopeObject), "aScopeObject globals not a dict?");
// sigh - I still don't understand mGlobal vs aScopeObject :(
NS_ASSERTION(pyScopeObject == mGlobal, "Scope is not the global?");
NS_ENSURE_TRUE(PyDict_Check(pyScopeObject), NS_ERROR_UNEXPECTED);
} else
pyScopeObject = mGlobal;
PyCodeObject *pyScriptObject = (PyCodeObject *)aScriptObject;
NS_ASSERTION(PyCode_Check(pyScriptObject), "aScriptObject not a code object?");
NS_ENSURE_TRUE(PyCode_Check(pyScriptObject), NS_ERROR_UNEXPECTED);
PyObject *ret = PyEval_EvalCode(pyScriptObject, pyScopeObject, NULL);
if (!ret)
return HandlePythonError();
// PyObject *obu = PyUnicode_FromObject(obRet);
// if (obRet)
// PyUnicode_AS_UNICODE(val_use)
Py_DECREF(ret);
return NS_OK;
}
nsresult
nsPythonContext::CompileScript(const PRUnichar* aText,
PRInt32 aTextLength,
void *aScopeObject,
nsIPrincipal *aPrincipal,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
void** aScriptObject)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
// XXX - todo - specify PyCF_SOURCE_IS_UTF8 in Py_CompileStringFlags
NS_ConvertUTF16toUTF8 cs(aText, aTextLength);
// XXX - need to instantiate a tokenizer and set its lineno member.
// ignore that for now.
// Python insists on \n between lines and a trailing \n. Fixup windows/mac
nsCAutoString source(cs); // hope this does copy-on-write
// Windows linebreaks: Map CRLF to LF:
source.ReplaceSubstring(NS_LITERAL_CSTRING("\r\n").get(),
NS_LITERAL_CSTRING("\n").get());
// Mac linebreaks: Map any remaining CR to LF:
source.ReplaceSubstring(NS_LITERAL_CSTRING("\r").get(),
NS_LITERAL_CSTRING("\n").get());
// trailing \n
source.Append(NS_LITERAL_CSTRING("\n"));
CEnterLeavePython _celp;
PyObject *co = Py_CompileString(source.get(), aURL, Py_file_input);
if (!co)
return HandlePythonError();
*aScriptObject = co;
PYLEAK_STAT_INCREMENT(ScriptObject);
return NS_OK;
}
nsresult
nsPythonContext::CompileEventHandler(nsIScriptBinding *aTarget, nsIAtom *aName,
const char *aEventName,
const nsAString& aBody,
const char *aURL, PRUint32 aLineNo,
PRBool aShared, void** aHandler)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
// shameless clone of above - let's see what happens before rationalizing
// XXX - todo - specify PyCF_SOURCE_IS_UTF8 in Py_CompileStringFlags
nsCAutoString cs;
CopyUTF16toUTF8(aBody, cs);
// XXX - need to instantiate a tokenizer and set its lineno member.
// ignore that for now.
// Python insists on \n between lines and a trailing \n. Fixup windows/mac
nsCAutoString source(cs); // hope this does copy-on-write
// Windows linebreaks: Map CRLF to LF:
source.ReplaceSubstring(NS_LITERAL_CSTRING("\r\n").get(),
NS_LITERAL_CSTRING("\n").get());
// Mac linebreaks: Map any remaining CR to LF:
source.ReplaceSubstring(NS_LITERAL_CSTRING("\r").get(),
NS_LITERAL_CSTRING("\n").get());
// trailing \n
source.Append(NS_LITERAL_CSTRING("\n"));
CEnterLeavePython _celp;
PyObject *co = Py_CompileString(source.get(), aURL, Py_file_input);
if (!co)
return HandlePythonError();
PYLEAK_STAT_INCREMENT(EventHandler);
*aHandler = co;
// If we were passed a handler, bind to it.
nsresult rv = NS_OK;
if (aTarget) {
NS_ASSERTION(aTarget->GetNativeObject() == nsnull, "Can't already have a native");
rv = BindCompiledEventHandler(aTarget, aName, *aHandler);
}
return rv;
}
nsresult
nsPythonContext::BindCompiledEventHandler(nsIScriptBinding *aTarget, nsIAtom *aName,
void *aHandler)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
NS_ASSERTION(aTarget->GetLanguage() == nsIProgrammingLanguage::PYTHON,
"Must be a Python binder!?");
nsPyScriptBinding *pyBinding = (nsPyScriptBinding *)aTarget;
NS_ASSERTION(pyBinding->mCodeObject == nsnull, "Already bound?");
// XXX - not taking a reference to aHandler - it is assumed we steal the
// lifetime from the caller.
pyBinding->mCodeObject = (PyObject *)aHandler;
return NS_OK;
}
nsresult
nsPythonContext::CompileFunction(void* aTarget,
const nsACString& aName,
PRUint32 aArgCount,
const char** aArgArray,
const nsAString& aBody,
const char* aURL,
PRUint32 aLineNo,
PRBool aShared,
void** aFunctionObject)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
NS_ERROR("CompileFunction not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsPythonContext::CallEventHandler(nsIScriptBinding *aTarget, void* aHandler,
nsIArray *aargv, nsISupports **arv)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
if (!mScriptsEnabled) {
return NS_OK;
}
nsPyScriptBinding *pyBinding = (nsPyScriptBinding *)aTarget;
NS_ENSURE_TRUE(pyBinding->mCodeObject, NS_ERROR_UNEXPECTED);
CEnterLeavePython _celp;
PyObject *obEvent = NULL;
PyObject *obTarget = NULL;
PyObject *thisGlobals = NULL;
PyObject *ret = NULL;
PRBool ok = PR_FALSE;
*arv = nsnull;
// exit via goto
thisGlobals = PyDict_Copy(mGlobal);
if (!thisGlobals)
goto done;
// Could get perf by caching wrapped object
obTarget = Py_nsISupports::PyObjectFromInterface(pyBinding->mHolder,
NS_GET_IID(nsISupports),
PR_TRUE);
if (!obTarget)
goto done;
// XXX - what should this be exposed as?
PyDict_SetItemString(thisGlobals, "target", obTarget);
// This sucks - 'compile' is passed the literal name 'event', but that
// is too early for us. It also kinda sucks it is hard-coded as argv[0]
if (aargv) {
PRUint32 argc = 0;
aargv->GetLength(&argc);
if (argc) {
nsCOMPtr<nsISupports> arg;
nsresult rv;
rv = aargv->QueryElementAt(0, NS_GET_IID(nsISupports), getter_AddRefs(arg));
if (NS_SUCCEEDED(rv))
obEvent = Py_nsISupports::PyObjectFromInterface(arg, NS_GET_IID(nsISupports),
PR_TRUE);
}
}
if (obEvent)
PyDict_SetItemString(thisGlobals, "event", obEvent);
ret = PyEval_EvalCode((PyCodeObject *)pyBinding->mCodeObject,
thisGlobals, NULL);
if (!ret)
goto done;
ok = Py_nsISupports::InterfaceFromPyObject(ret, NS_GET_IID(nsIVariant),
arv, PR_TRUE, PR_TRUE);
done:
nsresult rv = ok ? NS_OK : HandlePythonError();
Py_XDECREF(ret);
Py_XDECREF(obEvent);
Py_XDECREF(obTarget);
Py_XDECREF(thisGlobals);
return rv;
}
nsresult
nsPythonContext::GetScriptBinding(nsISupports *aObject, void *aScope,
nsIScriptBinding **aBinding)
{
*aBinding = new nsPyScriptBinding(aObject);
if (!*aBinding)
return NS_ERROR_OUT_OF_MEMORY;
NS_IF_ADDREF(*aBinding);
return NS_OK;
}
nsresult
nsPythonContext::GetScriptBindingHandler(nsIScriptBinding *aBinding,
nsString &name,
void **handler)
{
NS_ASSERTION(aBinding->GetLanguage() == nsIProgrammingLanguage::PYTHON,
"Not a Python binding!?");
nsPyScriptBinding *pyBinding = (nsPyScriptBinding *)aBinding;
*handler = pyBinding->mCodeObject;
return NS_OK;
}
nsresult
nsPythonContext::SetProperty(void *aTarget, const char *aPropName, nsISupports *aVal)
{
NS_ERROR("SetProperty not impl");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsPythonContext::AddGCRoot(void* aScriptObjectRef, const char* aName)
{
return NS_OK;
}
nsresult
nsPythonContext::RemoveGCRoot(void* aScriptObjectRef)
{
return NS_OK;
}
nsresult
nsPythonContext::InitClasses(void *aGlobalObj)
{
return NS_OK;
}
void
nsPythonContext::SetDefaultLanguageVersion(PRUint32 aVersion)
{
return;
}
nsIScriptGlobalObject *
nsPythonContext::GetGlobalObject()
{
NS_ERROR("Not implemented");
return nsnull;
}
void *
nsPythonContext::GetNativeContext()
{
return nsnull;
}
void *
nsPythonContext::GetNativeGlobal()
{
NS_ASSERTION(mGlobal, "GetNativeGlobal called before InitContext??");
return mGlobal;
}
void
nsPythonContext::WillInitializeContext()
{
mIsInitialized = PR_FALSE;
}
void
nsPythonContext::DidInitializeContext()
{
mIsInitialized = PR_TRUE;
}
PRBool
nsPythonContext::IsContextInitialized()
{
return mIsInitialized;
}
PRBool
nsPythonContext::GetProcessingScriptTag()
{
return mProcessingScriptTag;
}
void
nsPythonContext::SetProcessingScriptTag(PRBool aResult)
{
mProcessingScriptTag = aResult;
}
PRBool
nsPythonContext::GetScriptsEnabled()
{
return mScriptsEnabled;
}
void
nsPythonContext::SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts)
{
// eeek - this seems the wrong way around - the global should callback
// into the context.
mScriptsEnabled = aEnabled;
nsIScriptGlobalObject *global = GetGlobalObject();
if (global) {
global->SetScriptsEnabled(aEnabled, aFireTimeouts);
}
}
void
nsPythonContext::SetOwner(nsIScriptContextOwner* owner)
{
// The owner should not be addrefed!! We'll be told
// when the owner goes away.
mOwner = owner;
}
nsIScriptContextOwner *
nsPythonContext::GetOwner()
{
return mOwner;
}
nsresult
nsPythonContext::SetTerminationFunction(nsScriptTerminationFunc aFunc,
nsISupports* aRef)
{
NS_ERROR("Term functions need thought");
return NS_ERROR_UNEXPECTED;
}
void
nsPythonContext::ScriptEvaluated(PRBool aTerminated)
{
;
}
void
nsPythonContext::GC()
{
;
}
nsresult
nsPythonContext::FinalizeClasses(void *aGlobalObj)
{
Py_XDECREF((PyObject *)aGlobalObj);
return NS_OK;
}
NS_IMETHODIMP
nsPythonContext::Notify(nsITimer *timer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsPyScriptBinding
// QueryInterface implementation for nsPyScriptBinding
NS_INTERFACE_MAP_BEGIN(nsPyScriptBinding)
NS_INTERFACE_MAP_ENTRY(nsIScriptBinding)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsPyScriptBinding)
NS_IMPL_RELEASE(nsPyScriptBinding)
nsPyScriptBinding::nsPyScriptBinding(nsISupports *aObject) :
mHolder(aObject), mCodeObject(NULL)
{
PYLEAK_STAT_INCREMENT(Binding);
}
nsPyScriptBinding::~nsPyScriptBinding()
{
PYLEAK_STAT_XDECREMENT(mCodeObject, EventHandler);
Py_XDECREF(mCodeObject);
PYLEAK_STAT_DECREMENT(Binding);
}
void *
nsPyScriptBinding::GetNativeObject()
{
NS_ERROR("GetNativeObject not impl");
return nsnull;
}
nsISupports *
nsPyScriptBinding::GetTarget()
{
return mHolder;
}

View File

@@ -0,0 +1,174 @@
/* ***** 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 (original author)
*
* 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 ***** */
#include "nsIScriptContext.h"
#include "nsITimer.h"
#include "PyXPCOM.h"
class nsIScriptObjectOwner;
class nsIArray;
class nsPythonContext : public nsIScriptContext,
public nsITimerCallback
{
public:
nsPythonContext();
virtual ~nsPythonContext();
NS_DECL_ISUPPORTS
virtual PRUint32 GetLanguage() { return nsIProgrammingLanguage::PYTHON; }
virtual nsresult EvaluateString(const nsAString& aScript,
void *aScopeObject,
nsIPrincipal *principal,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
nsAString *aRetValue,
PRBool* aIsUndefined);
virtual nsresult EvaluateStringWithValue(const nsAString& aScript,
void *aScopeObject,
nsIPrincipal *aPrincipal,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
void* aRetValue,
PRBool* aIsUndefined);
virtual nsresult CompileScript(const PRUnichar* aText,
PRInt32 aTextLength,
void *aScopeObject,
nsIPrincipal *principal,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
void** aScriptObject);
virtual nsresult ExecuteScript(void* aScriptObject,
void *aScopeObject,
nsAString* aRetValue,
PRBool* aIsUndefined);
virtual nsresult CompileEventHandler(nsIScriptBinding *aTarget,
nsIAtom *aName,
const char *aEventName,
const nsAString& aBody,
const char *aURL,
PRUint32 aLineNo,
PRBool aShared,
void** aHandler);
virtual nsresult CallEventHandler(nsIScriptBinding* aTarget, void* aHandler,
nsIArray *argv, nsISupports **rv);
virtual nsresult BindCompiledEventHandler(nsIScriptBinding *aTarget,
nsIAtom *aName,
void *aHandler);
virtual nsresult CompileFunction(void* aTarget,
const nsACString& aName,
PRUint32 aArgCount,
const char** aArgArray,
const nsAString& aBody,
const char* aURL,
PRUint32 aLineNo,
PRBool aShared,
void** aFunctionObject);
virtual nsresult GetScriptBinding(nsISupports *aObject, void *aScope,
nsIScriptBinding **aBinding);
virtual nsresult GetScriptBindingHandler(nsIScriptBinding *aBinding,
nsString &name,
void **handler);
virtual nsresult AddGCRoot(void *object, const char *desc);
virtual nsresult RemoveGCRoot(void *object);
virtual void SetDefaultLanguageVersion(PRUint32 aVersion);
virtual nsIScriptGlobalObject *GetGlobalObject();
virtual void *GetNativeContext();
virtual void *GetNativeGlobal();
virtual nsresult InitContext(nsIScriptGlobalObject *aGlobalObject);
virtual PRBool IsContextInitialized();
virtual void GC();
virtual void ScriptEvaluated(PRBool aTerminated);
virtual void SetOwner(nsIScriptContextOwner* owner);
virtual nsIScriptContextOwner *GetOwner();
virtual nsresult SetTerminationFunction(nsScriptTerminationFunc aFunc,
nsISupports* aRef);
virtual PRBool GetScriptsEnabled();
virtual void SetScriptsEnabled(PRBool aEnabled, PRBool aFireTimeouts);
virtual nsresult SetProperty(void *aTarget, const char *aPropName,
nsISupports *aVal);
virtual PRBool GetProcessingScriptTag();
virtual void SetProcessingScriptTag(PRBool aResult);
virtual void SetGCOnDestruction(PRBool aGCOnDestruction) {;}
virtual nsresult InitClasses(void *aGlobalObj);
virtual nsresult FinalizeClasses(void* aGlobalObj);
virtual void WillInitializeContext();
virtual void DidInitializeContext();
NS_DECL_NSITIMERCALLBACK
protected:
PRPackedBool mIsInitialized;
PRPackedBool mScriptsEnabled;
PRPackedBool mProcessingScriptTag;
PRUint32 mNumEvaluations;
PyObject *mGlobal;
nsIScriptContextOwner* mOwner; /* NB: weak reference, not ADDREF'd */
static nsresult HandlePythonError();
};
class nsPyScriptBinding : public nsIScriptBinding {
public:
nsPyScriptBinding(nsISupports *aObject);
virtual ~nsPyScriptBinding();
NS_DECL_ISUPPORTS
virtual PRUint32 GetLanguage() {return nsIProgrammingLanguage::PYTHON;}
void *GetNativeObject();
nsISupports *GetTarget();
nsCOMPtr<nsISupports> mHolder;
PyObject *mCodeObject;
};

View File

@@ -0,0 +1,51 @@
/* ***** 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 ***** */
#include "nsIGenericFactory.h"
#include "nsPyRuntime.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPythonRuntime)
static const nsModuleComponentInfo components[] = {
{ "Python Script Language", NS_SCRIPT_LANGUAGE_PYTHON_CID,
NS_SCRIPT_LANGUAGE_PYTHON_CONTRACTID,
nsPythonRuntimeConstructor,
nsPythonRuntime::RegisterSelf,
nsPythonRuntime::UnregisterSelf,},
};
// Implementation of the module object.
NS_IMPL_NSGETMODULE(nsPyDOMModule, components)

View File

@@ -0,0 +1,116 @@
/* ***** 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 (original author)
*
* 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 ***** */
#include "nsPyRuntime.h"
#include "nsPyContext.h"
#include "nsIServiceManager.h"
#include "nsICategoryManager.h"
// QueryInterface implementation for nsPythonRuntime
NS_INTERFACE_MAP_BEGIN(nsPythonRuntime)
NS_INTERFACE_MAP_ENTRY(nsILanguageRuntime)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsPythonRuntime)
NS_IMPL_RELEASE(nsPythonRuntime)
nsresult
nsPythonRuntime::CreateContext(nsIScriptContext **ret)
{
if (!Py_IsInitialized()) {
Py_Initialize();
PyXPCOM_Globals_Ensure();
}
*ret = new nsPythonContext();
if (!ret)
return NS_ERROR_OUT_OF_MEMORY;
NS_IF_ADDREF(*ret);
return NS_OK;
}
NS_METHOD
nsPythonRuntime::RegisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const char* aComponentType,
const nsModuleComponentInfo *info)
{
nsresult rv = NS_OK;
nsCOMPtr<nsICategoryManager> catman =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsXPIDLCString previous;
rv = catman->AddCategoryEntry(SCRIPT_LANGUAGE_CATEGORY,
"application/x-python",
NS_SCRIPT_LANGUAGE_PYTHON_CONTRACTID,
PR_TRUE, PR_TRUE, getter_Copies(previous));
if (NS_FAILED(rv))
return rv;
// And also register a short name.
rv = catman->AddCategoryEntry(SCRIPT_LANGUAGE_CATEGORY,
"python",
NS_SCRIPT_LANGUAGE_PYTHON_CONTRACTID,
PR_TRUE, PR_TRUE, getter_Copies(previous));
return rv;
}
NS_METHOD
nsPythonRuntime::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const nsModuleComponentInfo *info)
{
nsresult rv = NS_OK;
nsCOMPtr<nsICategoryManager> catman =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
catman->DeleteCategoryEntry(SCRIPT_LANGUAGE_CATEGORY,
"application/x-python", PR_TRUE);
catman->DeleteCategoryEntry(SCRIPT_LANGUAGE_CATEGORY,
"python", PR_TRUE);
return rv;
}

View File

@@ -0,0 +1,80 @@
/* ***** 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 (original author)
*
* 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 ***** */
#include "nsILanguageRuntime.h"
#include "nsIGenericFactory.h"
#define NS_SCRIPT_LANGUAGE_PYTHON_CID \
{ 0xcee4ee7d, 0xf230, 0x49da, { 0x94, 0xd8, 0x6a, 0x9a, 0x48, 0xe, 0x12, 0xb3 } }
#define NS_SCRIPT_LANGUAGE_PYTHON_CONTRACTID \
"@mozilla.org/scriptlanguage/python;1"
class nsPythonRuntime : public nsILanguageRuntime
{
public:
// registration callbacks
static NS_METHOD
RegisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const char* aComponentType,
const nsModuleComponentInfo *info);
static NS_METHOD
UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const nsModuleComponentInfo *info);
// nsISupports
NS_DECL_ISUPPORTS
// nsIScriptLanguage
virtual PRUint32 GetLanguage() {
return nsIProgrammingLanguage::PYTHON;
}
virtual void ShutDown() {;}
virtual nsresult CreateContext(nsIScriptContext **ret);
virtual nsresult ParseVersion(const nsString &aVersionStr, PRUint32 *flags) {
*flags=0;
return NS_OK;
}
};

View File

@@ -0,0 +1,48 @@
# ***** 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: author
#
# 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 *****
DEPTH =../../../..
DIRS = \
pyxultest \
$(NULL)
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
pyexecdir = @libdir@/python$(PYTHON_VER_DOTTED)/site-packages
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,51 @@
# ***** 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: author
#
# 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 *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
XPI_FILE = pyxultest-$(shell date +%Y%m%d).xpi
xpi:
zip -j $(DIST)/$(XPI_FILE) $(srcdir)/install.js
cd $(DIST); zip -r $(XPI_FILE) \
bin/chrome/pyxultest.jar

View File

@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<RDF:Seq about="urn:mozilla:package:root">
<RDF:li resource="urn:mozilla:package:pyxultest"/>
</RDF:Seq>
<RDF:Description about="urn:mozilla:package:pyxultest"
chrome:displayName="Python in XUL test"
chrome:author="Mark Hammond"
chrome:name="pyxultest">
</RDF:Description>
</RDF:RDF>

View File

@@ -0,0 +1,93 @@
/* ***** 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 ***** */
// this function verifies disk space in kilobytes
function verifyDiskSpace(dirPath, spaceRequired)
{
var spaceAvailable;
// Get the available disk space on the given path
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
// Convert the available disk space into kilobytes
spaceAvailable = parseInt(spaceAvailable / 1024);
// do the verification
if(spaceAvailable < spaceRequired)
{
logComment("Insufficient disk space: " + dirPath);
logComment(" required : " + spaceRequired + " K");
logComment(" available: " + spaceAvailable + " K");
return(false);
}
return(true);
}
var srDest = 100;
var err = initInstall("Python XUL test", "pyxultest", "0.1");
logComment("initInstall: " + err);
var fProgram = getFolder("Program");
logComment("fProgram: " + fProgram);
if (verifyDiskSpace(fProgram, srDest))
{
err = addDirectory("Program", "0.1", "bin", fProgram, "", true);
logComment("addDirectory() returned: " + err);
var chromeFolder = getFolder("Chrome", "pyxultest.jar");
registerChrome(CONTENT | DELAYED_CHROME, chromeFolder, "content/pyxultest/");
err = getLastError();
if (err == ACCESS_DENIED) {
alert("Unable to write to program directory " + fProgram + ".\n You will need to restart the browser with administrator/root privileges to install this software. After installing as root (or administrator), you will need to restart the browser one more time to register the installed software.\n After the second restart, you can go back to running the browser without privileges!");
cancelInstall(err);
logComment("cancelInstall() due to error: " + err);
}
else if (err != SUCCESS) {
cancelInstall(err);
logComment("cancelInstall() due to error: " + err);
}
else {
performInstall();
logComment("performInstall() returned: " + err);
}
}
else
cancelInstall(INSUFFICIENT_DISK_SPACE);

View File

@@ -0,0 +1,6 @@
pyxultest.jar:
content/pyxultest/contents.rdf (contents.rdf)
content/pyxultest/pyxultest.xul (pyxultest.xul)
# content/pyxultest/pyxultest.js (pyxultest.js)
content/pyxultest/pyxultest.py (pyxultest.py)
content/pyxultest/pyxultest.css (pyxultest.css)

View File

@@ -0,0 +1,37 @@
/* ***** 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 ***** */
/* nothing to see here! */

View File

@@ -0,0 +1,3 @@
# An out-of-line script for this Python demo
print "Hello from an out-of-line Python script"

View File

@@ -0,0 +1,75 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="main-window" orient="vertical"
screenX="100" screenY="100"
height="300" width="500"
>
<script type="application/x-python" src="chrome://pyxultest/content/pyxultest.py"/>
<script type="application/x-python">
<![CDATA[
import sys
import xpcom
from xpcom import components
class EventListener:
_com_interfaces_ = components.interfaces.nsIDOMEventListener
def __init__(self, handler, globs = None):
try:
self.co = handler.func_code
except AttributeError:
self.co = compile(handler, "inline script", "exec")
self.globals = globs or globals()
def handleEvent(self, event):
exec self.co in self.globals
def event():
input = this.document.getElementById("input-box")
val = "This is the Python on XUL demo, using Python " + sys.version
input.setAttribute("value", val)
# Sadly no inline event handlers yet - hook up a click event.
button = this.document.getElementById("button1")
button.addEventListener('click', EventListener('print "hello from the click event"'), False)
print "Event listener is", this.window.addEventListener
this.window.addEventListener('load', EventListener('print "hello from the event " + str(this.document)'), False)
this.window.addEventListener('load', EventListener(event), False)
print this
for attr in "document parent top scrollbars name textZoom scrollX scrollY".split():
try:
val = getattr(this, attr)
except (xpcom.Exception, AttributeError), exc:
print "FAILED to get attribute %s: %s" % (attr, exc)
else:
print attr, "is", val
print "Scrollbar visible =", this.scrollbars.visible
#this.alert('hi from Python');
import xpcom
print "Window location is", this.window.location.href
#promptService = xpcom.components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(xpcom.components.interfaces.nsIPromptService)
#promptService.alert(this.window, "title", "Hello from Python");
]]>
</script>
<vbox flex="1">
<textbox id="input-box" style="width:100%" value = "hello there"
rows="5" multiline="1" flex="1"
/>
<button scriptLanguage="python" id="button1" label="click me" oncommand="print 'hello!!!';print event.target.tagName"/>
</vbox>
<!-- Here we have a script element defined at a parent node -->
<hbox scriptLanguage="python" oncommand="print 'You clicked on a', event.target.tagName">
<button label = "click here"/>
<button label = "or here"/>
</hbox>
</window>