adding new files. not part of build

This commit is contained in:
jband%netscape.com 2000-01-03 22:34:01 +00:00
parent 85bba6cd51
commit 5a0b3e6330
5 changed files with 550 additions and 0 deletions

View File

@ -0,0 +1,39 @@
xpcsample1.* is a set of files that show a sample of implementing some simple
xpcom classes and relecting them into JavaScript as a chain of properties on the
global object.
xpcsample1.idl declares four interfaces: nsIXPCSample_ClassA,
nsIXPCSample_ClassB, nsIXPCSample_ClassC, and nsIXPCSample_HookerUpper. 'A' has
an integer value (called 'someValue') and a 'B'. 'B' has an integer value and a
'C'. 'C' just has an integer value. nsIXPCSample_HookerUpper just has one method
that when called will attach an instance of 'A' to the global object.
Confused? This is quite contrived. It will make more sense after examining the
code.
So, this means that after calling the method
nsIXPCSample_HookerUpper::createSampleObjectAtGlobalScope in JavaScript one can
access:
A.someValue, A.B.someValue, and A.B.C.someValue.
see xpcsample.js (or run 'xpcshell xpcsample.js').
The point of all this is to show how to build a hierarchy of native xpcom
objects
with properties and methods reflected into JavaScript. Of course, in real
life these interfaces and native objects would be much more interesting.
The only direct jsapi calls required are those that will 'root' the hierarchy
into the JavaSCript namespace. 'createSampleObjectAtGlobalScope' shows an
example of doing this.
Most native objects can be satisfactorily reflected using these mechanisms.
However, some fancy stuff might require the extended support found in
nsIXPCScriptable.h. For example, relecting objects that act like constructor
functions, receiving 'finalize' calls on the native object, or reflecting
'dynamically' named properties (i.e. those not declared in xpidl). Native xpcom
objects that implement nsIXPCScriptable are given much more control over how
they are reflected into JavaScript. There should be few situations where this
additional control is needed.

View File

@ -0,0 +1,77 @@
#!gmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU Public License (the "GPL"), in which case the
# provisions of the GPL are applicable instead of those above.
# If you wish to allow use of your version of this file only
# under the terms of the GPL and not to allow others to use your
# version of this file under the NPL, indicate your decision by
# deleting the provisions above and replace them with the notice
# and other provisions required by the GPL. If you do not delete
# the provisions above, a recipient may use your version of this
# file under either the NPL or the GPL.
DEPTH=..\..\..\..
MAKE_OBJ_TYPE = DLL
DLLNAME = xpcsample
DLL =.\$(OBJDIR)\$(DLLNAME).dll
MODULE=xpcsample
DEFINES=-DWIN32_LEAN_AND_MEAN
XPIDLSRCS = \
.\xpcsample1.idl \
$(NULL)
OBJS= \
.\$(OBJDIR)\xpcsample1.obj \
$(NULL)
LINCS=-I$(PUBLIC)\xpconnect -I$(PUBLIC)\xpcom -I$(PUBLIC)\js \
-I$(PUBLIC)\raptor
LCFLAGS = \
$(LCFLAGS) \
$(DEFINES) \
$(NULL)
LLIBS= $(LIBNSPR) \
$(DIST)\lib\js$(MOZ_BITS)$(VERSION_NUMBER).lib \
$(DIST)\lib\xpcom.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(DLLNAME).lib
rm -f $(DIST)\bin\components\$(DLLNAME).dll
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,336 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
/* xpconnect api sample */
#include "xpcsample1.h"
#include "nsIXPConnect.h"
#include "jsapi.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
/***************************************************************************/
// forward declare the below classes for clarity
class nsXPCSample_ClassA;
class nsXPCSample_ClassB;
class nsXPCSample_ClassC;
/***************************************************************************/
// declare the classes
class nsXPCSample_ClassA : public nsIXPCSample_ClassA
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCSAMPLE_CLASSA
nsXPCSample_ClassA(PRInt32 aValue);
virtual ~nsXPCSample_ClassA();
private:
PRInt32 mValue;
nsCOMPtr<nsIXPCSample_ClassB> mClassB;
};
/********************************/
class nsXPCSample_ClassB : public nsIXPCSample_ClassB
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCSAMPLE_CLASSB
nsXPCSample_ClassB(PRInt32 aValue);
virtual ~nsXPCSample_ClassB();
private:
PRInt32 mValue;
nsCOMPtr<nsIXPCSample_ClassC> mClassC;
};
/********************************/
class nsXPCSample_ClassC : public nsIXPCSample_ClassC
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCSAMPLE_CLASSC
nsXPCSample_ClassC(PRInt32 aValue);
virtual ~nsXPCSample_ClassC();
private:
PRInt32 mValue;
};
/***************************************************************************/
// implement the 'root' ClassA for this odd sample
NS_IMPL_ISUPPORTS1(nsXPCSample_ClassA, nsIXPCSample_ClassA)
nsXPCSample_ClassA::nsXPCSample_ClassA(PRInt32 aValue)
: mValue(aValue)
{
NS_INIT_ISUPPORTS();
}
nsXPCSample_ClassA::~nsXPCSample_ClassA()
{
// empty
}
/* attribute PRInt32 someValue; */
NS_IMETHODIMP nsXPCSample_ClassA::GetSomeValue(PRInt32 *aSomeValue)
{
*aSomeValue = mValue;
return NS_OK;
}
NS_IMETHODIMP nsXPCSample_ClassA::SetSomeValue(PRInt32 aSomeValue)
{
mValue = aSomeValue;
return NS_OK;
}
/* readonly attribute nsIXPCSample_ClassB B; */
NS_IMETHODIMP nsXPCSample_ClassA::GetB(nsIXPCSample_ClassB * *aB)
{
if(!mClassB && !(mClassB = new nsXPCSample_ClassB(mValue)))
return NS_ERROR_FAILURE;
*aB = mClassB;
NS_ADDREF(*aB);
return NS_OK;
}
/***************************************************************************/
// implement ClassB for this odd sample
NS_IMPL_ISUPPORTS1(nsXPCSample_ClassB, nsIXPCSample_ClassB)
nsXPCSample_ClassB::nsXPCSample_ClassB(PRInt32 aValue)
: mValue(aValue)
{
NS_INIT_ISUPPORTS();
}
nsXPCSample_ClassB::~nsXPCSample_ClassB()
{
// empty
}
/* attribute PRInt32 someValue; */
NS_IMETHODIMP nsXPCSample_ClassB::GetSomeValue(PRInt32 *aSomeValue)
{
*aSomeValue = mValue;
return NS_OK;
}
NS_IMETHODIMP nsXPCSample_ClassB::SetSomeValue(PRInt32 aSomeValue)
{
mValue = aSomeValue;
return NS_OK;
}
/* readonly attribute nsIXPCSample_ClassC C; */
NS_IMETHODIMP nsXPCSample_ClassB::GetC(nsIXPCSample_ClassC * *aC)
{
if(!mClassC && !(mClassC = new nsXPCSample_ClassC(mValue)))
return NS_ERROR_FAILURE;
*aC = mClassC;
NS_ADDREF(*aC);
return NS_OK;
}
/***************************************************************************/
// implement ClassC for this odd sample
NS_IMPL_ISUPPORTS1(nsXPCSample_ClassC, nsIXPCSample_ClassC)
nsXPCSample_ClassC::nsXPCSample_ClassC(PRInt32 aValue)
: mValue(aValue)
{
NS_INIT_ISUPPORTS();
}
nsXPCSample_ClassC::~nsXPCSample_ClassC()
{
// empty
}
/* attribute PRInt32 someValue; */
NS_IMETHODIMP nsXPCSample_ClassC::GetSomeValue(PRInt32 *aSomeValue)
{
*aSomeValue = mValue;
return NS_OK;
}
NS_IMETHODIMP nsXPCSample_ClassC::SetSomeValue(PRInt32 aSomeValue)
{
mValue = aSomeValue;
return NS_OK;
}
/***************************************************************************/
// implement the hooker-upper (see the comment in the xpcsample1.idl)
class nsXPCSample_HookerUpper : public nsIXPCSample_HookerUpper
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCSAMPLE_HOOKERUPPER
nsXPCSample_HookerUpper();
virtual ~nsXPCSample_HookerUpper();
};
NS_IMPL_ISUPPORTS1(nsXPCSample_HookerUpper, nsIXPCSample_HookerUpper)
nsXPCSample_HookerUpper::nsXPCSample_HookerUpper()
{
NS_INIT_ISUPPORTS();
}
nsXPCSample_HookerUpper::~nsXPCSample_HookerUpper()
{
// empty
}
/* void createSampleObjectAtGlobalScope (in string name, in PRInt32 value); */
NS_IMETHODIMP
nsXPCSample_HookerUpper::CreateSampleObjectAtGlobalScope(const char *name, PRInt32 value)
{
// we use the xpconnect native call context stuff to get the current
// JSContext. Again, this would not be necessary if we were setting up
// our own JSContext instead of resonding to a call inside a running
// context.
// get the xpconnect service
nsresult rv;
NS_WITH_SERVICE(nsIXPConnect, xpc, nsIXPConnect::GetCID(), &rv);
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
// get the xpconnect native call context
nsCOMPtr<nsIXPCNativeCallContext> callContext;
xpc->GetCurrentNativeCallContext(getter_AddRefs(callContext));
if(!callContext)
return NS_ERROR_FAILURE;
// verify that we are being called from JS (i.e. the current call is
// to this object - though we don't verify that it is to this exact method)
nsCOMPtr<nsISupports> callee;
callContext->GetCallee(getter_AddRefs(callee));
if(!callee || callee.get() != (nsISupports*)this)
return NS_ERROR_FAILURE;
// Get JSContext of current call
JSContext* cx;
rv = callContext->GetJSContext(&cx);
if(NS_FAILED(rv) || !cx)
return NS_ERROR_FAILURE;
// Get the xpc wrapper (for 'this') so that we can get its JSObject
nsCOMPtr<nsIXPConnectWrappedNative> calleeWrapper;
callContext->GetCalleeWrapper(getter_AddRefs(calleeWrapper));
if(!calleeWrapper)
return NS_ERROR_FAILURE;
// Get the JSObject of the wrapper
JSObject* calleeJSObject;
rv = calleeWrapper->GetJSObject(&calleeJSObject);
if(NS_FAILED(rv) || !calleeJSObject)
return NS_ERROR_FAILURE;
// Now we walk the parent chain of the wrapper's JSObject to get at the
// global object to which we'd like to attack the new property (which is
// the point of this whole exercise!)
JSObject* tempJSObject;
JSObject* globalJSObject = calleeJSObject;
while(tempJSObject = JS_GetParent(cx, globalJSObject))
globalJSObject = tempJSObject;
// --- if we did this all at JSContext setup time then only the following
// is necessary...
// Create the new native object
nsXPCSample_ClassA* classA = new nsXPCSample_ClassA(value);
if(!classA)
return NS_ERROR_FAILURE;
// Build an xpconnect wrapper around the object
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
rv = xpc->WrapNative(cx, globalJSObject, classA,
NS_GET_IID(nsXPCSample_ClassA),
getter_AddRefs(wrapper));
if(NS_FAILED(rv) || !wrapper)
return NS_ERROR_FAILURE;
// Get the JSObject of the new wrapper we just built around our ClassA obj
JSObject* ourJSObject;
rv = wrapper->GetJSObject(&ourJSObject);
if(NS_FAILED(rv) || !ourJSObject)
return NS_ERROR_FAILURE;
// Now we can use the JSAPI to add this JSObject as a property of the
// global object.
if(!JS_DefineProperty(cx,
globalJSObject, // add property to this object
"A", // give property this name
OBJECT_TO_JSVAL(ourJSObject),
nsnull, nsnull,
JSPROP_PERMANENT | // these flags are optional
JSPROP_READONLY |
JSPROP_ENUMERATE))
return NS_ERROR_FAILURE;
// all is well - new object was added!
return NS_OK;
}
/***************************************************************************/
// generic factory and component registration stuff...
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCSample_HookerUpper)
static nsModuleComponentInfo components[] = {
{ "sample xpc component",
{ 0x97380cf0, 0xc21b, 0x11d3, { 0x98, 0xc9, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } },
NS_NSXPCSAMPLE_HOOKERUPPER_PROGID,
nsXPCSample_HookerUpperConstructor }
};
NS_IMPL_NSGETMODULE("nsXPCSampleModule", components)

View File

@ -0,0 +1,77 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
#include "nsISupports.idl"
// forward declare the below interfaces for clarity
interface nsIXPCSample_ClassA;
interface nsIXPCSample_ClassB;
interface nsIXPCSample_ClassC;
[scriptable, uuid(6bd0c120-c216-11d3-98c9-006008962422)]
interface nsIXPCSample_ClassA : nsISupports
{
attribute PRInt32 someValue;
readonly attribute nsIXPCSample_ClassB B;
};
[scriptable, uuid(c9c7bac0-c216-11d3-98c9-006008962422)]
interface nsIXPCSample_ClassB : nsISupports
{
attribute PRInt32 someValue;
readonly attribute nsIXPCSample_ClassC C;
};
[scriptable, uuid(df7bd080-c216-11d3-98c9-006008962422)]
interface nsIXPCSample_ClassC : nsISupports
{
attribute PRInt32 someValue;
};
// This is an interace for a funky object that can create an instance of the
// chain above in the global scope of the currently running JSContext. One
// might more normally do this automatically as the JSContext is created
// (or the 'request' serviced), but here I wanted to be able to show this
// activity from within an xpcom component.
[scriptable, uuid(15794370-c217-11d3-98c9-006008962422)]
interface nsIXPCSample_HookerUpper : nsISupports
{
void createSampleObjectAtGlobalScope(in string name, in PRInt32 value);
};
%{C++
#define NS_NSXPCSAMPLE_HOOKERUPPER_PROGID "xpc.sample_hookerupper.1"
%}

View File

@ -0,0 +1,21 @@
var clazz = Components.classes["xpc.sample_hookerupper.1"];
var iface = Components.interfaces.nsIXPCSample_HookerUpper;
var hookerupper = clazz.createInstance(iface);
hookerupper.createSampleObjectAtGlobalScope("A",5);
dump("A = "+A+"\n");
dump("A.someValue = "+A.someValue+"\n");
A.someValue++ ;
dump("A.someValue = "+A.someValue+"\n");
dump("A.B = "+A.B+"\n");
dump("A.B.someValue = "+A.B.someValue+"\n");
A.B.someValue++ ;
dump("A.B.someValue = "+A.B.someValue+"\n");
dump("A.B.C = "+A.B.C+"\n");
dump("A.B.C.someValue = "+A.B.C.someValue+"\n");
A.B.C.someValue++ ;
dump("A.B.C.someValue = "+A.B.C.someValue+"\n");