mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 17:59:34 +00:00
Bug 484775 - DocumentFragments and Attribute nodes should expose nsIDOMEventTarget to JS, r+sr=peterv
--HG-- extra : rebase_source : 7bce078904782a5a907eebbbff7b74a905cfa8c1
This commit is contained in:
parent
99bd11faa6
commit
4ade0eee29
@ -42,7 +42,6 @@
|
||||
#include "nsCaseTreatment.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIProgrammingLanguage.h" // for ::JAVASCRIPT
|
||||
|
||||
// Forward declarations
|
||||
class nsIAtom;
|
||||
@ -64,8 +63,8 @@ class nsISMILAttr;
|
||||
|
||||
// IID for the nsIContent interface
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0x48cb2d6d, 0x9ccc, 0x4d0b, \
|
||||
{ 0x8c, 0x07, 0x29, 0x96, 0xb5, 0xf9, 0x68, 0x55 } }
|
||||
{ 0x3ca5afbe, 0x1052, 0x4682, \
|
||||
{ 0x9f, 0xa0, 0x0e, 0x39, 0xe4, 0xf8, 0xef, 0x9d } }
|
||||
|
||||
/**
|
||||
* A node of content in a document's content model. This interface
|
||||
@ -755,19 +754,6 @@ public:
|
||||
// PRInt32. We should really use PRUint32 instead.
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
/* The default script type (language) ID for this content.
|
||||
All content must support fetching the default script language.
|
||||
*/
|
||||
virtual PRUint32 GetScriptTypeID() const
|
||||
{ return nsIProgrammingLanguage::JAVASCRIPT; }
|
||||
|
||||
/* Not all content supports setting a new default language */
|
||||
virtual nsresult SetScriptTypeID(PRUint32 aLang)
|
||||
{
|
||||
NS_NOTREACHED("SetScriptTypeID not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of this content node (the atom corresponding to the
|
||||
* value of the null-namespace attribute whose name is given by
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsIProgrammingLanguage.h" // for ::JAVASCRIPT
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
@ -239,8 +240,8 @@ private:
|
||||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
{ 0x7bccc9bd, 0x30eb, 0x47c0, \
|
||||
{ 0x8b, 0xc7, 0x6f, 0x19, 0x75, 0xc8, 0xe7, 0xd7 } }
|
||||
{ 0xfc22c6df, 0x3e8e, 0x47c3, \
|
||||
{ 0x96, 0xa6, 0xaf, 0x14, 0x3c, 0x05, 0x88, 0x68 } }
|
||||
|
||||
/**
|
||||
* An internal interface that abstracts some DOMNode-related parts that both
|
||||
@ -862,6 +863,21 @@ public:
|
||||
nsIContent* const * mEnd;
|
||||
};
|
||||
|
||||
/**
|
||||
* The default script type (language) ID for this node.
|
||||
* All nodes must support fetching the default script language.
|
||||
*/
|
||||
virtual PRUint32 GetScriptTypeID() const
|
||||
{ return nsIProgrammingLanguage::JAVASCRIPT; }
|
||||
|
||||
/**
|
||||
* Not all nodes support setting a new default language.
|
||||
*/
|
||||
NS_IMETHOD SetScriptTypeID(PRUint32 aLang)
|
||||
{
|
||||
NS_NOTREACHED("SetScriptTypeID not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
protected:
|
||||
|
||||
// Override this function to create a custom slots class.
|
||||
|
@ -111,6 +111,12 @@ NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMAttribute)
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
|
||||
new nsNodeSupportsWeakRefTearoff(this))
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget,
|
||||
nsDOMEventRTTearoff::Create(this))
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3EventTarget,
|
||||
nsDOMEventRTTearoff::Create(this))
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
|
||||
nsDOMEventRTTearoff::Create(this))
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(Attr)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@ -731,8 +737,7 @@ nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
nsresult
|
||||
nsDOMAttribute::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// We don't support event dispatching to attributes yet.
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -747,7 +752,9 @@ nsDOMAttribute::DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return nsEventDispatcher::DispatchDOMEvent(static_cast<nsINode*>(this),
|
||||
aEvent, aDOMEvent,
|
||||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1536,8 +1536,8 @@ nsDOMEventRTTearoff::mCachedEventTearoff[NS_EVENT_TEAROFF_CACHE_SIZE];
|
||||
PRUint32 nsDOMEventRTTearoff::mCachedEventTearoffCount = 0;
|
||||
|
||||
|
||||
nsDOMEventRTTearoff::nsDOMEventRTTearoff(nsIContent *aContent)
|
||||
: mContent(aContent)
|
||||
nsDOMEventRTTearoff::nsDOMEventRTTearoff(nsINode *aNode)
|
||||
: mNode(aNode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1545,13 +1545,13 @@ nsDOMEventRTTearoff::~nsDOMEventRTTearoff()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_1(nsDOMEventRTTearoff, mContent)
|
||||
NS_IMPL_CYCLE_COLLECTION_1(nsDOMEventRTTearoff, mNode)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventRTTearoff)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOM3EventTarget)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNSEventTarget)
|
||||
NS_INTERFACE_MAP_END_AGGREGATED(mContent)
|
||||
NS_INTERFACE_MAP_END_AGGREGATED(mNode)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsDOMEventRTTearoff,
|
||||
nsIDOMEventTarget)
|
||||
@ -1560,7 +1560,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS_WITH_DESTROY(nsDOMEventRTTearoff,
|
||||
LastRelease())
|
||||
|
||||
nsDOMEventRTTearoff *
|
||||
nsDOMEventRTTearoff::Create(nsIContent *aContent)
|
||||
nsDOMEventRTTearoff::Create(nsINode *aNode)
|
||||
{
|
||||
if (mCachedEventTearoffCount) {
|
||||
// We have cached unused instances of this class, return a cached
|
||||
@ -1569,13 +1569,13 @@ nsDOMEventRTTearoff::Create(nsIContent *aContent)
|
||||
mCachedEventTearoff[--mCachedEventTearoffCount];
|
||||
|
||||
// Set the back pointer to the content object
|
||||
tearoff->mContent = aContent;
|
||||
tearoff->mNode = aNode;
|
||||
|
||||
return tearoff;
|
||||
}
|
||||
|
||||
// The cache is empty, this means we haveto create a new instance.
|
||||
return new nsDOMEventRTTearoff(aContent);
|
||||
return new nsDOMEventRTTearoff(aNode);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -1600,8 +1600,8 @@ nsDOMEventRTTearoff::LastRelease()
|
||||
// could result in code that grabs a tearoff from the cache and we don't
|
||||
// want to get reused while still being torn down.
|
||||
// See bug 330526.
|
||||
nsCOMPtr<nsIContent> kungFuDeathGrip;
|
||||
kungFuDeathGrip.swap(mContent);
|
||||
nsCOMPtr<nsINode> kungFuDeathGrip;
|
||||
kungFuDeathGrip.swap(mNode);
|
||||
|
||||
// The refcount balancing and destructor re-entrancy protection
|
||||
// code in Release() sets mRefCnt to 1 so we have to set it to 0
|
||||
@ -1619,7 +1619,7 @@ nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv =
|
||||
mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(listener_manager, aTarget);
|
||||
@ -1628,14 +1628,14 @@ nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
|
||||
NS_IMETHODIMP
|
||||
nsDOMEventRTTearoff::GetScriptTypeID(PRUint32 *aLang)
|
||||
{
|
||||
*aLang = mContent->GetScriptTypeID();
|
||||
return NS_OK;
|
||||
*aLang = mNode->GetScriptTypeID();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEventRTTearoff::SetScriptTypeID(PRUint32 aLang)
|
||||
{
|
||||
return mContent->SetScriptTypeID(aLang);
|
||||
return mNode->SetScriptTypeID(aLang);
|
||||
}
|
||||
|
||||
|
||||
@ -1647,7 +1647,7 @@ nsDOMEventRTTearoff::AddEventListener(const nsAString& aType,
|
||||
{
|
||||
return
|
||||
AddEventListener(aType, aListener, useCapture,
|
||||
!nsContentUtils::IsChromeDoc(mContent->GetOwnerDoc()));
|
||||
!nsContentUtils::IsChromeDoc(mNode->GetOwnerDoc()));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1663,7 +1663,7 @@ nsDOMEventRTTearoff::DispatchEvent(nsIDOMEvent *aEvt, PRBool* _retval)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv =
|
||||
mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(listener_manager);
|
||||
NS_ENSURE_STATE(target);
|
||||
@ -1720,7 +1720,7 @@ nsDOMEventRTTearoff::AddEventListener(const nsAString& aType,
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv =
|
||||
mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
@ -3198,7 +3198,7 @@ nsGenericElement::GetScriptTypeID() const
|
||||
return (flags >> NODE_SCRIPT_TYPE_OFFSET) & 0x000F;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsGenericElement::SetScriptTypeID(PRUint32 aLang)
|
||||
{
|
||||
if ((aLang & 0x000F) != aLang) {
|
||||
|
@ -249,7 +249,7 @@ private:
|
||||
// nsDOMEventRTTearoff::Create(). That's why the constructor and
|
||||
// destrucor of this class is private.
|
||||
|
||||
nsDOMEventRTTearoff(nsIContent *aContent);
|
||||
nsDOMEventRTTearoff(nsINode *aNode);
|
||||
|
||||
static nsDOMEventRTTearoff *mCachedEventTearoff[NS_EVENT_TEAROFF_CACHE_SIZE];
|
||||
static PRUint32 mCachedEventTearoffCount;
|
||||
@ -270,7 +270,7 @@ public:
|
||||
* Use this static method to create instances of nsDOMEventRTTearoff.
|
||||
* @param aContent the content to create a tearoff for
|
||||
*/
|
||||
static nsDOMEventRTTearoff *Create(nsIContent *aContent);
|
||||
static nsDOMEventRTTearoff *Create(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Call before shutdown to clear the cache and free memory for this class.
|
||||
@ -297,7 +297,7 @@ private:
|
||||
* Strong reference back to the content object from where an instance of this
|
||||
* class was 'torn off'
|
||||
*/
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
nsCOMPtr<nsINode> mNode;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -426,7 +426,7 @@ public:
|
||||
virtual PRBool MayHaveFrame() const;
|
||||
|
||||
virtual PRUint32 GetScriptTypeID() const;
|
||||
virtual nsresult SetScriptTypeID(PRUint32 aLang);
|
||||
NS_IMETHOD SetScriptTypeID(PRUint32 aLang);
|
||||
|
||||
virtual void DestroyContent();
|
||||
virtual void SaveSubtreeState();
|
||||
|
@ -1284,15 +1284,15 @@ nsEventListenerManager::RemoveEventListener(const nsAString& aType,
|
||||
NS_IMETHODIMP
|
||||
nsEventListenerManager::DispatchEvent(nsIDOMEvent* aEvent, PRBool *_retval)
|
||||
{
|
||||
nsCOMPtr<nsIContent> targetContent(do_QueryInterface(mTarget));
|
||||
if (!targetContent) {
|
||||
nsCOMPtr<nsINode> targetNode(do_QueryInterface(mTarget));
|
||||
if (!targetNode) {
|
||||
// nothing to dispatch on -- bad!
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// XXX sXBL/XBL2 issue -- do we really want the owner here? What
|
||||
// if that's the XBL document? Would we want its presshell? Or what?
|
||||
nsCOMPtr<nsIDocument> document = targetContent->GetOwnerDoc();
|
||||
nsCOMPtr<nsIDocument> document = targetNode->GetOwnerDoc();
|
||||
|
||||
// Do nothing if the element does not belong to a document
|
||||
if (!document) {
|
||||
@ -1308,7 +1308,7 @@ nsEventListenerManager::DispatchEvent(nsIDOMEvent* aEvent, PRBool *_retval)
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsresult rv =
|
||||
nsEventDispatcher::DispatchDOMEvent(targetContent, nsnull, aEvent,
|
||||
nsEventDispatcher::DispatchDOMEvent(targetNode, nsnull, aEvent,
|
||||
context, &status);
|
||||
*_retval = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return rv;
|
||||
|
@ -2050,6 +2050,7 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentFragment)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Element, nsIDOMElement)
|
||||
@ -2064,6 +2065,7 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMAttr)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Attr)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Text, nsIDOMText)
|
||||
|
@ -97,6 +97,7 @@ _TEST_FILES = \
|
||||
iframe_bug463000.html \
|
||||
test_bug465263.html \
|
||||
test_bug479143.html \
|
||||
test_bug484775.html \
|
||||
test_bug427744.html \
|
||||
$(NULL)
|
||||
|
||||
|
53
dom/tests/mochitest/bugs/test_bug484775.html
Normal file
53
dom/tests/mochitest/bugs/test_bug484775.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=484775
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 484775</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=484775">Mozilla Bug 484775</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 484775 **/
|
||||
|
||||
var expectedTarget = null;
|
||||
var expectedType = null;
|
||||
var eventCount = 0;
|
||||
|
||||
function listener(evt) {
|
||||
++eventCount;
|
||||
ok(evt.type, expectedType, "Wrong event type!");
|
||||
ok(evt.target, expectedTarget, "Wrong event type!");
|
||||
}
|
||||
|
||||
expectedType = "TestEvent";
|
||||
var event = document.createEvent("Event");
|
||||
event.initEvent(expectedType, true, true);
|
||||
ok(event.type, expectedType, "Wrong event type!");
|
||||
|
||||
var attr = document.createAttribute("attribute");
|
||||
attr.addEventListener(expectedType, listener, false);
|
||||
attr.dispatchEvent(event);
|
||||
is(eventCount, 1, "Should have fired an event!");
|
||||
attr.removeEventListener(expectedType, listener, false);
|
||||
|
||||
var df = document.createDocumentFragment();
|
||||
df.addEventListener(expectedType, listener, false);
|
||||
df.dispatchEvent(event);
|
||||
is(eventCount, 2, "Should have fired an event!");
|
||||
df.removeEventListener(expectedType, listener, false);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user