mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1180798 - Pass event names in nsIEventListenerChangeListener r=smaug
This commit is contained in:
parent
dfc1421bdb
commit
f16760445c
@ -398,7 +398,8 @@ EventListenerManager::AddEventListenerInternal(
|
||||
}
|
||||
|
||||
if (mIsMainThreadELM && mTarget) {
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget);
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget,
|
||||
aTypeAtom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,7 +519,8 @@ EventListenerManager::RemoveEventListenerInternal(
|
||||
mTarget->EventListenerRemoved(aUserType);
|
||||
}
|
||||
if (mIsMainThreadELM && mTarget) {
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget);
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget,
|
||||
aUserType);
|
||||
}
|
||||
|
||||
if (!deviceType
|
||||
@ -654,7 +656,7 @@ EventListenerManager::SetEventHandlerInternal(
|
||||
mTarget->EventListenerAdded(aName);
|
||||
}
|
||||
if (mIsMainThreadELM && mTarget) {
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget);
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, aName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,7 +786,7 @@ EventListenerManager::RemoveEventHandler(nsIAtom* aName,
|
||||
mTarget->EventListenerRemoved(aName);
|
||||
}
|
||||
if (mIsMainThreadELM && mTarget) {
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget);
|
||||
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, aName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,44 @@ namespace mozilla {
|
||||
|
||||
using namespace dom;
|
||||
|
||||
/******************************************************************************
|
||||
* mozilla::EventListenerChange
|
||||
******************************************************************************/
|
||||
|
||||
NS_IMPL_ISUPPORTS(EventListenerChange, nsIEventListenerChange)
|
||||
|
||||
EventListenerChange::~EventListenerChange()
|
||||
{
|
||||
}
|
||||
|
||||
EventListenerChange::EventListenerChange(dom::EventTarget* aTarget) :
|
||||
mTarget(aTarget)
|
||||
{
|
||||
mChangedListenerNames = nsArrayBase::Create();
|
||||
}
|
||||
|
||||
void
|
||||
EventListenerChange::AddChangedListenerName(nsIAtom* aEventName)
|
||||
{
|
||||
mChangedListenerNames->AppendElement(aEventName, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
EventListenerChange::GetTarget(nsIDOMEventTarget** aTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
NS_ADDREF(*aTarget = mTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
EventListenerChange::GetChangedListenerNames(nsIArray** aEventNames)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventNames);
|
||||
NS_ADDREF(*aEventNames = mChangedListenerNames);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* mozilla::EventListenerInfo
|
||||
******************************************************************************/
|
||||
@ -323,7 +361,8 @@ EventListenerService::RemoveListenerChangeListener(nsIListenerChangeListener* aL
|
||||
};
|
||||
|
||||
void
|
||||
EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget)
|
||||
EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget,
|
||||
nsIAtom* aName)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mChangeListeners.IsEmpty()) {
|
||||
@ -337,10 +376,13 @@ EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarg
|
||||
NS_DispatchToCurrentThread(runnable);
|
||||
}
|
||||
|
||||
if (!mPendingListenerChangesSet.Get(aTarget)) {
|
||||
mPendingListenerChanges->AppendElement(aTarget, false);
|
||||
mPendingListenerChangesSet.Put(aTarget, true);
|
||||
nsRefPtr<EventListenerChange> changes = mPendingListenerChangesSet.Get(aTarget);
|
||||
if (!changes) {
|
||||
changes = new EventListenerChange(aTarget);
|
||||
mPendingListenerChanges->AppendElement(changes, false);
|
||||
mPendingListenerChangesSet.Put(aTarget, changes);
|
||||
}
|
||||
changes->AddChangedListenerName(aName);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
class nsIMutableArray;
|
||||
|
||||
@ -27,6 +28,23 @@ class EventTarget;
|
||||
template<typename T>
|
||||
class Maybe;
|
||||
|
||||
class EventListenerChange final : public nsIEventListenerChange
|
||||
{
|
||||
public:
|
||||
explicit EventListenerChange(dom::EventTarget* aTarget);
|
||||
|
||||
void AddChangedListenerName(nsIAtom* aEventName);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIEVENTLISTENERCHANGE
|
||||
|
||||
protected:
|
||||
virtual ~EventListenerChange();
|
||||
nsCOMPtr<dom::EventTarget> mTarget;
|
||||
nsCOMPtr<nsIMutableArray> mChangedListenerNames;
|
||||
|
||||
};
|
||||
|
||||
class EventListenerInfo final : public nsIEventListenerInfo
|
||||
{
|
||||
public:
|
||||
@ -70,19 +88,21 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIEVENTLISTENERSERVICE
|
||||
|
||||
static void NotifyAboutMainThreadListenerChange(dom::EventTarget* aTarget)
|
||||
static void NotifyAboutMainThreadListenerChange(dom::EventTarget* aTarget,
|
||||
nsIAtom* aName)
|
||||
{
|
||||
if (sInstance) {
|
||||
sInstance->NotifyAboutMainThreadListenerChangeInternal(aTarget);
|
||||
sInstance->NotifyAboutMainThreadListenerChangeInternal(aTarget, aName);
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyPendingChanges();
|
||||
private:
|
||||
void NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget);
|
||||
void NotifyAboutMainThreadListenerChangeInternal(dom::EventTarget* aTarget,
|
||||
nsIAtom* aName);
|
||||
nsTObserverArray<nsCOMPtr<nsIListenerChangeListener>> mChangeListeners;
|
||||
nsCOMPtr<nsIMutableArray> mPendingListenerChanges;
|
||||
nsDataHashtable<nsISupportsHashKey, bool> mPendingListenerChangesSet;
|
||||
nsDataHashtable<nsISupportsHashKey, nsRefPtr<EventListenerChange>> mPendingListenerChangesSet;
|
||||
|
||||
static EventListenerService* sInstance;
|
||||
};
|
||||
|
@ -9,10 +9,21 @@ interface nsIDOMEventListener;
|
||||
interface nsIDOMEventTarget;
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, function, uuid(8d5b5a6b-dec0-473d-86c4-591801dfaac1)]
|
||||
/**
|
||||
* Contains an event target along with an array of nsIAtom in form "oneventname"
|
||||
* representing changed event listener names.
|
||||
*/
|
||||
[scriptable, uuid(07222b02-da12-4cf4-b2f7-761da007a8d8)]
|
||||
interface nsIEventListenerChange : nsISupports
|
||||
{
|
||||
readonly attribute nsIDOMEventTarget target;
|
||||
readonly attribute nsIArray changedListenerNames;
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(aa7c95f6-d3b5-44b3-9597-1d9f19b9c5f2)]
|
||||
interface nsIListenerChangeListener : nsISupports
|
||||
{
|
||||
void listenersChanged(in nsIArray aEventTargets);
|
||||
void listenersChanged(in nsIArray aEventListenerChanges);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674
|
||||
var els = Components.classes["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Components.interfaces.nsIEventListenerService);
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function dummyListener() {}
|
||||
|
||||
var runningTest = null;
|
||||
@ -35,29 +37,49 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674
|
||||
d.addEventListener("foo", dummyListener);
|
||||
d.addEventListener("foo", dummyListener);
|
||||
xhr.addEventListener("foo", dummyListener);
|
||||
tests[0] = [d, xhr];
|
||||
tests[0] = [{target: d, listeners: ["onfoo"]},
|
||||
{target: xhr, listeners: ["onfoo"]}];
|
||||
},
|
||||
function() {
|
||||
d.addEventListener("bar", dummyListener);
|
||||
d.addEventListener("baz", dummyListener);
|
||||
xhr.addEventListener("bar", dummyListener);
|
||||
xhr.addEventListener("baz", dummyListener);
|
||||
tests[0] = [{target: d, listeners: ["onbaz", "onbar"]},
|
||||
{target: xhr, listeners: ["onbaz", "onbar"]}];
|
||||
},
|
||||
function() {
|
||||
d.onclick = dummyListener;
|
||||
d.onclick = dummyListener;
|
||||
xhr.onload = dummyListener;
|
||||
tests[0] = [d, xhr];
|
||||
tests[0] = [{target: d, listeners: ["onclick"]},
|
||||
{target: xhr, listeners: ["onload"]}];
|
||||
},
|
||||
function() {
|
||||
d.onclick = function() {};
|
||||
tests[0] = [d];
|
||||
tests[0] = [{target: d, listeners: ["onclick"]}];
|
||||
},
|
||||
function() {
|
||||
d.removeEventListener("foo", dummyListener);
|
||||
d.removeEventListener("foo", dummyListener);
|
||||
xhr.removeEventListener("foo", dummyListener);
|
||||
tests[0] = [d, xhr];
|
||||
tests[0] = [{target: d, listeners: ["onfoo"]},
|
||||
{target: xhr, listeners: ["onfoo"]}];
|
||||
},
|
||||
function() {
|
||||
d.removeEventListener("bar", dummyListener);
|
||||
d.removeEventListener("baz", dummyListener);
|
||||
xhr.removeEventListener("bar", dummyListener);
|
||||
xhr.removeEventListener("baz", dummyListener);
|
||||
tests[0] = [{target: d, listeners: ["onbar", "onbaz"]},
|
||||
{target: xhr, listeners: ["onbar", "onbaz"]}];
|
||||
},
|
||||
function() {
|
||||
d.onclick = null;
|
||||
d.onclick = null;
|
||||
xhr.onload = null;
|
||||
tests[0] = [d, xhr];
|
||||
tests[0] = [{target: d, listeners: ["onclick"]},
|
||||
{target: xhr, listeners: ["onload"]}];
|
||||
},
|
||||
function() {
|
||||
els.removeListenerChangeListener(changeListener);
|
||||
@ -76,29 +98,43 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=524674
|
||||
if (typeof tests[0] == "function") {
|
||||
return;
|
||||
}
|
||||
var expectedEventTargets = tests[0];
|
||||
var e = array.enumerate();
|
||||
var expectedEventChanges = tests[0];
|
||||
var eventChanges = array.enumerate();
|
||||
var i = 0;
|
||||
while (e.hasMoreElements()) {
|
||||
while (eventChanges.hasMoreElements() && i < expectedEventChanges.length) {
|
||||
var current;
|
||||
try {
|
||||
current = e.getNext();
|
||||
current = eventChanges.getNext().QueryInterface(Ci.nsIEventListenerChange);
|
||||
var expected = expectedEventChanges[i];
|
||||
|
||||
if (current.target == expected.target) {
|
||||
// expected.target.listeners should be a subset of
|
||||
// current.changedListenerNames if all expected listener changes were
|
||||
// sent. We may get random other event listener changes here too, not
|
||||
// just the one from the test.
|
||||
is(current.target, expected.target, current.target + " = " + expected.target);
|
||||
|
||||
var eNames = current.changedListenerNames.enumerate();
|
||||
var listeners = [];
|
||||
while (eNames.hasMoreElements()) {
|
||||
var listenerName = eNames.getNext().QueryInterface(Ci.nsIAtom).toString();
|
||||
listeners.push(listenerName);
|
||||
}
|
||||
var matchAll = expected.listeners.every(function(val)
|
||||
{ return listeners.indexOf(val) >= 0; });
|
||||
if (!matchAll)
|
||||
return;
|
||||
++i;
|
||||
}
|
||||
} catch(ex) {
|
||||
continue;
|
||||
}
|
||||
var expected = expectedEventTargets[i];
|
||||
if (current == expected) {
|
||||
is(current, expected, current + " = " + expected);
|
||||
// We may get random other event listener changes here too, not just the one from the
|
||||
// test.
|
||||
++i
|
||||
}
|
||||
}
|
||||
if (expectedEventTargets.length != i) {
|
||||
if (expectedEventChanges.length != i) {
|
||||
return;
|
||||
}
|
||||
|
||||
is(expectedEventTargets.length, i, "Should have got notification for all the changes.");
|
||||
is(expectedEventChanges.length, i, "Should have got notification for all the changes.");
|
||||
tests.shift();
|
||||
|
||||
ok(tests.length);
|
||||
|
Loading…
Reference in New Issue
Block a user