зеркало из https://github.com/mozilla/gecko-dev.git
backout bug 1236979 (changesets 2f4de652525e, d7136545a16e, f62e6638add1, f8b1e085b161) for xpcshell test failures
This commit is contained in:
Родитель
13208cc3e7
Коммит
2eb04f5120
|
@ -931,10 +931,6 @@ GK_ATOM(onupgradeneeded, "onupgradeneeded")
|
|||
GK_ATOM(onussdreceived, "onussdreceived")
|
||||
GK_ATOM(onversionchange, "onversionchange")
|
||||
GK_ATOM(onvoicechange, "onvoicechange")
|
||||
GK_ATOM(onwebkitAnimationEnd, "onwebkitAnimationEnd")
|
||||
GK_ATOM(onwebkitAnimationIteration, "onwebkitAnimationIteration")
|
||||
GK_ATOM(onwebkitAnimationStart, "onwebkitAnimationStart")
|
||||
GK_ATOM(onwebkitTransitionEnd, "onwebkitTransitionEnd")
|
||||
GK_ATOM(onwheel, "onwheel")
|
||||
GK_ATOM(open, "open")
|
||||
GK_ATOM(optgroup, "optgroup")
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
class EventTarget;
|
||||
class EventMessageAutoOverride;
|
||||
class WantsPopupControlCheck;
|
||||
#define GENERATED_EVENT(EventClass_) class EventClass_;
|
||||
#include "mozilla/dom/GeneratedEventList.h"
|
||||
|
@ -240,7 +239,6 @@ protected:
|
|||
void SetEventType(const nsAString& aEventTypeArg);
|
||||
already_AddRefed<nsIContent> GetTargetFromFrame();
|
||||
|
||||
friend class EventMessageAutoOverride;
|
||||
friend class WantsPopupControlCheck;
|
||||
void SetWantsPopupControlCheck(bool aCheck)
|
||||
{
|
||||
|
@ -270,48 +268,6 @@ protected:
|
|||
bool mWantsPopupControlCheck;
|
||||
};
|
||||
|
||||
/**
|
||||
* RAII helper-class to override an event's message (i.e. its DOM-exposed
|
||||
* type), for as long as the object is alive. Restores the original
|
||||
* EventMessage when destructed.
|
||||
*
|
||||
* Notable requirements:
|
||||
* - The original & overriding messages must be known (not eUnidentifiedEvent).
|
||||
* - The original & overriding messages must be different.
|
||||
* - The passed-in nsIDOMEvent must outlive this RAII helper.
|
||||
*/
|
||||
class MOZ_RAII EventMessageAutoOverride
|
||||
{
|
||||
public:
|
||||
explicit EventMessageAutoOverride(nsIDOMEvent* aEvent,
|
||||
EventMessage aOverridingMessage)
|
||||
: mEvent(aEvent->InternalDOMEvent()),
|
||||
mOrigMessage(mEvent->mEvent->mMessage)
|
||||
{
|
||||
MOZ_ASSERT(aOverridingMessage != mOrigMessage,
|
||||
"Don't use this class if you're not actually overriding");
|
||||
MOZ_ASSERT(aOverridingMessage != eUnidentifiedEvent,
|
||||
"Only use this class with a valid overriding EventMessage");
|
||||
MOZ_ASSERT(mOrigMessage != eUnidentifiedEvent &&
|
||||
mEvent->mEvent->typeString.IsEmpty(),
|
||||
"Only use this class on events whose overridden type is "
|
||||
"known (so we can restore it properly)");
|
||||
|
||||
mEvent->mEvent->mMessage = aOverridingMessage;
|
||||
}
|
||||
|
||||
~EventMessageAutoOverride()
|
||||
{
|
||||
mEvent->mEvent->mMessage = mOrigMessage;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Non-owning ref, which should be safe since we're a stack-allocated object
|
||||
// with limited lifetime. Whoever creates us should keep mEvent alive.
|
||||
Event* const MOZ_NON_OWNING_REF mEvent;
|
||||
const EventMessage mOrigMessage;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS WantsPopupControlCheck
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -19,9 +19,7 @@
|
|||
#include "mozilla/HalSensor.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
|
@ -97,46 +95,6 @@ MutationBitForEventType(EventMessage aEventType)
|
|||
|
||||
uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
|
||||
|
||||
static bool
|
||||
IsWebkitPrefixSupportEnabled()
|
||||
{
|
||||
static bool sIsWebkitPrefixSupportEnabled;
|
||||
static bool sIsPrefCached = false;
|
||||
|
||||
if (!sIsPrefCached) {
|
||||
sIsPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sIsWebkitPrefixSupportEnabled,
|
||||
"layout.css.prefixes.webkit");
|
||||
}
|
||||
|
||||
return sIsWebkitPrefixSupportEnabled;
|
||||
}
|
||||
|
||||
// If the given EventMessage has a legacy version that we support, then this
|
||||
// function returns that legacy version. Otherwise, this function simply
|
||||
// returns the passed-in EventMessage.
|
||||
EventMessage
|
||||
GetLegacyEventMessage(EventMessage aEventMessage)
|
||||
{
|
||||
if (IsWebkitPrefixSupportEnabled()) {
|
||||
// webkit-prefixed legacy events:
|
||||
if (aEventMessage == eTransitionEnd) {
|
||||
return eWebkitTransitionEnd;
|
||||
}
|
||||
if (aEventMessage == eAnimationStart) {
|
||||
return eWebkitAnimationStart;
|
||||
}
|
||||
if (aEventMessage == eAnimationEnd) {
|
||||
return eWebkitAnimationEnd;
|
||||
}
|
||||
if (aEventMessage == eAnimationIteration) {
|
||||
return eWebkitAnimationIteration;
|
||||
}
|
||||
}
|
||||
|
||||
return aEventMessage;
|
||||
}
|
||||
|
||||
EventListenerManagerBase::EventListenerManagerBase()
|
||||
: mNoListenerForEvent(eVoidEvent)
|
||||
, mMayHavePaintEventListener(false)
|
||||
|
@ -645,15 +603,9 @@ EventListenerManager::RemoveEventListenerInternal(
|
|||
}
|
||||
|
||||
bool
|
||||
EventListenerManager::ListenerCanHandle(const Listener* aListener,
|
||||
const WidgetEvent* aEvent,
|
||||
EventMessage aEventMessage) const
|
||||
|
||||
EventListenerManager::ListenerCanHandle(Listener* aListener,
|
||||
WidgetEvent* aEvent)
|
||||
{
|
||||
MOZ_ASSERT(aEventMessage == aEvent->mMessage ||
|
||||
aEventMessage == GetLegacyEventMessage(aEvent->mMessage),
|
||||
"aEvent and aEventMessage should agree, modulo legacyness");
|
||||
|
||||
// This is slightly different from EVENT_TYPE_EQUALS in that it returns
|
||||
// true even when aEvent->mMessage == eUnidentifiedEvent and
|
||||
// aListener=>mEventMessage != eUnidentifiedEvent as long as the atoms are
|
||||
|
@ -668,7 +620,7 @@ EventListenerManager::ListenerCanHandle(const Listener* aListener,
|
|||
return aListener->mTypeString.Equals(aEvent->typeString);
|
||||
}
|
||||
MOZ_ASSERT(mIsMainThreadELM);
|
||||
return aListener->mEventMessage == aEventMessage;
|
||||
return aListener->mEventMessage == aEvent->mMessage;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1152,107 +1104,77 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||
aEvent->mFlags.mDefaultPrevented = true;
|
||||
}
|
||||
|
||||
nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners);
|
||||
Maybe<nsAutoPopupStatePusher> popupStatePusher;
|
||||
if (mIsMainThreadELM) {
|
||||
popupStatePusher.emplace(Event::GetEventPopupControlState(aEvent, *aDOMEvent));
|
||||
}
|
||||
|
||||
bool hasListener = false;
|
||||
bool usingLegacyMessage = false;
|
||||
EventMessage eventMessage = aEvent->mMessage;
|
||||
|
||||
while (true) {
|
||||
nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners);
|
||||
Maybe<EventMessageAutoOverride> legacyAutoOverride;
|
||||
while (iter.HasMore()) {
|
||||
if (aEvent->mFlags.mImmediatePropagationStopped) {
|
||||
break;
|
||||
}
|
||||
Listener* listener = &iter.GetNext();
|
||||
// Check that the phase is same in event and event listener.
|
||||
// Handle only trusted events, except when listener permits untrusted events.
|
||||
if (ListenerCanHandle(listener, aEvent, eventMessage)) {
|
||||
hasListener = true;
|
||||
if (listener->IsListening(aEvent) &&
|
||||
(aEvent->mFlags.mIsTrusted ||
|
||||
listener->mFlags.mAllowUntrustedEvents)) {
|
||||
if (!*aDOMEvent) {
|
||||
// This is tiny bit slow, but happens only once per event.
|
||||
nsCOMPtr<EventTarget> et =
|
||||
do_QueryInterface(aEvent->originalTarget);
|
||||
RefPtr<Event> event = EventDispatcher::CreateEvent(et, aPresContext,
|
||||
while (iter.HasMore()) {
|
||||
if (aEvent->mFlags.mImmediatePropagationStopped) {
|
||||
break;
|
||||
}
|
||||
Listener* listener = &iter.GetNext();
|
||||
// Check that the phase is same in event and event listener.
|
||||
// Handle only trusted events, except when listener permits untrusted events.
|
||||
if (ListenerCanHandle(listener, aEvent)) {
|
||||
hasListener = true;
|
||||
if (listener->IsListening(aEvent) &&
|
||||
(aEvent->mFlags.mIsTrusted ||
|
||||
listener->mFlags.mAllowUntrustedEvents)) {
|
||||
if (!*aDOMEvent) {
|
||||
// This is tiny bit slow, but happens only once per event.
|
||||
nsCOMPtr<EventTarget> et =
|
||||
do_QueryInterface(aEvent->originalTarget);
|
||||
RefPtr<Event> event = EventDispatcher::CreateEvent(et, aPresContext,
|
||||
aEvent,
|
||||
EmptyString());
|
||||
event.forget(aDOMEvent);
|
||||
}
|
||||
if (*aDOMEvent) {
|
||||
event.forget(aDOMEvent);
|
||||
}
|
||||
if (*aDOMEvent) {
|
||||
if (!aEvent->currentTarget) {
|
||||
aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
|
||||
if (!aEvent->currentTarget) {
|
||||
aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
|
||||
if (!aEvent->currentTarget) {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe add a marker to the docshell's timeline, but only
|
||||
// bother with all the logic if some docshell is recording.
|
||||
nsDocShell* docShell;
|
||||
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
|
||||
bool needsEndEventMarker = false;
|
||||
|
||||
if (mIsMainThreadELM &&
|
||||
listener->mListenerType != Listener::eNativeListener) {
|
||||
nsCOMPtr<nsIDocShell> docShellComPtr = GetDocShellForTarget();
|
||||
if (docShellComPtr) {
|
||||
docShell = static_cast<nsDocShell*>(docShellComPtr.get());
|
||||
if (timelines && timelines->HasConsumer(docShell)) {
|
||||
needsEndEventMarker = true;
|
||||
nsAutoString typeStr;
|
||||
(*aDOMEvent)->GetType(typeStr);
|
||||
uint16_t phase;
|
||||
(*aDOMEvent)->GetEventPhase(&phase);
|
||||
timelines->AddMarkerForDocShell(docShell, Move(
|
||||
MakeUnique<EventTimelineMarker>(
|
||||
typeStr, phase, MarkerTracingType::START)));
|
||||
}
|
||||
}
|
||||
if (usingLegacyMessage && !legacyAutoOverride) {
|
||||
// Override the aDOMEvent's event-message (its .type) until we
|
||||
// finish traversing listeners (when legacyAutoOverride destructs)
|
||||
legacyAutoOverride.emplace(*aDOMEvent, eventMessage);
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe add a marker to the docshell's timeline, but only
|
||||
// bother with all the logic if some docshell is recording.
|
||||
nsDocShell* docShell;
|
||||
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
|
||||
bool needsEndEventMarker = false;
|
||||
if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
|
||||
aEvent->mFlags.mExceptionHasBeenRisen = true;
|
||||
}
|
||||
|
||||
if (mIsMainThreadELM &&
|
||||
listener->mListenerType != Listener::eNativeListener) {
|
||||
nsCOMPtr<nsIDocShell> docShellComPtr = GetDocShellForTarget();
|
||||
if (docShellComPtr) {
|
||||
docShell = static_cast<nsDocShell*>(docShellComPtr.get());
|
||||
if (timelines && timelines->HasConsumer(docShell)) {
|
||||
needsEndEventMarker = true;
|
||||
nsAutoString typeStr;
|
||||
(*aDOMEvent)->GetType(typeStr);
|
||||
uint16_t phase;
|
||||
(*aDOMEvent)->GetEventPhase(&phase);
|
||||
timelines->AddMarkerForDocShell(docShell, Move(
|
||||
MakeUnique<EventTimelineMarker>(
|
||||
typeStr, phase, MarkerTracingType::START)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
|
||||
aEvent->mFlags.mExceptionHasBeenRisen = true;
|
||||
}
|
||||
|
||||
if (needsEndEventMarker) {
|
||||
timelines->AddMarkerForDocShell(
|
||||
docShell, "DOMEvent", MarkerTracingType::END);
|
||||
}
|
||||
if (needsEndEventMarker) {
|
||||
timelines->AddMarkerForDocShell(
|
||||
docShell, "DOMEvent", MarkerTracingType::END);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find any matching listeners, and our event has a legacy
|
||||
// version, we'll now switch to looking for that legacy version and we'll
|
||||
// recheck our listeners.
|
||||
if (hasListener || usingLegacyMessage) {
|
||||
// (No need to recheck listeners, because we already found a match, or we
|
||||
// already rechecked them.)
|
||||
break;
|
||||
}
|
||||
EventMessage legacyEventMessage = GetLegacyEventMessage(eventMessage);
|
||||
if (legacyEventMessage == eventMessage) {
|
||||
break; // There's no legacy version of our event; no need to recheck.
|
||||
}
|
||||
MOZ_ASSERT(GetLegacyEventMessage(legacyEventMessage) == legacyEventMessage,
|
||||
"Legacy event messages should not themselves have legacy versions");
|
||||
|
||||
// Recheck our listeners, using the legacy event message we just looked up:
|
||||
eventMessage = legacyEventMessage;
|
||||
usingLegacyMessage = true;
|
||||
}
|
||||
|
||||
aEvent->currentTarget = nullptr;
|
||||
|
|
|
@ -571,9 +571,7 @@ protected:
|
|||
nsPIDOMWindowInner* GetInnerWindowForTarget();
|
||||
already_AddRefed<nsPIDOMWindowInner> GetTargetAsInnerWindow() const;
|
||||
|
||||
bool ListenerCanHandle(const Listener* aListener,
|
||||
const WidgetEvent* aEvent,
|
||||
EventMessage aEventMessage) const;
|
||||
bool ListenerCanHandle(Listener* aListener, WidgetEvent* aEvent);
|
||||
|
||||
// BE AWARE, a lot of instances of EventListenerManager will be created.
|
||||
// Therefor, we need to keep this class compact. When you add integer
|
||||
|
|
|
@ -924,7 +924,6 @@ NON_IDL_EVENT(MozEdgeUICompleted,
|
|||
EventNameType_None,
|
||||
eSimpleGestureEventClass)
|
||||
|
||||
// CSS Transition & Animation events:
|
||||
NON_IDL_EVENT(transitionend,
|
||||
eTransitionEnd,
|
||||
EventNameType_None,
|
||||
|
@ -942,24 +941,6 @@ NON_IDL_EVENT(animationiteration,
|
|||
EventNameType_None,
|
||||
eAnimationEventClass)
|
||||
|
||||
// Webkit-prefixed versions of Transition & Animation events, for web compat:
|
||||
NON_IDL_EVENT(webkitTransitionEnd,
|
||||
eWebkitTransitionEnd,
|
||||
EventNameType_None,
|
||||
eTransitionEventClass)
|
||||
NON_IDL_EVENT(webkitAnimationEnd,
|
||||
eWebkitAnimationEnd,
|
||||
EventNameType_None,
|
||||
eAnimationEventClass)
|
||||
NON_IDL_EVENT(webkitAnimationIteration,
|
||||
eWebkitAnimationIteration,
|
||||
EventNameType_None,
|
||||
eAnimationEventClass)
|
||||
NON_IDL_EVENT(webkitAnimationStart,
|
||||
eWebkitAnimationStart,
|
||||
EventNameType_None,
|
||||
eAnimationEventClass)
|
||||
|
||||
NON_IDL_EVENT(audioprocess,
|
||||
eAudioProcess,
|
||||
EventNameType_None,
|
||||
|
|
|
@ -168,7 +168,6 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
|
|||
[test_eventTimeStamp.html]
|
||||
[test_focus_disabled.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_legacy_event.html]
|
||||
[test_messageEvent.html]
|
||||
[test_moz_mouse_pixel_scroll_event.html]
|
||||
skip-if = buildapp == 'b2g' # bug 1126090, no wheel events on b2g
|
||||
|
|
|
@ -1,256 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1236979
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1236979 (events that have legacy alternative versions)</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
@keyframes anim1 {
|
||||
0% { margin-left: 0px }
|
||||
100% { margin-left: 100px }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1236979">Mozilla Bug 1236979</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1236979 **/
|
||||
|
||||
'use strict';
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Array of info-bundles about each legacy event to be tested:
|
||||
var gLegacyEventInfo = [
|
||||
{
|
||||
legacy_name: "webkitTransitionEnd",
|
||||
modern_name: "transitionend",
|
||||
trigger_event: triggerShortTransition,
|
||||
},
|
||||
{
|
||||
legacy_name: "webkitAnimationStart",
|
||||
modern_name: "animationstart",
|
||||
trigger_event: triggerShortAnimation,
|
||||
},
|
||||
{
|
||||
legacy_name: "webkitAnimationEnd",
|
||||
modern_name: "animationend",
|
||||
trigger_event: triggerShortAnimation,
|
||||
},
|
||||
{
|
||||
legacy_name: "webkitAnimationIteration",
|
||||
modern_name: "animationiteration",
|
||||
trigger_event: triggerAnimationIteration,
|
||||
}
|
||||
];
|
||||
|
||||
// EVENT-TRIGGERING FUNCTIONS
|
||||
// --------------------------
|
||||
// This function triggers a very short (1ms long) transition, which will cause
|
||||
// events to fire for the transition ending.
|
||||
function triggerShortTransition(node) {
|
||||
node.style.transition = "1ms color linear" ;
|
||||
node.style.color = "purple";
|
||||
// Flush style, so that the above assignment value actually takes effect
|
||||
// in the computed style, so that a transition will get triggered when it
|
||||
// changes.
|
||||
window.getComputedStyle(node, "").color;
|
||||
node.style.color = "teal";
|
||||
}
|
||||
|
||||
// This function triggers a very short (1ms long) animation, which will cause
|
||||
// events to fire for the animation beginning & ending.
|
||||
function triggerShortAnimation(node) {
|
||||
node.style.animation = "anim1 1ms linear";
|
||||
}
|
||||
|
||||
// This function triggers a long animation with two iterations, which is
|
||||
// *nearly* at the end of its first iteration. It will hit the end of that
|
||||
// iteration (firing an event) almost immediately, 1ms in the future.
|
||||
//
|
||||
// NOTE: It's important that this animation have a *long* duration. If it were
|
||||
// short (e.g. 1ms duration), then we might jump past all its iterations in
|
||||
// a single refresh-driver tick. And if that were to happens, we'd *never* fire
|
||||
// any animationiteration events -- the CSS Animations spec says this event
|
||||
// must not be fired "...when an animationend event would fire at the same time"
|
||||
// (which would be the case in this example with a 1ms duration). So, to make
|
||||
// sure our event does fire, we use a long duration and a nearly-as-long
|
||||
// negative delay. This ensures we hit the end of the first iteration right
|
||||
// away, and that we don't risk hitting the end of the second iteration at the
|
||||
// same time.
|
||||
function triggerAnimationIteration(node) {
|
||||
node.style.animation = "anim1 300s -299.999s linear 2";
|
||||
}
|
||||
|
||||
// GENERAL UTILITY FUNCTIONS
|
||||
// -------------------------
|
||||
// Creates a new div and appends it as a child of the specified parentNode, or
|
||||
// (if no parent is specified) as a child of the element with ID 'display'.
|
||||
function createChildDiv(parentNode) {
|
||||
if (!parentNode) {
|
||||
parentNode = document.getElementById("display");
|
||||
if (!parentNode) {
|
||||
ok(false, "no 'display' element to append to");
|
||||
}
|
||||
}
|
||||
var div = document.createElement("div");
|
||||
parentNode.appendChild(div);
|
||||
return div;
|
||||
}
|
||||
|
||||
// Returns an event-handler function, which (when invoked) simply checks that
|
||||
// the event's type matches what's expected. If a callback is passed in, then
|
||||
// the event-handler will invoke that callback as well.
|
||||
function createHandlerWithTypeCheck(expectedEventType, extraHandlerLogic) {
|
||||
var handler = function(e) {
|
||||
is(e.type, expectedEventType,
|
||||
"When an event handler for '" + expectedEventType + "' is invoked, " +
|
||||
"the event's type field should be '" + expectedEventType + "'.");
|
||||
if (extraHandlerLogic) {
|
||||
extraHandlerLogic(e);
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
// TEST FUNCTIONS
|
||||
// --------------
|
||||
// These functions expect to be passed an entry from gEventInfo, and they
|
||||
// return a Promise which performs the test & resolves when it's complete.
|
||||
// The function names all begin with "mp", which stands for "make promise".
|
||||
// So e.g. "mpTestLegacyEventSent" means "make a promise to test that the
|
||||
// legacy event is sent".
|
||||
|
||||
// Tests that the legacy event type is sent, when only a legacy handler is
|
||||
// registered.
|
||||
function mpTestLegacyEventSent(eventInfo) {
|
||||
return new Promise(
|
||||
function(resolve, reject) {
|
||||
// Create a node & register an event-handler for the legacy event:
|
||||
var div = createChildDiv();
|
||||
|
||||
var handler = createHandlerWithTypeCheck(eventInfo.legacy_name,
|
||||
function() {
|
||||
// When event-handler is done, clean up & resolve:
|
||||
div.parentNode.removeChild(div);
|
||||
resolve();
|
||||
});
|
||||
div.addEventListener(eventInfo.legacy_name, handler);
|
||||
|
||||
// Trigger the event:
|
||||
eventInfo.trigger_event(div);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Test that the modern event type (and only the modern event type) is fired,
|
||||
// when listeners of both modern & legacy types are registered. The legacy
|
||||
// listener should not be invoked.
|
||||
function mpTestModernBeatsLegacy(eventInfo) {
|
||||
return new Promise(
|
||||
function(resolve, reject) {
|
||||
var div = createChildDiv();
|
||||
|
||||
var legacyHandler = function(e) {
|
||||
reject("Handler for legacy event '" + eventInfo.legacy_name +
|
||||
"' should not be invoked when there's a handler registered " +
|
||||
"for both modern & legacy event type on the same node");
|
||||
};
|
||||
|
||||
var modernHandler = createHandlerWithTypeCheck(eventInfo.modern_name,
|
||||
function() {
|
||||
// Indicate that the test has passed (we invoked the modern handler):
|
||||
ok(true, "Handler for modern event '" + eventInfo.modern_name +
|
||||
"' should be invoked when there's a handler registered for " +
|
||||
"both modern & legacy event type on the same node");
|
||||
// When event-handler is done, clean up & resolve:
|
||||
div.parentNode.removeChild(div);
|
||||
resolve();
|
||||
});
|
||||
|
||||
div.addEventListener(eventInfo.legacy_name, legacyHandler);
|
||||
div.addEventListener(eventInfo.modern_name, modernHandler);
|
||||
eventInfo.trigger_event(div);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Test that an event which bubbles may fire listeners of different flavors
|
||||
// (modern vs. legacy) at each bubbling level, depending on what's registered
|
||||
// at that level.
|
||||
function mpTestAncestorsWithDiffListeners(eventInfo) {
|
||||
return new Promise(
|
||||
function(resolve, reject) {
|
||||
var grandparent = createChildDiv();
|
||||
var parent = createChildDiv(grandparent);
|
||||
var target = createChildDiv(parent);
|
||||
var didEventFireOnTarget = false;
|
||||
var didEventFireOnParent = false;
|
||||
var eventSentToTarget;
|
||||
|
||||
target.addEventListener(eventInfo.modern_name,
|
||||
createHandlerWithTypeCheck(eventInfo.modern_name,
|
||||
function(e) {
|
||||
ok(e.bubbles, "Expecting event to bubble");
|
||||
eventSentToTarget = e;
|
||||
didEventFireOnTarget = true;
|
||||
}));
|
||||
|
||||
parent.addEventListener(eventInfo.legacy_name,
|
||||
createHandlerWithTypeCheck(eventInfo.legacy_name,
|
||||
function(e) {
|
||||
is(e, eventSentToTarget,
|
||||
"Same event object should bubble, " +
|
||||
"despite difference in type");
|
||||
didEventFireOnParent = true;
|
||||
}));
|
||||
|
||||
grandparent.addEventListener(eventInfo.modern_name,
|
||||
createHandlerWithTypeCheck(eventInfo.modern_name,
|
||||
function(e) {
|
||||
ok(didEventFireOnTarget,
|
||||
"Event should have fired on child");
|
||||
ok(didEventFireOnParent,
|
||||
"Event should have fired on parent");
|
||||
is(e, eventSentToTarget,
|
||||
"Same event object should bubble, " +
|
||||
"despite difference in type");
|
||||
parent.removeChild(target);
|
||||
resolve();
|
||||
}));
|
||||
eventInfo.trigger_event(target);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// MAIN FUNCTION: Kick off the tests.
|
||||
function main() {
|
||||
Promise.resolve().then(function() {
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestLegacyEventSent))
|
||||
}).then(function() {
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestModernBeatsLegacy));
|
||||
}).then(function() {
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestAncestorsWithDiffListeners));
|
||||
}).then(function() {
|
||||
SimpleTest.finish();
|
||||
}).catch(function(reason) {
|
||||
ok(false, "Test failed: " + reason);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -312,18 +312,12 @@ NS_EVENT_MESSAGE(eGestureNotify)
|
|||
|
||||
NS_EVENT_MESSAGE(eScrolledAreaChanged)
|
||||
|
||||
// CSS Transition & Animation events:
|
||||
NS_EVENT_MESSAGE(eTransitionEnd)
|
||||
|
||||
NS_EVENT_MESSAGE(eAnimationStart)
|
||||
NS_EVENT_MESSAGE(eAnimationEnd)
|
||||
NS_EVENT_MESSAGE(eAnimationIteration)
|
||||
|
||||
// Webkit-prefixed versions of Transition & Animation events, for web compat:
|
||||
NS_EVENT_MESSAGE(eWebkitTransitionEnd)
|
||||
NS_EVENT_MESSAGE(eWebkitAnimationStart)
|
||||
NS_EVENT_MESSAGE(eWebkitAnimationEnd)
|
||||
NS_EVENT_MESSAGE(eWebkitAnimationIteration)
|
||||
|
||||
NS_EVENT_MESSAGE(eSMILBeginEvent)
|
||||
NS_EVENT_MESSAGE(eSMILEndEvent)
|
||||
NS_EVENT_MESSAGE(eSMILRepeatEvent)
|
||||
|
|
Загрузка…
Ссылка в новой задаче