backout bug 1236979 (changesets 2f4de652525e, d7136545a16e, f62e6638add1, f8b1e085b161) for xpcshell test failures

This commit is contained in:
Daniel Holbert 2016-02-01 21:57:38 -08:00
Родитель 13208cc3e7
Коммит 2eb04f5120
8 изменённых файлов: 59 добавлений и 469 удалений

Просмотреть файл

@ -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)