Back to index

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

#include <nsXBLBinding.h>

Collaboration diagram for nsXBLBinding:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsXBLBinding (nsXBLPrototypeBinding *aProtoBinding)
 ~nsXBLBinding ()
nsrefcnt AddRef ()
 XBLBindings are refcounted.
nsrefcnt Release ()
nsXBLPrototypeBindingPrototypeBinding ()
nsIContentGetAnonymousContent ()
nsXBLBindingGetBaseBinding ()
void SetBaseBinding (nsXBLBinding *aBinding)
nsIContentGetBoundElement ()
void SetBoundElement (nsIContent *aElement)
PRBool IsStyleBinding () const
void SetIsStyleBinding (PRBool aIsStyle)
void MarkForDeath ()
PRBool MarkedForDeath () const
PRBool HasStyleSheets () const
PRBool InheritsStyle () const
PRBool ImplementsInterface (REFNSIID aIID) const
PRBool ShouldBuildChildFrames () const
void GenerateAnonymousContent ()
void InstallAnonymousContent (nsIContent *aAnonParent, nsIContent *aElement)
void InstallEventHandlers ()
nsresult InstallImplementation ()
void ExecuteAttachedHandler ()
void ExecuteDetachedHandler ()
void UnhookEventHandlers ()
nsIAtomGetBaseTag (PRInt32 *aNameSpaceID)
nsXBLBindingGetFirstBindingWithConstructor ()
nsXBLBindingRootBinding ()
nsXBLBindingGetFirstStyleBinding ()
nsresult GetInsertionPointsFor (nsIContent *aParent, nsVoidArray **aResult)
nsIContentGetInsertionPoint (nsIContent *aChild, PRUint32 *aIndex)
nsIContentGetSingleInsertionPoint (PRUint32 *aIndex, PRBool *aMultipleInsertionPoints)
void AttributeChanged (nsIAtom *aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag, PRBool aNotify)
void ChangeDocument (nsIDocument *aOldDocument, nsIDocument *aNewDocument)
void WalkRules (nsIStyleRuleProcessor::EnumFunc aFunc, void *aData)
already_AddRefed< nsIDOMNodeListGetAnonymousNodes ()

Static Public Member Functions

static nsresult GetTextData (nsIContent *aParent, nsString &aResult)
static nsresult DoInitJSClass (JSContext *cx, JSObject *global, JSObject *obj, const nsAFlatCString &aClassName, void **aClassObject)

Protected Member Functions

nsresult InitClass (const nsCString &aClassName, nsIScriptContext *aContext, nsIDocument *aDocument, void **aScriptObject, void **aClassObject)
PRBool AllowScripts ()

Protected Attributes

nsAutoRefCnt mRefCnt
nsXBLPrototypeBindingmPrototypeBinding
nsCOMPtr< nsIContentmContent
nsRefPtr< nsXBLBindingmNextBinding
nsIContentmBoundElement
nsObjectHashtable * mInsertionPointTable
PRPackedBool mIsStyleBinding
PRPackedBool mMarkedForDeath

Detailed Description

Definition at line 56 of file nsXBLBinding.h.


Constructor & Destructor Documentation

Definition at line 162 of file nsXBLBinding.cpp.

  : mPrototypeBinding(aBinding),
    mInsertionPointTable(nsnull),
    mIsStyleBinding(PR_TRUE),
    mMarkedForDeath(PR_FALSE)
{
  NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
  // Grab a ref to the document info so the prototype binding won't die
  NS_ADDREF(mPrototypeBinding->XBLDocumentInfo());
}

Here is the call graph for this function:

Definition at line 174 of file nsXBLBinding.cpp.

Here is the call graph for this function:


Member Function Documentation

XBLBindings are refcounted.

They are held onto in 3 ways:

  1. The binding manager's binding table holds onto all bindings that are currently attached to a content node.
  2. Bindings hold onto their base binding. This is important since the base binding itself may not be attached to anything.
  3. The binding manager holds an additional reference to bindings which are queued to fire their constructors.

Definition at line 72 of file nsXBLBinding.h.

  {
    ++mRefCnt;
    NS_LOG_ADDREF(this, mRefCnt, "nsXBLBinding", sizeof(nsXBLBinding));
    return mRefCnt;
  }

Definition at line 1201 of file nsXBLBinding.cpp.

{
  PRBool result;
  mPrototypeBinding->GetAllowScripts(&result);
  if (!result) {
    return result;
  }

  // Nasty hack.  Use the JSContext of the bound node, since the
  // security manager API expects to get the docshell type from
  // that.  But use the nsIPrincipal of our document.
  nsIScriptSecurityManager* mgr = nsContentUtils::GetSecurityManager();
  if (!mgr) {
    return PR_FALSE;
  }
  
  nsIDocument* doc = mBoundElement->GetOwnerDoc();
  if (!doc) {
    return PR_FALSE;
  }

  nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
  if (!global) {
    return PR_FALSE;
  }

  nsCOMPtr<nsIScriptContext> context = global->GetContext();
  if (!context) {
    return PR_FALSE;
  }
  
  JSContext* cx = (JSContext*) context->GetNativeContext();

  nsCOMPtr<nsIDocument> ourDocument;
  mPrototypeBinding->XBLDocumentInfo()->GetDocument(getter_AddRefs(ourDocument));
  nsIPrincipal* principal = ourDocument->GetPrincipal();
  if (!principal) {
    return PR_FALSE;
  }

  PRBool canExecute;
  nsresult rv = mgr->CanExecuteScripts(cx, principal, &canExecute);
  return NS_SUCCEEDED(rv) && canExecute;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXBLBinding::AttributeChanged ( nsIAtom aAttribute,
PRInt32  aNameSpaceID,
PRBool  aRemoveFlag,
PRBool  aNotify 
)

Definition at line 774 of file nsXBLBinding.cpp.

{
  // XXX Change if we ever allow multiple bindings in a chain to contribute anonymous content
  if (!mContent) {
    if (mNextBinding)
      mNextBinding->AttributeChanged(aAttribute, aNameSpaceID,
                                     aRemoveFlag, aNotify);
  } else {
    mPrototypeBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag,
                                        mBoundElement, mContent, aNotify);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXBLBinding::ChangeDocument ( nsIDocument aOldDocument,
nsIDocument aNewDocument 
)

Definition at line 883 of file nsXBLBinding.cpp.

{
  if (aOldDocument != aNewDocument) {
    if (mNextBinding)
      mNextBinding->ChangeDocument(aOldDocument, aNewDocument);

    // Only style bindings get their prototypes unhooked.
    if (mIsStyleBinding) {
      // Now the binding dies.  Unhook our prototypes.
      nsIContent* interfaceElement =
        mPrototypeBinding->GetImmediateChild(nsXBLAtoms::implementation);

      if (interfaceElement) { 
        nsIScriptGlobalObject *global = aOldDocument->GetScriptGlobalObject();
        if (global) {
          nsIScriptContext *context = global->GetContext();
          if (context) {
            JSContext *jscontext = (JSContext *)context->GetNativeContext();
 
            nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
            nsresult rv = nsContentUtils::XPConnect()->
              WrapNative(jscontext, global->GetGlobalJSObject(),
                         mBoundElement, NS_GET_IID(nsISupports),
                         getter_AddRefs(wrapper));
            if (NS_FAILED(rv))
              return;

            JSObject* scriptObject = nsnull;
            rv = wrapper->GetJSObject(&scriptObject);
            if (NS_FAILED(rv))
              return;

            // XXX Stay in sync! What if a layered binding has an
            // <interface>?!

            // XXX Sanity check to make sure our class name matches
            // Pull ourselves out of the proto chain.
            JSObject* ourProto = ::JS_GetPrototype(jscontext, scriptObject);
            if (ourProto)
            {
              JSObject* grandProto = ::JS_GetPrototype(jscontext, ourProto);
              ::JS_SetPrototype(jscontext, scriptObject, grandProto);
            }

            // Don't remove the reference from the document to the
            // wrapper here since it'll be removed by the element
            // itself when that's taken out of the document.
          }
        }
      }
    }

    // Update the anonymous content.
    nsIContent *anonymous = mContent;
    if (anonymous) {
      // Also kill the default content within all our insertion points.
      if (mInsertionPointTable)
        mInsertionPointTable->Enumerate(ChangeDocumentForDefaultContent,
                                        nsnull);

#ifdef MOZ_XUL
      nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(aOldDocument));
#endif

      anonymous->UnbindFromTree(); // Kill it.

#ifdef MOZ_XUL
      // To make XUL templates work (and other XUL-specific stuff),
      // we'll need to notify it using its add & remove APIs. Grab the
      // interface now...
      if (xuldoc)
        xuldoc->RemoveSubtreeFromDocument(anonymous);
#endif
    }

    // Make sure that henceforth we don't claim that mBoundElement's children
    // have insertion parents in the old document.
    nsIBindingManager* bindingManager = aOldDocument->BindingManager();
    for (PRUint32 i = mBoundElement->GetChildCount(); i > 0; --i) {
      NS_ASSERTION(mBoundElement->GetChildAt(i-1),
                   "Must have child at i for 0 <= i < GetChildCount()!");
      bindingManager->SetInsertionParent(mBoundElement->GetChildAt(i-1),
                                         nsnull);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXBLBinding::DoInitJSClass ( JSContext cx,
JSObject global,
JSObject obj,
const nsAFlatCString aClassName,
void **  aClassObject 
) [static]

Definition at line 1001 of file nsXBLBinding.cpp.

{
  // First ensure our JS class is initialized.
  jsval val;
  JSObject* proto;

  nsCAutoString className(aClassName);
  JSObject* parent_proto = nsnull;  // If we have an "obj" we can set this
  if (obj) {
    // Retrieve the current prototype of obj.
    parent_proto = ::JS_GetPrototype(cx, obj);
    if (parent_proto) {
      // We need to create a unique classname based on aClassName and
      // parent_proto.  Append a space (an invalid URI character) to ensure that
      // we don't have accidental collisions with the case when parent_proto is
      // null and aClassName ends in some bizarre numbers (yeah, it's unlikely).
      jsid parent_proto_id;
      if (!::JS_GetObjectId(cx, parent_proto, &parent_proto_id)) {
        // Probably OOM
        return NS_ERROR_OUT_OF_MEMORY;
      }

      // One space, maybe "0x", at most 16 chars (on a 64-bit system) of long,
      // and a null-terminator (which PR_snprintf ensures is there even if the
      // string representation of what we're printing does not fit in the buffer
      // provided).
      char buf[20];
      PR_snprintf(buf, sizeof(buf), " %lx", parent_proto_id);
      className.Append(buf);
    }
  }

  if ((!::JS_LookupPropertyWithFlags(cx, global, className.get(),
                                     JSRESOLVE_CLASSNAME,
                                     &val)) ||
      JSVAL_IS_PRIMITIVE(val)) {
    // We need to initialize the class.

    nsXBLJSClass* c;
    void* classObject;
    nsCStringKey key(className);
    classObject = (nsXBLService::gClassTable)->Get(&key);

    if (classObject) {
      c = NS_STATIC_CAST(nsXBLJSClass*, classObject);

      // If c is on the LRU list (i.e., not linked to itself), remove it now!
      JSCList* link = NS_STATIC_CAST(JSCList*, c);
      if (c->next != link) {
        JS_REMOVE_AND_INIT_LINK(link);
        nsXBLService::gClassLRUListLength--;
      }
    } else {
      if (JS_CLIST_IS_EMPTY(&nsXBLService::gClassLRUList)) {
        // We need to create a struct for this class.
        c = new nsXBLJSClass(className);

        if (!c)
          return NS_ERROR_OUT_OF_MEMORY;
      } else {
        // Pull the least recently used class struct off the list.
        JSCList* lru = (nsXBLService::gClassLRUList).next;
        JS_REMOVE_AND_INIT_LINK(lru);
        nsXBLService::gClassLRUListLength--;

        // Remove any mapping from the old name to the class struct.
        c = NS_STATIC_CAST(nsXBLJSClass*, lru);
        nsCStringKey oldKey(c->name);
        (nsXBLService::gClassTable)->Remove(&oldKey);

        // Change the class name and we're done.
        nsMemory::Free((void*) c->name);
        c->name = ToNewCString(className);
      }

      // Add c to our table.
      (nsXBLService::gClassTable)->Put(&key, (void*)c);
    }

    // The prototype holds a strong reference to its class struct.
    c->Hold();

    // Make a new object prototyped by parent_proto and parented by global.
    proto = ::JS_InitClass(cx,                  // context
                           global,              // global object
                           parent_proto,        // parent proto 
                           c,                   // JSClass
                           nsnull,              // JSNative ctor
                           0,                   // ctor args
                           nsnull,              // proto props
                           nsnull,              // proto funcs
                           nsnull,              // ctor props (static)
                           nsnull);             // ctor funcs (static)
    if (!proto) {
      // This will happen if we're OOM or if the security manager
      // denies defining the new class...

      (nsXBLService::gClassTable)->Remove(&key);

      c->Drop();

      return NS_ERROR_OUT_OF_MEMORY;
    }

    *aClassObject = (void*)proto;
  }
  else {
    proto = JSVAL_TO_OBJECT(val);
  }

  if (obj) {
    // Set the prototype of our object to be the new class.
    if (!::JS_SetPrototype(cx, obj, proto)) {
      return NS_ERROR_FAILURE;
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 789 of file nsXBLBinding.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 799 of file nsXBLBinding.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 438 of file nsXBLBinding.cpp.

{
  // Fetch the content element for this binding.
  nsIContent* content =
    mPrototypeBinding->GetImmediateChild(nsXBLAtoms::content);

  if (!content) {
    // We have no anonymous content.
    if (mNextBinding)
      mNextBinding->GenerateAnonymousContent();

    return;
  }
     
  // Find out if we're really building kids or if we're just
  // using the attribute-setting shorthand hack.
  PRUint32 contentCount = content->GetChildCount();

  // Plan to build the content by default.
  PRBool hasContent = (contentCount > 0);
  PRBool hasInsertionPoints = mPrototypeBinding->HasInsertionPoints();

#ifdef DEBUG
  // See if there's an includes attribute.
  nsAutoString includes;
  content->GetAttr(kNameSpaceID_None, nsXBLAtoms::includes, includes);
  if (!includes.IsEmpty()) {
    nsCAutoString id;
    mPrototypeBinding->GetID(id);
    nsCAutoString message("An XBL Binding with an id of ");
    message += id;
    message += " and found in the file ";
    nsCAutoString uri;
    mPrototypeBinding->DocURI()->GetSpec(uri);
    message += uri;
    message += " is still using the deprecated\n<content includes=\"\"> syntax! Use <children> instead!\n"; 
    NS_WARNING(message.get());
  }
#endif

  if (hasContent || hasInsertionPoints) {
    nsIDocument* doc = mBoundElement->GetOwnerDoc();

    // XXX doc will be null if we're in the midst of paint suppression.
    if (! doc)
      return;
    
    nsIBindingManager *bindingManager = doc->BindingManager();

    nsCOMPtr<nsIDOMNodeList> children;
    bindingManager->GetContentListFor(mBoundElement, getter_AddRefs(children));
 
    nsCOMPtr<nsIDOMNode> node;
    nsCOMPtr<nsIContent> childContent;
    PRUint32 length;
    children->GetLength(&length);
    if (length > 0 && !hasInsertionPoints) {
      // There are children being placed underneath us, but we have no specified
      // insertion points, and therefore no place to put the kids.  Don't generate
      // anonymous content.
      // Special case template and observes.
      for (PRUint32 i = 0; i < length; i++) {
        children->Item(i, getter_AddRefs(node));
        childContent = do_QueryInterface(node);

        nsINodeInfo *ni = childContent->GetNodeInfo();

        if (!ni || (!ni->Equals(nsXULAtoms::observes, kNameSpaceID_XUL) &&
                    !ni->Equals(nsXULAtoms::templateAtom, kNameSpaceID_XUL))) {
          hasContent = PR_FALSE;
          break;
        }
      }
    }

    if (hasContent || hasInsertionPoints) {
      nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content));

      nsCOMPtr<nsIDOMNode> clonedNode;
      domElement->CloneNode(PR_TRUE, getter_AddRefs(clonedNode));
  
      mContent = do_QueryInterface(clonedNode);
      InstallAnonymousContent(mContent, mBoundElement);

      if (hasInsertionPoints) {
        // Now check and see if we have a single insertion point 
        // or multiple insertion points.
      
        // Enumerate the prototype binding's insertion table to build
        // our table of instantiated insertion points.
        mPrototypeBinding->InstantiateInsertionPoints(this);

        // We now have our insertion point table constructed.  We
        // enumerate this table.  For each array of insertion points
        // bundled under the same content node, we generate a content
        // list.  In the case of the bound element, we generate a new
        // anonymous node list that will be used in place of the binding's
        // cached anonymous node list.
        ContentListData data(this, bindingManager);
        mInsertionPointTable->Enumerate(BuildContentLists, &data);
      
        // We need to place the children
        // at their respective insertion points.
        PRUint32 index = 0;
        PRBool multiplePoints = PR_FALSE;
        nsIContent *singlePoint = GetSingleInsertionPoint(&index,
                                                          &multiplePoints);
      
        if (children) {
          if (multiplePoints) {
            // We must walk the entire content list in order to determine where
            // each child belongs.
            children->GetLength(&length);
            for (PRUint32 i = 0; i < length; i++) {
              children->Item(i, getter_AddRefs(node));
              childContent = do_QueryInterface(node);

              // Now determine the insertion point in the prototype table.
              PRUint32 index;
              nsIContent *point = GetInsertionPoint(childContent, &index);
              bindingManager->SetInsertionParent(childContent, point);

              // Find the correct nsIXBLInsertion point in our table.
              nsVoidArray* arr;
              GetInsertionPointsFor(point, &arr);
              nsXBLInsertionPoint* insertionPoint = nsnull;
              PRInt32 arrCount = arr->Count();
              for (PRInt32 j = 0; j < arrCount; j++) {
                insertionPoint = NS_STATIC_CAST(nsXBLInsertionPoint*, arr->ElementAt(j));
                if (insertionPoint->Matches(point, index))
                  break;
                insertionPoint = nsnull;
              }

              if (insertionPoint) 
                insertionPoint->AddChild(childContent);
              else {
                // We were unable to place this child.  All anonymous content
                // should be thrown out.  Special-case template and observes.

                nsINodeInfo *ni = childContent->GetNodeInfo();

                if (!ni ||
                    (!ni->Equals(nsXULAtoms::observes, kNameSpaceID_XUL) &&
                     !ni->Equals(nsXULAtoms::templateAtom, kNameSpaceID_XUL))) {
                  // Kill all anonymous content.
                  mContent = nsnull;
                  bindingManager->SetContentListFor(mBoundElement, nsnull);
                  bindingManager->SetAnonymousNodesFor(mBoundElement, nsnull);
                  return;
                }
              }
            }
          }
          else {
            // All of our children are shunted to this single insertion point.
            nsVoidArray* arr;
            GetInsertionPointsFor(singlePoint, &arr);
            nsXBLInsertionPoint* insertionPoint = NS_STATIC_CAST(nsXBLInsertionPoint*, arr->ElementAt(0));
        
            nsCOMPtr<nsIDOMNode> node;
            nsCOMPtr<nsIContent> content;
            PRUint32 length;
            children->GetLength(&length);
          
            for (PRUint32 i = 0; i < length; i++) {
              children->Item(i, getter_AddRefs(node));
              content = do_QueryInterface(node);
              bindingManager->SetInsertionParent(content, singlePoint);
              insertionPoint->AddChild(content);
            }
          }
        }

        // Now that all of our children have been added, we need to walk all of our
        // nsIXBLInsertion points to see if any of them have default content that
        // needs to be built.
        mInsertionPointTable->Enumerate(RealizeDefaultContent, &data);
      }
    }

    mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent);
  }

  // Always check the content element for potential attributes.
  // This shorthand hack always happens, even when we didn't
  // build anonymous content.
  PRUint32 length = content->GetAttrCount();

  PRInt32 namespaceID;
  nsCOMPtr<nsIAtom> name;
  nsCOMPtr<nsIAtom> prefix;

  for (PRUint32 i = 0; i < length; ++i) {
    content->GetAttrNameAt(i, &namespaceID, getter_AddRefs(name),
                           getter_AddRefs(prefix));

    if (name != nsXBLAtoms::includes) {
      nsAutoString value;
      mBoundElement->GetAttr(namespaceID, name, value);
      if (value.IsEmpty()) {
        nsAutoString value2;
        content->GetAttr(namespaceID, name, value2);
        mBoundElement->SetAttr(namespaceID, name, value2, PR_FALSE);
      }
    }

    // Conserve space by wiping the attributes off the clone.
    if (mContent)
      mContent->UnsetAttr(namespaceID, name, PR_FALSE);
  }
}

Here is the call graph for this function:

Definition at line 92 of file nsXBLBinding.h.

{ return mContent; }

Here is the caller graph for this function:

Definition at line 1344 of file nsXBLBinding.cpp.

{
  if (mContent) {
    nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(mContent));
    nsIDOMNodeList *nodeList = nsnull;
    elt->GetChildNodes(&nodeList);
    return nodeList;
  }

  if (mNextBinding)
    return mNextBinding->GetAnonymousNodes();

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 94 of file nsXBLBinding.h.

{ return mNextBinding; }

Here is the caller graph for this function:

nsIAtom * nsXBLBinding::GetBaseTag ( PRInt32 aNameSpaceID)

Definition at line 764 of file nsXBLBinding.cpp.

{
  nsIAtom *tag = mPrototypeBinding->GetBaseTag(aNameSpaceID);
  if (!tag && mNextBinding)
    return mNextBinding->GetBaseTag(aNameSpaceID);

  return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 97 of file nsXBLBinding.h.

{ return mBoundElement; }

Here is the caller graph for this function:

Definition at line 240 of file nsXBLBinding.cpp.

{
  if (mPrototypeBinding->GetConstructor())
    return this;

  if (mNextBinding)
    return mNextBinding->GetFirstBindingWithConstructor();

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1321 of file nsXBLBinding.cpp.

{
  if (mIsStyleBinding)
    return this;

  return mNextBinding ? mNextBinding->GetFirstStyleBinding() : nsnull;
}

Here is the caller graph for this function:

Definition at line 1280 of file nsXBLBinding.cpp.

{
  if (mContent) {
    return mPrototypeBinding->GetInsertionPoint(mBoundElement, mContent,
                                                aChild, aIndex);
  }

  if (mNextBinding)
    return mNextBinding->GetInsertionPoint(aChild, aIndex);

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1258 of file nsXBLBinding.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

nsIContent * nsXBLBinding::GetSingleInsertionPoint ( PRUint32 aIndex,
PRBool aMultipleInsertionPoints 
)

Definition at line 1294 of file nsXBLBinding.cpp.

{
  *aMultipleInsertionPoints = PR_FALSE;
  if (mContent) {
    return mPrototypeBinding->GetSingleInsertionPoint(mBoundElement, mContent, 
                                                      aIndex, 
                                                      aMultipleInsertionPoints);
  }

  if (mNextBinding)
    return mNextBinding->GetSingleInsertionPoint(aIndex,
                                                 aMultipleInsertionPoints);

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXBLBinding::GetTextData ( nsIContent aParent,
nsString aResult 
) [static]

Definition at line 1182 of file nsXBLBinding.cpp.

{
  aResult.Truncate(0);

  PRUint32 textCount = aParent->GetChildCount();
  nsAutoString answer;
  for (PRUint32 j = 0; j < textCount; j++) {
    // Get the child.
    nsCOMPtr<nsIDOMText> text(do_QueryInterface(aParent->GetChildAt(j)));
    if (text) {
      nsAutoString data;
      text->GetData(data);
      aResult += data;
    }
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 252 of file nsXBLBinding.cpp.

{
  // Find out if we need to re-resolve style.  We'll need to do this
  // if we have additional stylesheets in our binding document.
  if (mPrototypeBinding->HasStyleSheets())
    return PR_TRUE;

  return mNextBinding ? mNextBinding->HasStyleSheets() : PR_FALSE;
}

Here is the call graph for this function:

Definition at line 1337 of file nsXBLBinding.cpp.

{
  return mPrototypeBinding->ImplementsInterface(aIID) ||
    (mNextBinding && mNextBinding->ImplementsInterface(aIID));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 971 of file nsXBLBinding.cpp.

{
  // XXX Will have to change if we ever allow multiple bindings to contribute anonymous content.
  // Most derived binding with anonymous content determines style inheritance for now.

  // XXX What about bindings with <content> but no kids, e.g., my treecell-text binding?
  if (mContent)
    return mPrototypeBinding->InheritsStyle();
  
  if (mNextBinding)
    return mNextBinding->InheritsStyle();

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXBLBinding::InitClass ( const nsCString aClassName,
nsIScriptContext aContext,
nsIDocument aDocument,
void **  aScriptObject,
void **  aClassObject 
) [protected]

Definition at line 1125 of file nsXBLBinding.cpp.

{
  *aClassObject = nsnull;
  *aScriptObject = nsnull;

  nsresult rv;

  // Obtain the bound element's current script object.
  JSContext* cx = (JSContext*)aContext->GetNativeContext();

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

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

    return NS_ERROR_UNEXPECTED;
  }

  nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
  rv = nsContentUtils::XPConnect()->WrapNative(cx, sgo->GetGlobalJSObject(),
                                               mBoundElement,
                                               NS_GET_IID(nsISupports),
                                               getter_AddRefs(wrapper));
  NS_ENSURE_SUCCESS(rv, rv);

  JSObject* object = nsnull;
  rv = wrapper->GetJSObject(&object);
  NS_ENSURE_SUCCESS(rv, rv);

  *aScriptObject = object;

  // First ensure our JS class is initialized.

  rv = DoInitJSClass(cx, sgo->GetGlobalJSObject(), object, aClassName,
                     aClassObject);
  NS_ENSURE_SUCCESS(rv, rv);

  // Root mBoundElement so that it doesn't lose it's binding
  nsIDocument* doc = mBoundElement->GetOwnerDoc();

  if (doc) {
    nsCOMPtr<nsIXPConnectWrappedNative> native_wrapper =
      do_QueryInterface(wrapper);

    if (native_wrapper) {
      NS_DOMClassInfo_PreserveNodeWrapper(native_wrapper);
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

void nsXBLBinding::InstallAnonymousContent ( nsIContent aAnonParent,
nsIContent aElement 
)

Definition at line 193 of file nsXBLBinding.cpp.

{
  // We need to ensure two things.
  // (1) The anonymous content should be fooled into thinking it's in the bound
  // element's document, assuming that the bound element is in a document
  // Note that we don't change the current doc of aAnonParent here, since that
  // quite simply does not matter.  aAnonParent is just a way of keeping refs
  // to all its kids, which are anonymous content from the point of view of
  // aElement.
  // (2) The children's parent back pointer should not be to this synthetic root
  // but should instead point to the enclosing parent element.
  nsIDocument* doc = aElement->GetCurrentDoc();
  PRBool allowScripts = AllowScripts();

  PRUint32 childCount = aAnonParent->GetChildCount();
  for (PRUint32 i = 0; i < childCount; i++) {
    nsIContent *child = aAnonParent->GetChildAt(i);
    child->UnbindFromTree();
    nsresult rv =
      child->BindToTree(doc, aElement, mBoundElement, allowScripts);
    if (NS_FAILED(rv)) {
      // Oh, well... Just give up.
      // XXXbz This really shouldn't be a void method!
      child->UnbindFromTree();
      return;
    }        

#ifdef MOZ_XUL
    // To make XUL templates work (and other goodies that happen when
    // an element is added to a XUL document), we need to notify the
    // XUL document using its special API.
    nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
    if (xuldoc)
      xuldoc->AddSubtreeToDocument(child);
#endif
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 652 of file nsXBLBinding.cpp.

{
  // Don't install handlers if scripts aren't allowed.
  if (AllowScripts()) {
    // Fetch the handlers prototypes for this binding.
    nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();

    if (handlerChain) {
      nsCOMPtr<nsIEventListenerManager> manager;
      mBoundElement->GetListenerManager(getter_AddRefs(manager));
      if (!manager)
        return;

      nsCOMPtr<nsIDOMEventGroup> systemEventGroup;

      nsXBLPrototypeHandler* curr;
      for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
        // Fetch the event type.
        nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
        if (!eventAtom ||
            eventAtom == nsXBLAtoms::keyup ||
            eventAtom == nsXBLAtoms::keydown ||
            eventAtom == nsXBLAtoms::keypress)
          continue;

        nsAutoString type;
        eventAtom->ToString(type);

        // If this is a command, add it in the system event group, otherwise 
        // add it to the standard event group.

        // This is a weak ref. systemEventGroup above is already a
        // strong ref, so we are guaranteed it will not go away.
        nsIDOMEventGroup* eventGroup = nsnull;
        if (curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) {
          if (!systemEventGroup)
            manager->GetSystemEventGroupLM(getter_AddRefs(systemEventGroup));
          eventGroup = systemEventGroup;
        }

        nsXBLEventHandler* handler = curr->GetEventHandler();
        if (handler) {
          // Figure out if we're using capturing or not.
          PRInt32 flags = (curr->GetPhase() == NS_PHASE_CAPTURING) ?
            NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;

          if (curr->AllowUntrustedEvents()) {
            flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
          }

          manager->AddEventListenerByType(handler, type, flags, eventGroup);
        }
      }

      const nsCOMArray<nsXBLKeyEventHandler>* keyHandlers =
        mPrototypeBinding->GetKeyEventHandlers();
      PRInt32 i;
      for (i = 0; i < keyHandlers->Count(); ++i) {
        nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);

        nsAutoString type;
        handler->GetEventName(type);

        // If this is a command, add it in the system event group, otherwise 
        // add it to the standard event group.

        // This is a weak ref. systemEventGroup above is already a
        // strong ref, so we are guaranteed it will not go away.
        nsIDOMEventGroup* eventGroup = nsnull;
        if (handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) {
          if (!systemEventGroup)
            manager->GetSystemEventGroupLM(getter_AddRefs(systemEventGroup));
          eventGroup = systemEventGroup;
        }

        // Figure out if we're using capturing or not.
        PRInt32 flags = (handler->GetPhase() == NS_PHASE_CAPTURING) ?
          NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;

        // For key handlers we have to set NS_PRIV_EVENT_UNTRUSTED_PERMITTED flag.
        // Whether the handling of the event is allowed or not is handled in
        // nsXBLKeyEventHandler::HandleEvent
        flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;

        manager->AddEventListenerByType(handler, type, flags, eventGroup);
      }
    }
  }

  if (mNextBinding)
    mNextBinding->InstallEventHandlers();
}

Here is the call graph for this function:

Definition at line 746 of file nsXBLBinding.cpp.

{
  // Always install the base class properties first, so that
  // derived classes can reference the base class properties.

  if (mNextBinding) {
    nsresult rv = mNextBinding->InstallImplementation();
    NS_ENSURE_SUCCESS(rv, rv);
  }
  
  // iterate through each property in the prototype's list and install the property.
  if (AllowScripts())
    return mPrototypeBinding->InstallImplementation(mBoundElement);

  return NS_OK;
}

Here is the call graph for this function:

Definition at line 100 of file nsXBLBinding.h.

{ return mIsStyleBinding; }

Definition at line 104 of file nsXBLBinding.h.

{ return mMarkedForDeath; }

Here is the caller graph for this function:

Definition at line 1330 of file nsXBLBinding.cpp.

Here is the call graph for this function:

Definition at line 91 of file nsXBLBinding.h.

{ return mPrototypeBinding; }

Here is the caller graph for this function:

Definition at line 79 of file nsXBLBinding.h.

  {
    --mRefCnt;
    NS_LOG_RELEASE(this, mRefCnt, "nsXBLBinding");
    if (mRefCnt == 0) {
      mRefCnt = 1;
      delete this;
      return 0;
    }
    return mRefCnt;
  }

Definition at line 1312 of file nsXBLBinding.cpp.

{
  if (mNextBinding)
    return mNextBinding->RootBinding();

  return this;
}

Here is the caller graph for this function:

Definition at line 182 of file nsXBLBinding.cpp.

{
  if (mNextBinding) {
    NS_ERROR("Base XBL binding is already defined!");
    return;
  }

  mNextBinding = aBinding; // Comptr handles rel/add
}

Here is the caller graph for this function:

Definition at line 232 of file nsXBLBinding.cpp.

{
  mBoundElement = aElement;
  if (mNextBinding)
    mNextBinding->SetBoundElement(aElement);
}

Definition at line 101 of file nsXBLBinding.h.

{ mIsStyleBinding = aIsStyle; }

Here is the caller graph for this function:

Definition at line 1360 of file nsXBLBinding.cpp.

{
  if (mContent)
    return mPrototypeBinding->ShouldBuildChildFrames();

  if (mNextBinding) 
    return mNextBinding->ShouldBuildChildFrames();

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 809 of file nsXBLBinding.cpp.

{
  nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();

  if (handlerChain) {
    nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
    nsCOMPtr<nsIDOM3EventTarget> target = do_QueryInterface(receiver);
    nsCOMPtr<nsIDOMEventGroup> systemEventGroup;

    nsXBLPrototypeHandler* curr;
    for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
      nsXBLEventHandler* handler = curr->GetCachedEventHandler();
      if (handler) {
        nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
        if (!eventAtom ||
            eventAtom == nsXBLAtoms::keyup ||
            eventAtom == nsXBLAtoms::keydown ||
            eventAtom == nsXBLAtoms::keypress)
          continue;

        nsAutoString type;
        eventAtom->ToString(type);

        // Figure out if we're using capturing or not.
        PRBool useCapture = (curr->GetPhase() == NS_PHASE_CAPTURING);

        // If this is a command, remove it from the system event group, otherwise 
        // remove it from the standard event group.

        // This is a weak ref. systemEventGroup above is already a
        // strong ref, so we are guaranteed it will not go away.
        nsIDOMEventGroup* eventGroup = nsnull;
        if (curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) {
          if (!systemEventGroup)
            receiver->GetSystemEventGroup(getter_AddRefs(systemEventGroup));
          eventGroup = systemEventGroup;
        }

        target->RemoveGroupedEventListener(type, handler, useCapture,
                                           eventGroup);
      }
    }

    const nsCOMArray<nsXBLKeyEventHandler>* keyHandlers =
      mPrototypeBinding->GetKeyEventHandlers();
    PRInt32 i;
    for (i = 0; i < keyHandlers->Count(); ++i) {
      nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);

      nsAutoString type;
      handler->GetEventName(type);

      // Figure out if we're using capturing or not.
      PRBool useCapture = (handler->GetPhase() == NS_PHASE_CAPTURING);

      // If this is a command, remove it from the system event group, otherwise 
      // remove it from the standard event group.

      // This is a weak ref. systemEventGroup above is already a
      // strong ref, so we are guaranteed it will not go away.
      nsIDOMEventGroup* eventGroup = nsnull;
      if (handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) {
        if (!systemEventGroup)
          receiver->GetSystemEventGroup(getter_AddRefs(systemEventGroup));
        eventGroup = systemEventGroup;
      }

      target->RemoveGroupedEventListener(type, handler, useCapture,
                                         eventGroup);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXBLBinding::WalkRules ( nsIStyleRuleProcessor::EnumFunc  aFunc,
void aData 
)

Definition at line 987 of file nsXBLBinding.cpp.

{
  if (mNextBinding)
    mNextBinding->WalkRules(aFunc, aData);

  nsIStyleRuleProcessor *rules = mPrototypeBinding->GetRuleProcessor();
  if (rules)
    (*aFunc)(rules, aData);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 164 of file nsXBLBinding.h.

Definition at line 161 of file nsXBLBinding.h.

nsObjectHashtable* nsXBLBinding::mInsertionPointTable [protected]

Definition at line 166 of file nsXBLBinding.h.

Definition at line 168 of file nsXBLBinding.h.

Definition at line 169 of file nsXBLBinding.h.

Definition at line 162 of file nsXBLBinding.h.

Definition at line 160 of file nsXBLBinding.h.

Definition at line 159 of file nsXBLBinding.h.


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