mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-14 18:51:28 +00:00
new XBL features
This commit is contained in:
parent
8ebf3d0720
commit
91f9dc53a1
@ -56,6 +56,8 @@ public:
|
||||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement) = 0;
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement) = 0;
|
||||
|
||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult) = 0;
|
||||
|
||||
// Called when an attribute changes on a binding.
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag) = 0;
|
||||
|
||||
|
@ -51,6 +51,10 @@ public:
|
||||
// For a given element, returns a flat list of all the anonymous children that need
|
||||
// frames built.
|
||||
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult) = 0;
|
||||
|
||||
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
|
||||
NS_IMETHOD GetBaseTag(nsIContent* aContent, nsIAtom** aResult) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // nsIXBLService_h__
|
||||
|
@ -14,11 +14,13 @@
|
||||
#include "plstr.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIXMLContentSink.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsXMLDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsINameSpace.h"
|
||||
|
||||
// Event listeners
|
||||
#include "nsIDOMMouseListener.h"
|
||||
@ -31,11 +33,14 @@
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsIXBLBinding.h"
|
||||
|
||||
// Static IIDs/CIDs. Try to minimize these.
|
||||
// None
|
||||
static char kNameSpaceSeparator = ':';
|
||||
|
||||
// Helper classes
|
||||
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
||||
@ -86,6 +91,8 @@ class nsXBLBinding: public nsIXBLBinding
|
||||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement);
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement);
|
||||
|
||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag);
|
||||
|
||||
public:
|
||||
@ -102,6 +109,7 @@ public:
|
||||
static nsIAtom* kInheritsAtom;
|
||||
static nsIAtom* kTypeAtom;
|
||||
static nsIAtom* kCapturerAtom;
|
||||
static nsIAtom* kExtendsAtom;
|
||||
|
||||
// Used to easily obtain the correct IID for an event.
|
||||
struct EventHandlerMapEntry {
|
||||
@ -145,6 +153,7 @@ nsIAtom* nsXBLBinding::kExcludesAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kTypeAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kCapturerAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
|
||||
|
||||
nsXBLBinding::EventHandlerMapEntry
|
||||
nsXBLBinding::kEventHandlerMap[] = {
|
||||
@ -212,6 +221,7 @@ nsXBLBinding::nsXBLBinding(void)
|
||||
kInheritsAtom = NS_NewAtom("inherits");
|
||||
kTypeAtom = NS_NewAtom("type");
|
||||
kCapturerAtom = NS_NewAtom("capturer");
|
||||
kExtendsAtom = NS_NewAtom("extends");
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
@ -234,6 +244,7 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||
NS_RELEASE(kInheritsAtom);
|
||||
NS_RELEASE(kTypeAtom);
|
||||
NS_RELEASE(kCapturerAtom);
|
||||
NS_RELEASE(kExtendsAtom);
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
@ -331,6 +342,32 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
||||
else return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIDOMNamedNodeMap> namedMap;
|
||||
|
||||
node->GetAttributes(getter_AddRefs(namedMap));
|
||||
PRUint32 length;
|
||||
namedMap->GetLength(&length);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> attribute;
|
||||
for (PRUint32 i = 0; i < length; ++i)
|
||||
{
|
||||
namedMap->Item(i, getter_AddRefs(attribute));
|
||||
nsCOMPtr<nsIDOMAttr> attr(do_QueryInterface(attribute));
|
||||
nsAutoString name;
|
||||
attr->GetName(name);
|
||||
if (name != L"excludes") {
|
||||
nsAutoString value;
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mBoundElement));
|
||||
element->GetAttribute(name, value);
|
||||
if (value == "") {
|
||||
nsAutoString value2;
|
||||
attr->GetValue(value2);
|
||||
element->SetAttribute(name, value2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Plan to build the content by default.
|
||||
PRBool buildContent = PR_TRUE;
|
||||
PRInt32 childCount;
|
||||
@ -382,58 +419,57 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement)
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||
|
||||
if (!handlers)
|
||||
return NS_OK;
|
||||
if (handlers) {
|
||||
// Now walk the handlers and add event listeners to the bound
|
||||
// element.
|
||||
PRInt32 childCount;
|
||||
handlers->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
handlers->ChildAt(i, *getter_AddRefs(child));
|
||||
|
||||
// Now walk the handlers and add event listeners to the bound
|
||||
// element.
|
||||
PRInt32 childCount;
|
||||
handlers->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
handlers->ChildAt(i, *getter_AddRefs(child));
|
||||
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kTypeAtom, type);
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kTypeAtom, type);
|
||||
|
||||
if (type != "") {
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
PRBool found = PR_FALSE;
|
||||
nsIID iid;
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
if (found) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
if (type != "") {
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
PRBool found = PR_FALSE;
|
||||
nsIID iid;
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
if (found) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
|
||||
if (mouse || key || xul) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(mBoundElement, child, type, &handler);
|
||||
if (mouse || key || xul) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(mBoundElement, child, type, &handler);
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kCapturerAtom, capturer);
|
||||
if (capturer == "true")
|
||||
useCapture = PR_TRUE;
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kCapturerAtom, capturer);
|
||||
if (capturer == "true")
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
// Add the event listener.
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else
|
||||
receiver->AddEventListener(type, (nsIDOMMenuListener*)handler, useCapture);
|
||||
// Add the event listener.
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else
|
||||
receiver->AddEventListener(type, (nsIDOMMenuListener*)handler, useCapture);
|
||||
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
|
||||
// XXX Call AddScriptEventListener for other IID types
|
||||
// XXX Call AddScriptEventListener for other IID types
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -444,6 +480,49 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::GetBaseTag(nsIAtom** aResult)
|
||||
{
|
||||
if (mNextBinding)
|
||||
return mNextBinding->GetBaseTag(aResult);
|
||||
|
||||
// XXX Cache the value as a "base" attribute so that we don't do this
|
||||
// check over and over each time the bound element occurs.
|
||||
|
||||
// We are the base binding. Obtain the extends attribute.
|
||||
nsAutoString extends;
|
||||
mBinding->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
||||
|
||||
if (extends != "") {
|
||||
// Obtain the namespace prefix.
|
||||
nsAutoString prefix;
|
||||
PRInt32 offset = extends.FindChar(kNameSpaceSeparator);
|
||||
if (-1 != offset) {
|
||||
extends.Left(prefix, offset);
|
||||
extends.Cut(0, offset+1);
|
||||
}
|
||||
if (prefix.Length() > 0) {
|
||||
// Look up the prefix.
|
||||
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
||||
nsCOMPtr<nsINameSpace> nameSpace;
|
||||
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(mBinding));
|
||||
if (xmlContent) {
|
||||
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
||||
|
||||
nsCOMPtr<nsINameSpace> tagSpace;
|
||||
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
||||
if (tagSpace) {
|
||||
// Score! Return the tag.
|
||||
// XXX We should really return the namespace as well.
|
||||
*aResult = NS_NewAtom(extends); // The addref happens here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
||||
{
|
||||
|
@ -98,6 +98,9 @@ class nsXBLService: public nsIXBLService
|
||||
// frames built.
|
||||
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult);
|
||||
|
||||
// Gets the object's base class type.
|
||||
NS_IMETHOD GetBaseTag(nsIContent* aContent, nsIAtom** aResult);
|
||||
|
||||
public:
|
||||
nsXBLService();
|
||||
virtual ~nsXBLService();
|
||||
@ -279,6 +282,7 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult)
|
||||
|
||||
(*aResult)->AppendElement(anonymousChild);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXBLBinding> nextBinding;
|
||||
@ -288,6 +292,16 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::GetBaseTag(nsIContent* aContent, nsIAtom** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
nsCOMPtr<nsIBindableContent> bindable = do_QueryInterface(aContent);
|
||||
if (!bindable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return bindable->GetBaseTag(aResult);
|
||||
}
|
||||
|
||||
// Internal helper methods ////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -344,13 +358,18 @@ NS_IMETHODIMP nsXBLService::GetBinding(nsCAutoString& aURLStr, nsIXBLBinding** a
|
||||
// Check for the presence of an extends attribute
|
||||
child->GetAttribute(kNameSpaceID_None, kExtendsAtom, value);
|
||||
if (value != "") {
|
||||
// We have a base class binding. Load it right now.
|
||||
nsCOMPtr<nsIXBLBinding> baseBinding;
|
||||
nsCAutoString url = value;
|
||||
GetBinding(url, getter_AddRefs(baseBinding));
|
||||
if (!baseBinding)
|
||||
return NS_OK; // At least we got the derived class binding loaded.
|
||||
(*aResult)->SetBaseBinding(baseBinding);
|
||||
// See if we are extending a builtin tag.
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
(*aResult)->GetBaseTag(getter_AddRefs(tag));
|
||||
if (!tag) {
|
||||
// We have a base class binding. Load it right now.
|
||||
nsCOMPtr<nsIXBLBinding> baseBinding;
|
||||
nsCAutoString url = value;
|
||||
GetBinding(url, getter_AddRefs(baseBinding));
|
||||
if (!baseBinding)
|
||||
return NS_OK; // At least we got the derived class binding loaded.
|
||||
(*aResult)->SetBaseBinding(baseBinding);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
class nsIContent;
|
||||
class nsIXBLBinding;
|
||||
class nsIAtom;
|
||||
|
||||
// {55D70FE0-C8E5-11d3-97FB-00400553EEF0}
|
||||
#define NS_IBINDABLE_CONTENT_IID \
|
||||
@ -46,6 +47,8 @@ public:
|
||||
|
||||
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding) = 0;
|
||||
NS_IMETHOD GetBinding(nsIXBLBinding** aResult) = 0;
|
||||
|
||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult) = 0;
|
||||
};
|
||||
|
||||
#endif // nsIBINDABLE_CONTENT_h__
|
||||
|
@ -56,6 +56,8 @@ public:
|
||||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement) = 0;
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement) = 0;
|
||||
|
||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult) = 0;
|
||||
|
||||
// Called when an attribute changes on a binding.
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag) = 0;
|
||||
|
||||
|
@ -51,6 +51,10 @@ public:
|
||||
// For a given element, returns a flat list of all the anonymous children that need
|
||||
// frames built.
|
||||
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult) = 0;
|
||||
|
||||
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
|
||||
NS_IMETHOD GetBaseTag(nsIContent* aContent, nsIAtom** aResult) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // nsIXBLService_h__
|
||||
|
@ -14,11 +14,13 @@
|
||||
#include "plstr.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIXMLContent.h"
|
||||
#include "nsIXMLContentSink.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsXMLDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsINameSpace.h"
|
||||
|
||||
// Event listeners
|
||||
#include "nsIDOMMouseListener.h"
|
||||
@ -31,11 +33,14 @@
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsIXBLBinding.h"
|
||||
|
||||
// Static IIDs/CIDs. Try to minimize these.
|
||||
// None
|
||||
static char kNameSpaceSeparator = ':';
|
||||
|
||||
// Helper classes
|
||||
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
||||
@ -86,6 +91,8 @@ class nsXBLBinding: public nsIXBLBinding
|
||||
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement);
|
||||
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement);
|
||||
|
||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag);
|
||||
|
||||
public:
|
||||
@ -102,6 +109,7 @@ public:
|
||||
static nsIAtom* kInheritsAtom;
|
||||
static nsIAtom* kTypeAtom;
|
||||
static nsIAtom* kCapturerAtom;
|
||||
static nsIAtom* kExtendsAtom;
|
||||
|
||||
// Used to easily obtain the correct IID for an event.
|
||||
struct EventHandlerMapEntry {
|
||||
@ -145,6 +153,7 @@ nsIAtom* nsXBLBinding::kExcludesAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kTypeAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kCapturerAtom = nsnull;
|
||||
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
|
||||
|
||||
nsXBLBinding::EventHandlerMapEntry
|
||||
nsXBLBinding::kEventHandlerMap[] = {
|
||||
@ -212,6 +221,7 @@ nsXBLBinding::nsXBLBinding(void)
|
||||
kInheritsAtom = NS_NewAtom("inherits");
|
||||
kTypeAtom = NS_NewAtom("type");
|
||||
kCapturerAtom = NS_NewAtom("capturer");
|
||||
kExtendsAtom = NS_NewAtom("extends");
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
@ -234,6 +244,7 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||
NS_RELEASE(kInheritsAtom);
|
||||
NS_RELEASE(kTypeAtom);
|
||||
NS_RELEASE(kCapturerAtom);
|
||||
NS_RELEASE(kExtendsAtom);
|
||||
|
||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||
while (entry->mAttributeName) {
|
||||
@ -331,6 +342,32 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
||||
else return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIDOMNamedNodeMap> namedMap;
|
||||
|
||||
node->GetAttributes(getter_AddRefs(namedMap));
|
||||
PRUint32 length;
|
||||
namedMap->GetLength(&length);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> attribute;
|
||||
for (PRUint32 i = 0; i < length; ++i)
|
||||
{
|
||||
namedMap->Item(i, getter_AddRefs(attribute));
|
||||
nsCOMPtr<nsIDOMAttr> attr(do_QueryInterface(attribute));
|
||||
nsAutoString name;
|
||||
attr->GetName(name);
|
||||
if (name != L"excludes") {
|
||||
nsAutoString value;
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mBoundElement));
|
||||
element->GetAttribute(name, value);
|
||||
if (value == "") {
|
||||
nsAutoString value2;
|
||||
attr->GetValue(value2);
|
||||
element->SetAttribute(name, value2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Plan to build the content by default.
|
||||
PRBool buildContent = PR_TRUE;
|
||||
PRInt32 childCount;
|
||||
@ -382,58 +419,57 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement)
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||
|
||||
if (!handlers)
|
||||
return NS_OK;
|
||||
if (handlers) {
|
||||
// Now walk the handlers and add event listeners to the bound
|
||||
// element.
|
||||
PRInt32 childCount;
|
||||
handlers->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
handlers->ChildAt(i, *getter_AddRefs(child));
|
||||
|
||||
// Now walk the handlers and add event listeners to the bound
|
||||
// element.
|
||||
PRInt32 childCount;
|
||||
handlers->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
handlers->ChildAt(i, *getter_AddRefs(child));
|
||||
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kTypeAtom, type);
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kTypeAtom, type);
|
||||
|
||||
if (type != "") {
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
PRBool found = PR_FALSE;
|
||||
nsIID iid;
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
if (found) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
if (type != "") {
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
PRBool found = PR_FALSE;
|
||||
nsIID iid;
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
if (found) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
|
||||
if (mouse || key || xul) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(mBoundElement, child, type, &handler);
|
||||
if (mouse || key || xul) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(mBoundElement, child, type, &handler);
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kCapturerAtom, capturer);
|
||||
if (capturer == "true")
|
||||
useCapture = PR_TRUE;
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kCapturerAtom, capturer);
|
||||
if (capturer == "true")
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
// Add the event listener.
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else
|
||||
receiver->AddEventListener(type, (nsIDOMMenuListener*)handler, useCapture);
|
||||
// Add the event listener.
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else
|
||||
receiver->AddEventListener(type, (nsIDOMMenuListener*)handler, useCapture);
|
||||
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
|
||||
// XXX Call AddScriptEventListener for other IID types
|
||||
// XXX Call AddScriptEventListener for other IID types
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -444,6 +480,49 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::GetBaseTag(nsIAtom** aResult)
|
||||
{
|
||||
if (mNextBinding)
|
||||
return mNextBinding->GetBaseTag(aResult);
|
||||
|
||||
// XXX Cache the value as a "base" attribute so that we don't do this
|
||||
// check over and over each time the bound element occurs.
|
||||
|
||||
// We are the base binding. Obtain the extends attribute.
|
||||
nsAutoString extends;
|
||||
mBinding->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
||||
|
||||
if (extends != "") {
|
||||
// Obtain the namespace prefix.
|
||||
nsAutoString prefix;
|
||||
PRInt32 offset = extends.FindChar(kNameSpaceSeparator);
|
||||
if (-1 != offset) {
|
||||
extends.Left(prefix, offset);
|
||||
extends.Cut(0, offset+1);
|
||||
}
|
||||
if (prefix.Length() > 0) {
|
||||
// Look up the prefix.
|
||||
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
||||
nsCOMPtr<nsINameSpace> nameSpace;
|
||||
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(mBinding));
|
||||
if (xmlContent) {
|
||||
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
||||
|
||||
nsCOMPtr<nsINameSpace> tagSpace;
|
||||
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
||||
if (tagSpace) {
|
||||
// Score! Return the tag.
|
||||
// XXX We should really return the namespace as well.
|
||||
*aResult = NS_NewAtom(extends); // The addref happens here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
||||
{
|
||||
|
@ -98,6 +98,9 @@ class nsXBLService: public nsIXBLService
|
||||
// frames built.
|
||||
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult);
|
||||
|
||||
// Gets the object's base class type.
|
||||
NS_IMETHOD GetBaseTag(nsIContent* aContent, nsIAtom** aResult);
|
||||
|
||||
public:
|
||||
nsXBLService();
|
||||
virtual ~nsXBLService();
|
||||
@ -279,6 +282,7 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult)
|
||||
|
||||
(*aResult)->AppendElement(anonymousChild);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXBLBinding> nextBinding;
|
||||
@ -288,6 +292,16 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::GetBaseTag(nsIContent* aContent, nsIAtom** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
nsCOMPtr<nsIBindableContent> bindable = do_QueryInterface(aContent);
|
||||
if (!bindable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return bindable->GetBaseTag(aResult);
|
||||
}
|
||||
|
||||
// Internal helper methods ////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -344,13 +358,18 @@ NS_IMETHODIMP nsXBLService::GetBinding(nsCAutoString& aURLStr, nsIXBLBinding** a
|
||||
// Check for the presence of an extends attribute
|
||||
child->GetAttribute(kNameSpaceID_None, kExtendsAtom, value);
|
||||
if (value != "") {
|
||||
// We have a base class binding. Load it right now.
|
||||
nsCOMPtr<nsIXBLBinding> baseBinding;
|
||||
nsCAutoString url = value;
|
||||
GetBinding(url, getter_AddRefs(baseBinding));
|
||||
if (!baseBinding)
|
||||
return NS_OK; // At least we got the derived class binding loaded.
|
||||
(*aResult)->SetBaseBinding(baseBinding);
|
||||
// See if we are extending a builtin tag.
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
(*aResult)->GetBaseTag(getter_AddRefs(tag));
|
||||
if (!tag) {
|
||||
// We have a base class binding. Load it right now.
|
||||
nsCOMPtr<nsIXBLBinding> baseBinding;
|
||||
nsCAutoString url = value;
|
||||
GetBinding(url, getter_AddRefs(baseBinding));
|
||||
if (!baseBinding)
|
||||
return NS_OK; // At least we got the derived class binding loaded.
|
||||
(*aResult)->SetBaseBinding(baseBinding);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user