Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes
nsXBLProtoImpl Class Reference

#include <nsXBLProtoImpl.h>

Collaboration diagram for nsXBLProtoImpl:
Collaboration graph

List of all members.

Public Member Functions

 nsXBLProtoImpl ()
 ~nsXBLProtoImpl ()
nsresult InstallImplementation (nsXBLPrototypeBinding *aBinding, nsIContent *aBoundElement)
nsresult InitTargetObjects (nsXBLPrototypeBinding *aBinding, nsIScriptContext *aContext, nsIContent *aBoundElement, nsIXPConnectJSObjectHolder **aScriptObjectHolder, void **aTargetClassObject)
nsresult CompilePrototypeMembers (nsXBLPrototypeBinding *aBinding)
void SetMemberList (nsXBLProtoImplMember *aMemberList)
PRBool CompiledMembers () const

Public Attributes

nsCString mClassName

Protected Member Functions

void DestroyMembers (nsXBLProtoImplMember *aBrokenMember)

Protected Attributes


Detailed Description

Definition at line 51 of file nsXBLProtoImpl.h.

Constructor & Destructor Documentation

Definition at line 62 of file nsXBLProtoImpl.h.

    // Note: the constructor and destructor are in mMembers, so we'll
    // clean them up automatically.
    for (nsXBLProtoImplMember* curr = mMembers; curr; curr=curr->GetNext())
      curr->Destroy(mClassObject != nsnull);
    delete mMembers; 

Here is the call graph for this function:

Member Function Documentation

Definition at line 91 of file nsXBLProtoImpl.h.

    return mClassObject != nsnull;

Here is the caller graph for this function:

Definition at line 164 of file nsXBLProtoImpl.cpp.

  // We want to pre-compile our implementation's members against a "prototype context". Then when we actually 
  // bind the prototype to a real xbl instance, we'll clone the pre-compiled JS into the real instance's 
  // context.
  nsCOMPtr<nsIScriptGlobalObjectOwner> globalOwner(
  nsIScriptGlobalObject* globalObject = globalOwner->GetScriptGlobalObject();

  nsIScriptContext *context = globalObject->GetContext();
  JSObject *global = globalObject->GetGlobalJSObject();

  void* classObject;
  nsresult rv = aBinding->InitClass(mClassName,
                                    (JSContext *)context->GetNativeContext(),
                                    global, global,
  if (NS_FAILED(rv))
    return rv;

  mClassObject = (JSObject*) classObject;
  if (!mClassObject)
    return NS_ERROR_FAILURE;

  // Now that we have a class object installed, we walk our member list and compile each of our
  // properties and methods in turn.
  for (nsXBLProtoImplMember* curr = mMembers;
       curr = curr->GetNext()) {
    nsresult rv = curr->CompileMember(context, mClassName, mClassObject);
    if (NS_FAILED(rv)) {
      return rv;
  return NS_OK;

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXBLProtoImpl::DestroyMembers ( nsXBLProtoImplMember aBrokenMember) [protected]

Definition at line 205 of file nsXBLProtoImpl.cpp.

  NS_ASSERTION(mClassObject, "This should never be called when there is no class object");
  PRBool compiled = PR_TRUE;
  for (nsXBLProtoImplMember* curr = mMembers; curr; curr = curr->GetNext()) {
    if (curr == aBrokenMember) {
      compiled = PR_FALSE;

  // Now clear out mMembers so we don't try to call Destroy() on them again
  delete mMembers;
  mMembers = nsnull;
  mConstructor = nsnull;
  mDestructor = nsnull;

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXBLProtoImpl::InitTargetObjects ( nsXBLPrototypeBinding aBinding,
nsIScriptContext aContext,
nsIContent aBoundElement,
nsIXPConnectJSObjectHolder **  aScriptObjectHolder,
void **  aTargetClassObject 

Definition at line 97 of file nsXBLProtoImpl.cpp.

  nsresult rv = NS_OK;
  *aScriptObjectHolder = nsnull;
  if (!mClassObject) {
    rv = CompilePrototypeMembers(aBinding); // This is the first time we've ever installed this binding on an element.
                                 // We need to go ahead and compile all methods and properties on a class
                                 // in our prototype binding.
    if (NS_FAILED(rv))
      return rv;

    if (!mClassObject)
      return NS_OK; // This can be ok, if all we've got are fields (and no methods/properties).

  nsIDocument *ownerDoc = aBoundElement->GetOwnerDoc();
  nsIScriptGlobalObject *sgo;

  if (!ownerDoc || !(sgo = ownerDoc->GetScriptGlobalObject())) {
    NS_ERROR("Can't find global object for bound content!");


  // Because our prototype implementation has a class, we need to build up a corresponding
  // class for the concrete implementation in the bound document.
  JSContext* jscontext = (JSContext*)aContext->GetNativeContext();
  JSObject* global = sgo->GetGlobalJSObject();
  nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
  rv = nsContentUtils::XPConnect()->WrapNative(jscontext, global,
  JSObject * object = nsnull;
  rv = wrapper->GetJSObject(&object);

  // All of the above code was just obtaining the bound element's script object and its immediate
  // concrete base class.  We need to alter the object so that our concrete class is interposed
  // between the object and its base class.  We become the new base class of the object, and the
  // object's old base class becomes the new class' base class.
  rv = aBinding->InitClass(mClassName, jscontext, global, object,
  if (NS_FAILED(rv))
    return rv;

  // Root ourselves in the document.
  nsIDocument* doc = aBoundElement->GetOwnerDoc();
  if (doc) {
    nsCOMPtr<nsIXPConnectWrappedNative> nativeWrapper(do_QueryInterface(wrapper));
    if (nativeWrapper) {

  return rv;

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 54 of file nsXBLProtoImpl.cpp.

  // This function is called to install a concrete implementation on a bound element using
  // this prototype implementation as a guide.  The prototype implementation is compiled lazily,
  // so for the first bound element that needs a concrete implementation, we also build the
  // prototype implementation.
  if (!mMembers)  // Constructor and destructor also live in mMembers
    return NS_OK; // Nothing to do, so let's not waste time.

  // If the way this gets the script context changes, fix
  // nsXBLProtoImplAnonymousMethod::Execute
  nsIDocument* document = aBoundElement->GetOwnerDoc();
  if (!document) return NS_OK;

  nsIScriptGlobalObject *global = document->GetScriptGlobalObject();
  if (!global) return NS_OK;

  nsCOMPtr<nsIScriptContext> context = global->GetContext();
  if (!context) return NS_OK;

  // InitTarget objects gives us back the JS object that represents the bound element and the
  // class object in the bound document that represents the concrete version of this implementation.
  // This function also has the side effect of building up the prototype implementation if it has
  // not been built already.
  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
  void * targetClassObject = nsnull;
  nsresult rv = InitTargetObjects(aBinding, context, aBoundElement,
                                  getter_AddRefs(holder), &targetClassObject);
  NS_ENSURE_SUCCESS(rv, rv); // kick out if we were unable to properly intialize our target objects

  JSObject * targetScriptObject;

  // Walk our member list and install each one in turn.
  for (nsXBLProtoImplMember* curr = mMembers;
       curr = curr->GetNext())
    curr->InstallMember(context, aBoundElement, targetScriptObject,
                        targetClassObject, mClassName);
  return NS_OK;

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 79 of file nsXBLProtoImpl.h.

{ delete mMembers; mMembers = aMemberList; };

Here is the caller graph for this function:

Member Data Documentation

Definition at line 89 of file nsXBLProtoImpl.h.

Definition at line 96 of file nsXBLProtoImpl.h.

Definition at line 102 of file nsXBLProtoImpl.h.

Definition at line 103 of file nsXBLProtoImpl.h.

Definition at line 99 of file nsXBLProtoImpl.h.

The documentation for this class was generated from the following files: