diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp
index d017134e6c..3b35c651e6 100644
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -496,76 +496,6 @@ bool ScriptErrorEvent::sHandlingScriptError = false;
// soon.
namespace xpc {
-void
-SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
-{
- JS::Rooted exception(cx);
- ::JS_GetPendingException(cx, &exception);
-
- // Note: we must do this before running any more code on cx.
- ::JS_ClearPendingException(cx);
-
- MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
- nsCOMPtr globalObject;
-
- // The eventual plan is for error reporting to happen in the AutoJSAPI
- // destructor using the global with which the AutoJSAPI was initialized. We
- // can't _quite_ do that yet, so we take a sloppy stab at those semantics. If
- // we have an nsIScriptContext, we'll get the right answer modulo
- // non-current-inners.
- //
- // Otherwise, we just use the privileged junk scope. This has the effect of
- // causing us to report the error as "chrome javascript" rather than "content
- // javascript", and not invoking any error reporters. This is exactly what we
- // want here.
- if (nsIScriptContext* scx = GetScriptContextFromJSContext(cx)) {
- nsCOMPtr outer = do_QueryInterface(scx->GetGlobalObject());
- if (outer) {
- globalObject = static_cast(outer->GetCurrentInnerWindow());
- }
- }
-
- // We run addons in a separate privileged compartment, but they still expect
- // to trigger the onerror handler of their associated DOMWindow.
- //
- // Note that the way we do this right now is sloppy. Error reporters can
- // theoretically be triggered at arbitrary times (not just immediately before
- // an AutoJSAPI comes off the stack), so we don't really have a way of knowing
- // that the global of the current compartment is the correct global with which
- // to report the error. But in practice this is probably fine for the time
- // being, and will get cleaned up soon when we fix bug 981187.
- if (!globalObject && JS::CurrentGlobalOrNull(cx)) {
- globalObject = xpc::AddonWindowOrNull(JS::CurrentGlobalOrNull(cx));
- }
-
- if (!globalObject) {
- globalObject = xpc::NativeGlobal(xpc::PrivilegedJunkScope());
- }
-
- if (globalObject) {
- RefPtr xpcReport = new xpc::ErrorReport();
- bool isChrome = nsContentUtils::IsSystemPrincipal(globalObject->PrincipalOrNull());
- nsCOMPtr win = do_QueryInterface(globalObject);
- xpcReport->Init(report, message, isChrome, win ? win->WindowID() : 0);
-
- // If we can't dispatch an event to a window, report it to the console
- // directly. This includes the case where the error was an OOM, because
- // triggering a scripted event handler is likely to generate further OOMs.
- if (!win || JSREPORT_IS_WARNING(xpcReport->mFlags) ||
- report->errorNumber == JSMSG_OUT_OF_MEMORY)
- {
- JS::Rooted stack(cx,
- xpc::FindExceptionStackForConsoleReport(win, exception));
- xpcReport->LogToConsoleWithStack(stack);
- return;
- }
-
- // Otherwise, we need to asynchronously invoke onerror before we can decide
- // whether or not to report the error to the console.
- DispatchScriptErrorEvent(win, JS_GetRuntime(cx), xpcReport, exception);
- }
-}
-
void
DispatchScriptErrorEvent(nsPIDOMWindow *win, JSRuntime *rt, xpc::ErrorReport *xpcReport,
JS::Handle exception)
diff --git a/gfx/layers/apz/reftests/reftest.list b/gfx/layers/apz/reftests/reftest.list
deleted file mode 100644
index fc76ab5384..0000000000
--- a/gfx/layers/apz/reftests/reftest.list
+++ /dev/null
@@ -1,14 +0,0 @@
-# The following tests test the async positioning of the scrollbars.
-# Basic root-frame scrollbar with async scrolling
-chaos-mode skip-if(!asyncPan) == async-scrollbar-1-v.html async-scrollbar-1-v-ref.html
-chaos-mode skip-if(!asyncPan) == async-scrollbar-1-h.html async-scrollbar-1-h-ref.html
-chaos-mode skip-if(!asyncPan) == async-scrollbar-1-vh.html async-scrollbar-1-vh-ref.html
-chaos-mode skip-if(!asyncPan) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl-ref.html
-chaos-mode skip-if(!asyncPan) == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl-ref.html
-chaos-mode skip-if(!asyncPan) == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl-ref.html
-
-# Different async zoom levels. Since the scrollthumb gets async-scaled in the
-# compositor, the border-radius ends of the scrollthumb are going to be a little
-# off, hence the fuzzy-if clauses.
-chaos-mode skip-if(!asyncZoom) fuzzy-if(B2G,98,82) == async-scrollbar-zoom-1.html async-scrollbar-zoom-1-ref.html
-chaos-mode skip-if(!asyncZoom) fuzzy-if(B2G,94,146) == async-scrollbar-zoom-2.html async-scrollbar-zoom-2-ref.html
diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp
index 0dcfffe5aa..9eacdb2233 100644
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1770,7 +1770,7 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
MOZ_ASSERT(result);
}
APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n",
- result, aNode, *aOutHitResult);
+ result, resultNode, *aOutHitResult);
return result;
}
diff --git a/gfx/layers/apz/src/InputBlockState.cpp b/gfx/layers/apz/src/InputBlockState.cpp
index d57893ef82..a92c264ff9 100644
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -25,7 +25,8 @@ static uint64_t sBlockCounter = InputBlockState::NO_BLOCK_ID + 1;
InputBlockState::InputBlockState(const RefPtr& aTargetApzc,
bool aTargetConfirmed)
: mTargetApzc(aTargetApzc)
- , mTargetConfirmed(aTargetConfirmed)
+ , mTargetConfirmed(aTargetConfirmed ? TargetConfirmationState::eConfirmed
+ : TargetConfirmationState::eUnconfirmed)
, mBlockId(sBlockCounter++)
, mTransformToApzc(aTargetApzc->GetTransformToThis())
{
@@ -35,12 +36,23 @@ InputBlockState::InputBlockState(const RefPtr& aTargetAp
}
bool
-InputBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc)
+InputBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
+ TargetConfirmationState aState)
{
- if (mTargetConfirmed) {
+ MOZ_ASSERT(aState == TargetConfirmationState::eConfirmed
+ || aState == TargetConfirmationState::eTimedOut);
+
+ if (mTargetConfirmed == TargetConfirmationState::eTimedOut &&
+ aState == TargetConfirmationState::eConfirmed) {
+ // The main thread finally responded. We had already timed out the
+ // confirmation, but we want to update the state internally so that we
+ // can record the time for telemetry purposes.
+ mTargetConfirmed = TargetConfirmationState::eTimedOutAndMainThreadResponded;
+ }
+ if (mTargetConfirmed != TargetConfirmationState::eUnconfirmed) {
return false;
}
- mTargetConfirmed = true;
+ mTargetConfirmed = aState;
TBS_LOG("%p got confirmed target APZC %p\n", this, mTargetApzc.get());
if (mTargetApzc == aTargetApzc) {
@@ -85,7 +97,14 @@ InputBlockState::GetBlockId() const
bool
InputBlockState::IsTargetConfirmed() const
{
- return mTargetConfirmed;
+ return mTargetConfirmed != TargetConfirmationState::eUnconfirmed;
+}
+
+bool
+InputBlockState::HasReceivedRealConfirmedTarget() const
+{
+ return mTargetConfirmed == TargetConfirmationState::eConfirmed ||
+ mTargetConfirmed == TargetConfirmationState::eTimedOutAndMainThreadResponded;
}
bool
@@ -192,7 +211,7 @@ CancelableBlockState::IsDefaultPrevented() const
bool
CancelableBlockState::HasReceivedAllContentNotifications() const
{
- return IsTargetConfirmed() && mContentResponded;
+ return HasReceivedRealConfirmedTarget() && mContentResponded;
}
bool
@@ -359,7 +378,8 @@ WheelBlockState::SetContentResponse(bool aPreventDefault)
}
bool
-WheelBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc)
+WheelBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
+ TargetConfirmationState aState)
{
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
// ESM or OverscrollHandoff would have computed. Make sure we get the right
@@ -370,7 +390,7 @@ WheelBlockState::SetConfirmedTargetApzc(const RefPtr& aT
apzc = apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(event);
}
- InputBlockState::SetConfirmedTargetApzc(apzc);
+ InputBlockState::SetConfirmedTargetApzc(apzc, aState);
return true;
}
@@ -603,7 +623,8 @@ PanGestureBlockState::PanGestureBlockState(const RefPtr&
}
bool
-PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc)
+PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
+ TargetConfirmationState aState)
{
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
// ESM or OverscrollHandoff would have computed. Make sure we get the right
@@ -618,7 +639,7 @@ PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
bool aTargetConfirmed);
virtual ~InputBlockState()
{}
- virtual bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc);
+ virtual bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
+ TargetConfirmationState aState);
const RefPtr& GetTargetApzc() const;
const RefPtr& GetOverscrollHandoffChain() const;
uint64_t GetBlockId() const;
bool IsTargetConfirmed() const;
+ bool HasReceivedRealConfirmedTarget() const;
void SetScrolledApzc(AsyncPanZoomController* aApzc);
AsyncPanZoomController* GetScrolledApzc() const;
@@ -65,7 +74,7 @@ private:
private:
RefPtr mTargetApzc;
- bool mTargetConfirmed;
+ TargetConfirmationState mTargetConfirmed;
const uint64_t mBlockId;
// The APZC that was actually scrolled by events in this input block.
@@ -227,7 +236,8 @@ public:
void HandleEvents() override;
bool MustStayActive() override;
const char* Type() override;
- bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc) override;
+ bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
+ TargetConfirmationState aState) override;
void AddEvent(const ScrollWheelInput& aEvent);
@@ -348,7 +358,8 @@ public:
void HandleEvents() override;
bool MustStayActive() override;
const char* Type() override;
- bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc) override;
+ bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc,
+ TargetConfirmationState aState) override;
void AddEvent(const PanGestureInput& aEvent);
diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp
index 321d1e183e..72180c3d7b 100644
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -118,7 +118,8 @@ InputQueue::ReceiveTouchInput(const RefPtr& aTarget,
// from a fast fling to a pinch state (i.e. second finger goes down while
// the first finger is moving).
block->SetDuringFastFling();
- block->SetConfirmedTargetApzc(aTarget);
+ block->SetConfirmedTargetApzc(aTarget,
+ InputBlockState::TargetConfirmationState::eConfirmed);
if (gfxPrefs::TouchActionEnabled()) {
block->SetAllowedTouchBehaviors(currentBehaviors);
}
@@ -334,22 +335,25 @@ InputQueue::ReceivePanGestureInput(const RefPtr& aTarget
block = mInputBlockQueue.LastElement()->AsPanGestureBlock();
}
+ PanGestureInput event = aEvent;
nsEventStatus result = nsEventStatus_eConsumeDoDefault;
if (!block || block->WasInterrupted()) {
- if (aEvent.mType != PanGestureInput::PANGESTURE_START) {
- // Only PANGESTURE_START events are allowed to start a new pan gesture block.
- INPQ_LOG("pangesture block %p was interrupted %d\n", block,
- block ? block->WasInterrupted() : 0);
- return nsEventStatus_eConsumeDoDefault;
+ if (event.mType != PanGestureInput::PANGESTURE_START) {
+ // Only PANGESTURE_START events are allowed to start a new pan gesture
+ // block, but we really want to start a new block here, so we magically
+ // turn this input into a PANGESTURE_START.
+ INPQ_LOG("transmogrifying pan input %d to PANGESTURE_START for new block\n",
+ event.mType);
+ event.mType = PanGestureInput::PANGESTURE_START;
}
- block = new PanGestureBlockState(aTarget, aTargetConfirmed, aEvent);
+ block = new PanGestureBlockState(aTarget, aTargetConfirmed, event);
INPQ_LOG("started new pan gesture block %p id %" PRIu64 " for target %p\n",
block, block->GetBlockId(), aTarget.get());
if (aTargetConfirmed &&
- aEvent.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection &&
- !CanScrollTargetHorizontally(aEvent, block)) {
+ event.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection &&
+ !CanScrollTargetHorizontally(event, block)) {
// This event may trigger a swipe gesture, depending on what our caller
// wants to do it. We need to suspend handling of this block until we get
// a content response which will tell us whether to proceed or abort the
@@ -379,8 +383,8 @@ InputQueue::ReceivePanGestureInput(const RefPtr& aTarget
// null) should take priority. This is equivalent to just always using the
// target (confirmed or not) from the block, which is what
// MaybeHandleCurrentBlock() does.
- if (!MaybeHandleCurrentBlock(block, aEvent)) {
- block->AddEvent(aEvent.AsPanGestureInput());
+ if (!MaybeHandleCurrentBlock(block, event)) {
+ block->AddEvent(event.AsPanGestureInput());
}
return result;
@@ -583,7 +587,9 @@ InputQueue::MainThreadTimeout(const uint64_t& aInputBlockId) {
// target apzc in the case where the main thread doesn't get back to us
// fast enough.
success = mInputBlockQueue[i]->TimeoutContentResponse();
- success |= mInputBlockQueue[i]->SetConfirmedTargetApzc(mInputBlockQueue[i]->GetTargetApzc());
+ success |= mInputBlockQueue[i]->SetConfirmedTargetApzc(
+ mInputBlockQueue[i]->GetTargetApzc(),
+ InputBlockState::TargetConfirmationState::eTimedOut);
break;
}
}
@@ -621,7 +627,8 @@ InputQueue::SetConfirmedTargetApzc(uint64_t aInputBlockId, const RefPtrGetBlockId() == aInputBlockId) {
- success = block->SetConfirmedTargetApzc(aTargetApzc);
+ success = block->SetConfirmedTargetApzc(aTargetApzc,
+ InputBlockState::TargetConfirmationState::eConfirmed);
block->RecordContentResponseTime();
break;
}
@@ -644,7 +651,8 @@ InputQueue::ConfirmDragBlock(uint64_t aInputBlockId, const RefPtrAsDragBlock();
if (block && block->GetBlockId() == aInputBlockId) {
block->SetDragMetrics(aDragMetrics);
- success = block->SetConfirmedTargetApzc(aTargetApzc);
+ success = block->SetConfirmedTargetApzc(aTargetApzc,
+ InputBlockState::TargetConfirmationState::eConfirmed);
block->RecordContentResponseTime();
break;
}
diff --git a/gfx/layers/apz/src/OverscrollHandoffState.h b/gfx/layers/apz/src/OverscrollHandoffState.h
index 699965a6d6..1290309e65 100644
--- a/gfx/layers/apz/src/OverscrollHandoffState.h
+++ b/gfx/layers/apz/src/OverscrollHandoffState.h
@@ -16,43 +16,13 @@
#include "Units.h" // for ScreenPoint
namespace mozilla {
+
+class InputData;
+
namespace layers {
class AsyncPanZoomController;
-/**
- * A variant of NS_INLINE_DECL_THREADSAFE_REFCOUNTING which makes the refcount
- * variable |mutable|, and the AddRef and Release methods |const|, to allow
- * using an |RefPtr|, and thereby enforcing better const-correctness.
- * This is currently here because OverscrollHandoffChain is the only thing
- * currently using it. As a follow-up, we can move this to xpcom/glue, write
- * a corresponding version for non-threadsafe refcounting, and perhaps
- * transition other clients of NS_INLINE_DECL_[THREADSAFE_]REFCOUNTING to the
- * mutable versions.
- */
-#define NS_INLINE_DECL_THREADSAFE_MUTABLE_REFCOUNTING(_class) \
-public: \
- NS_METHOD_(MozExternalRefCountType) AddRef(void) const { \
- MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(_class) \
- MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
- nsrefcnt count = ++mRefCnt; \
- NS_LOG_ADDREF(const_cast<_class*>(this), count, #_class, sizeof(*this)); \
- return (nsrefcnt) count; \
- } \
- NS_METHOD_(MozExternalRefCountType) Release(void) const { \
- MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); \
- nsrefcnt count = --mRefCnt; \
- NS_LOG_RELEASE(const_cast<_class*>(this), count, #_class); \
- if (count == 0) { \
- delete (this); \
- return 0; \
- } \
- return count; \
- } \
-protected: \
- mutable ::mozilla::ThreadSafeAutoRefCnt mRefCnt; \
-public:
-
/**
* This class represents the chain of APZCs along which overscroll is handed off.
* It is created by APZCTreeManager by starting from an initial APZC which is
@@ -71,7 +41,7 @@ public:
// Mutable so that we can pass around the class by
// RefPtr and thus enforce that, once built,
// the chain is not modified.
- NS_INLINE_DECL_THREADSAFE_MUTABLE_REFCOUNTING(OverscrollHandoffChain)
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OverscrollHandoffChain)
/*
* Methods for building the handoff chain.
diff --git a/gfx/layers/apz/test/apz_test_native_event_utils.js b/gfx/layers/apz/test/apz_test_native_event_utils.js
deleted file mode 100644
index 2c15897448..0000000000
--- a/gfx/layers/apz/test/apz_test_native_event_utils.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// Utilities for synthesizing of native events.
-
-function getPlatform() {
- if (navigator.platform.indexOf("Win") == 0) {
- return "windows";
- }
- if (navigator.platform.indexOf("Mac") == 0) {
- return "mac";
- }
- if (navigator.platform.indexOf("Linux") == 0) {
- return "linux";
- }
- return "unknown";
-}
-
-function nativeVerticalWheelEventMsg() {
- switch (getPlatform()) {
- case "windows": return 0x020A; // WM_MOUSEWHEEL
- case "mac": return 0; // value is unused, can be anything
- case "linux": return 4; // value is unused, pass GDK_SCROLL_SMOOTH anyway
- }
- throw "Native wheel events not supported on platform " + getPlatform();
-}
-
-function nativeHorizontalWheelEventMsg() {
- switch (getPlatform()) {
- case "windows": return 0x020E; // WM_MOUSEHWHEEL
- case "mac": return 0; // value is unused, can be anything
- case "linux": return 4; // value is unused, pass GDK_SCROLL_SMOOTH anyway
- }
- throw "Native wheel events not supported on platform " + getPlatform();
-}
-
-// Convert (aX, aY), in CSS pixels relative to aElement's bounding rect,
-// to device pixels relative to aElement's containing window.
-function coordinatesRelativeToWindow(aX, aY, aElement) {
- var targetWindow = aElement.ownerDocument.defaultView;
- var scale = targetWindow.devicePixelRatio;
- var rect = aElement.getBoundingClientRect();
- return {
- x: targetWindow.mozInnerScreenX + ((rect.left + aX) * scale),
- y: targetWindow.mozInnerScreenY + ((rect.top + aY) * scale)
- };
-}
-
-// Synthesizes a native mousewheel event and returns immediately. This does not
-// guarantee anything; you probably want to use one of the other functions below
-// which actually wait for results.
-// aX and aY are relative to |window|'s top-left. aDeltaX and aDeltaY
-// are pixel deltas, and aObserver can be left undefined if not needed.
-function synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY, aObserver) {
- var pt = coordinatesRelativeToWindow(aX, aY, aElement);
- if (aDeltaX && aDeltaY) {
- throw "Simultaneous wheeling of horizontal and vertical is not supported on all platforms.";
- }
- var msg = aDeltaX ? nativeHorizontalWheelEventMsg() : nativeVerticalWheelEventMsg();
- _getDOMWindowUtils().sendNativeMouseScrollEvent(pt.x, pt.y, msg, aDeltaX, aDeltaY, 0, 0, 0, aElement, aObserver);
- return true;
-}
-
-// Synthesizes a native mousewheel event and invokes the callback once the
-// request has been successfully made to the OS. This does not necessarily
-// guarantee that the OS generates the event we requested. See
-// synthesizeNativeWheel for details on the parameters.
-function synthesizeNativeWheelAndWaitForObserver(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
- var observer = {
- observe: function(aSubject, aTopic, aData) {
- if (aCallback && aTopic == "mousescrollevent") {
- setTimeout(aCallback, 0);
- }
- }
- };
- return synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY, observer);
-}
-
-// Synthesizes a native mousewheel event and invokes the callback once the
-// wheel event is dispatched to the window. See synthesizeNativeWheel for
-// details on the parameters.
-function synthesizeNativeWheelAndWaitForWheelEvent(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
- window.addEventListener("wheel", function wheelWaiter(e) {
- window.removeEventListener("wheel", wheelWaiter);
- setTimeout(aCallback, 0);
- });
- return synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY);
-}
-
-// Synthesizes a native mousewheel event and invokes the callback once the
-// first resulting scroll event is dispatched to the window.
-// See synthesizeNativeWheel for details on the parameters.
-function synthesizeNativeWheelAndWaitForScrollEvent(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
- var useCapture = true; // scroll events don't always bubble
- window.addEventListener("scroll", function scrollWaiter(e) {
- window.removeEventListener("scroll", scrollWaiter, useCapture);
- setTimeout(aCallback, 0);
- }, useCapture);
- return synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY);
-}
-
-// Synthesizes a native mouse move event and returns immediately.
-// aX and aY are relative to the top-left of |aElement|'s containing window.
-function synthesizeNativeMouseMove(aElement, aX, aY) {
- var pt = coordinatesRelativeToWindow(aX, aY, aElement);
- _getDOMWindowUtils().sendNativeMouseEvent(pt.x, pt.y, nativeMouseMoveEventMsg(), 0, aElement);
- return true;
-}
-
-// Synthesizes a native mouse move event and invokes the callback once the
-// mouse move event is dispatched to |aElement|'s containing window. If the event
-// targets content in a subdocument, |aElement| should be inside the
-// subdocument. See synthesizeNativeMouseMove for details on the other
-// parameters.
-function synthesizeNativeMouseMoveAndWaitForMoveEvent(aElement, aX, aY, aCallback) {
- var targetWindow = aElement.ownerDocument.defaultView;
- targetWindow.addEventListener("mousemove", function mousemoveWaiter(e) {
- targetWindow.removeEventListener("mousemove", mousemoveWaiter);
- setTimeout(aCallback, 0);
- });
- return synthesizeNativeMouseMove(aElement, aX, aY);
-}
-
-// Synthesizes a native touch event and dispatches it. aX and aY in CSS pixels
-// relative to the top-left of |aElement|'s bounding rect.
-function synthesizeNativeTouch(aElement, aX, aY, aType, aObserver = null, aTouchId = 0) {
- var pt = coordinatesRelativeToWindow(aX, aY, aElement);
- var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
- utils.sendNativeTouchPoint(aTouchId, aType, pt.x, pt.y, 1, 90, aObserver);
- return true;
-}
-
-function synthesizeNativeDrag(aElement, aX, aY, aDeltaX, aDeltaY, aObserver = null, aTouchId = 0) {
- synthesizeNativeTouch(aElement, aX, aY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
- var steps = Math.max(Math.abs(aDeltaX), Math.abs(aDeltaY));
- for (var i = 1; i < steps; i++) {
- var dx = i * (aDeltaX / steps);
- var dy = i * (aDeltaY / steps);
- synthesizeNativeTouch(aElement, aX + dx, aY + dy, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
- }
- synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
- return synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, aObserver, aTouchId);
-}
diff --git a/gfx/layers/apz/test/apz_test_utils.js b/gfx/layers/apz/test/apz_test_utils.js
deleted file mode 100644
index bc9830b9b1..0000000000
--- a/gfx/layers/apz/test/apz_test_utils.js
+++ /dev/null
@@ -1,118 +0,0 @@
-// Utilities for writing APZ tests using the framework added in bug 961289
-
-// ----------------------------------------------------------------------
-// Functions that convert the APZ test data into a more usable form.
-// Every place we have a WebIDL sequence whose elements are dictionaries
-// with two elements, a key, and a value, we convert this into a JS
-// object with a property for each key/value pair. (This is the structure
-// we really want, but we can't express in directly in WebIDL.)
-// ----------------------------------------------------------------------
-
-function convertEntries(entries) {
- var result = {};
- for (var i = 0; i < entries.length; ++i) {
- result[entries[i].key] = entries[i].value;
- }
- return result;
-}
-
-function convertScrollFrameData(scrollFrames) {
- var result = {};
- for (var i = 0; i < scrollFrames.length; ++i) {
- result[scrollFrames[i].scrollId] = convertEntries(scrollFrames[i].entries);
- }
- return result;
-}
-
-function convertBuckets(buckets) {
- var result = {};
- for (var i = 0; i < buckets.length; ++i) {
- result[buckets[i].sequenceNumber] = convertScrollFrameData(buckets[i].scrollFrames);
- }
- return result;
-}
-
-function convertTestData(testData) {
- var result = {};
- result.paints = convertBuckets(testData.paints);
- result.repaintRequests = convertBuckets(testData.repaintRequests);
- return result;
-}
-
-// ----------------------------------------------------------------
-// Utilities for reconstructing the structure of the APZC tree from
-// 'parentScrollId' entries in the APZ test data.
-// ----------------------------------------------------------------
-
-// Create a node with scroll id 'id' in the APZC tree.
-function makeNode(id) {
- return {scrollId: id, children: []};
-}
-
-// Find a node with scroll id 'id' in the APZC tree rooted at 'root'.
-function findNode(root, id) {
- if (root.scrollId == id) {
- return root;
- }
- for (var i = 0; i < root.children.length; ++i) {
- var subtreeResult = findNode(root.children[i], id);
- if (subtreeResult != null) {
- return subtreeResult;
- }
- }
- return null;
-}
-
-// Add a child -> parent link to the APZC tree rooted at 'root'.
-function addLink(root, child, parent) {
- var parentNode = findNode(root, parent);
- if (parentNode == null) {
- parentNode = makeNode(parent);
- root.children.push(parentNode);
- }
- parentNode.children.push(makeNode(child));
-}
-
-// Add a root node to the APZC tree. It will become a direct
-// child of 'root'.
-function addRoot(root, id) {
- root.children.push(makeNode(id));
-}
-
-// Given APZ test data for a single paint on the compositor side,
-// reconstruct the APZC tree structure from the 'parentScrollId'
-// entries that were logged. More specifically, the subset of the
-// APZC tree structure corresponding to the layer subtree for the
-// content process that triggered the paint, is reconstructed (as
-// the APZ test data only contains information abot this subtree).
-function buildApzcTree(paint) {
- // The APZC tree can potentially have multiple root nodes,
- // so we invent a node that is the parent of all roots.
- // This 'root' does not correspond to an APZC.
- var root = makeNode(-1);
- for (var scrollId in paint) {
- if ("isRootForLayersId" in paint[scrollId]) {
- addRoot(root, scrollId);
- } else if ("parentScrollId" in paint[scrollId]) {
- addLink(root, scrollId, paint[scrollId]["parentScrollId"]);
- }
- }
- return root;
-}
-
-function flushApzRepaints(aCallback, aWindow = window) {
- if (!aCallback) {
- throw "A callback must be provided!";
- }
- var repaintDone = function() {
- SpecialPowers.Services.obs.removeObserver(repaintDone, "apz-repaints-flushed", false);
- setTimeout(aCallback, 0);
- };
- SpecialPowers.Services.obs.addObserver(repaintDone, "apz-repaints-flushed", false);
- if (SpecialPowers.getDOMWindowUtils(aWindow).flushApzRepaints()) {
- dump("Flushed APZ repaints, waiting for callback...\n");
- } else {
- dump("Flushing APZ repaints was a no-op, triggering callback directly...\n");
- repaintDone();
- }
-}
diff --git a/gfx/layers/apz/test/helper_basic_pan.html b/gfx/layers/apz/test/helper_basic_pan.html
deleted file mode 100644
index 8876521683..0000000000
--- a/gfx/layers/apz/test/helper_basic_pan.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
- Sanity panning test
-
-
-
-
-
-
- Line 1
- Line 2
- Line 3
- Line 4
- Line 5
- Line 6
- Line 7
- Line 8
- Line 9
- Line 10
- Line 11
- Line 12
- Line 13
- Line 14
- Line 15
- Line 16
- Line 17
- Line 18
- Line 19
- Line 20
- Line 21
- Line 22
- Line 23
- Line 24
- Line 25
- Line 26
- Line 27
- Line 28
- Line 29
- Line 30
- Line 31
- Line 32
- Line 33
- Line 34
- Line 35
- Line 36
- Line 37
- Line 38
- Line 39
- Line 40
- Line 41
- Line 42
- Line 43
- Line 44
- Line 45
- Line 46
- Line 40
- Line 48
- Line 49
- Line 50
-
-
-
diff --git a/gfx/layers/apz/test/helper_div_pan.html b/gfx/layers/apz/test/helper_div_pan.html
deleted file mode 100644
index 8807611f66..0000000000
--- a/gfx/layers/apz/test/helper_div_pan.html
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
- Sanity panning test for scrollable div
-
-
-
-
-
-
-
-
diff --git a/gfx/layers/apz/test/helper_iframe_pan.html b/gfx/layers/apz/test/helper_iframe_pan.html
deleted file mode 100644
index e74be49ca0..0000000000
--- a/gfx/layers/apz/test/helper_iframe_pan.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
- Sanity panning test for scrollable div
-
-
-
-
-
-
-
- This div makes the top-level page scrollable.
-
-
-
diff --git a/gfx/layers/apz/test/helper_subframe_style.css b/gfx/layers/apz/test/helper_subframe_style.css
deleted file mode 100644
index a911bea711..0000000000
--- a/gfx/layers/apz/test/helper_subframe_style.css
+++ /dev/null
@@ -1,15 +0,0 @@
-body {
- height: 500px;
-}
-
-.inner-frame {
- margin-top: 25%;
- height: 200%;
- width: 75%;
- overflow: scroll;
-}
-.inner-content {
- height: 200%;
- width: 200%;
- background: repeating-linear-gradient(#EEE, #EEE 100px, #DDD 100px, #DDD 200px);
-}
diff --git a/gfx/layers/apz/test/mochitest.ini b/gfx/layers/apz/test/mochitest.ini
deleted file mode 100644
index 2834fe4c9b..0000000000
--- a/gfx/layers/apz/test/mochitest.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[DEFAULT]
-support-files = apz_test_utils.js
-[test_bug982141.html]
-skip-if = toolkit != 'gonk' # bug 991198
-support-files = helper_bug982141.html
-[test_bug1151663.html]
-skip-if = toolkit != 'gonk' # bug 991198
-support-files = helper_bug1151663.html
diff --git a/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js b/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
index ea4fcb28d5..6b8a43df93 100644
--- a/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
@@ -31,19 +31,56 @@ function nativeHorizontalWheelEventMsg() {
throw "Native wheel events not supported on platform " + getPlatform();
}
+// Given a pixel scrolling delta, converts it to the platform's native units.
+function nativeScrollUnits(aElement, aDimen) {
+ switch (getPlatform()) {
+ case "linux": {
+ // GTK deltas are treated as line height divided by 3 by gecko.
+ var targetWindow = aElement.ownerDocument.defaultView;
+ var lineHeight = targetWindow.getComputedStyle(aElement)["font-size"];
+ return aDimen / (parseInt(lineHeight) * 3);
+ }
+ }
+ return aDimen;
+}
+
+function nativeMouseMoveEventMsg() {
+ switch (getPlatform()) {
+ case "windows": return 1; // MOUSEEVENTF_MOVE
+ case "mac": return 5; // NSMouseMoved
+ case "linux": return 3; // GDK_MOTION_NOTIFY
+ }
+ throw "Native wheel events not supported on platform " + getPlatform();
+}
+
+// Convert (aX, aY), in CSS pixels relative to aElement's bounding rect,
+// to device pixels relative to aElement's containing window.
+function coordinatesRelativeToWindow(aX, aY, aElement) {
+ var targetWindow = aElement.ownerDocument.defaultView;
+ var scale = targetWindow.devicePixelRatio;
+ var rect = aElement.getBoundingClientRect();
+ return {
+ x: (targetWindow.mozInnerScreenX + rect.left + aX) * scale,
+ y: (targetWindow.mozInnerScreenY + rect.top + aY) * scale
+ };
+}
+
// Synthesizes a native mousewheel event and returns immediately. This does not
// guarantee anything; you probably want to use one of the other functions below
// which actually wait for results.
-// aX and aY are relative to |window|'s top-left. aDeltaX and aDeltaY
-// are pixel deltas, and aObserver can be left undefined if not needed.
+// aX and aY are relative to the top-left of |aElement|'s containing window.
+// aDeltaX and aDeltaY are pixel deltas, and aObserver can be left undefined
+// if not needed.
function synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY, aObserver) {
- aX += window.mozInnerScreenX;
- aY += window.mozInnerScreenY;
+ var pt = coordinatesRelativeToWindow(aX, aY, aElement);
if (aDeltaX && aDeltaY) {
throw "Simultaneous wheeling of horizontal and vertical is not supported on all platforms.";
}
+ aDeltaX = nativeScrollUnits(aElement, aDeltaX);
+ aDeltaY = nativeScrollUnits(aElement, aDeltaY);
var msg = aDeltaX ? nativeHorizontalWheelEventMsg() : nativeVerticalWheelEventMsg();
- _getDOMWindowUtils().sendNativeMouseScrollEvent(aX, aY, msg, aDeltaX, aDeltaY, 0, 0, 0, aElement, aObserver);
+ var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
+ utils.sendNativeMouseScrollEvent(pt.x, pt.y, msg, aDeltaX, aDeltaY, 0, 0, 0, aElement, aObserver);
return true;
}
@@ -63,13 +100,80 @@ function synthesizeNativeWheelAndWaitForObserver(aElement, aX, aY, aDeltaX, aDel
}
// Synthesizes a native mousewheel event and invokes the callback once the
-// wheel event is dispatched to the window. See synthesizeNativeWheel for
-// details on the parameters.
-function synthesizeNativeWheelAndWaitForEvent(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
- window.addEventListener("wheel", function wheelWaiter(e) {
- window.removeEventListener("wheel", wheelWaiter);
+// wheel event is dispatched to |aElement|'s containing window. If the event
+// targets content in a subdocument, |aElement| should be inside the
+// subdocument. See synthesizeNativeWheel for details on the other parameters.
+function synthesizeNativeWheelAndWaitForWheelEvent(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
+ var targetWindow = aElement.ownerDocument.defaultView;
+ targetWindow.addEventListener("wheel", function wheelWaiter(e) {
+ targetWindow.removeEventListener("wheel", wheelWaiter);
setTimeout(aCallback, 0);
});
return synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY);
}
+// Synthesizes a native mousewheel event and invokes the callback once the
+// first resulting scroll event is dispatched to |aElement|'s containing window.
+// If the event targets content in a subdocument, |aElement| should be inside
+// the subdocument. See synthesizeNativeWheel for details on the other
+// parameters.
+function synthesizeNativeWheelAndWaitForScrollEvent(aElement, aX, aY, aDeltaX, aDeltaY, aCallback) {
+ var targetWindow = aElement.ownerDocument.defaultView;
+ var useCapture = true; // scroll events don't always bubble
+ targetWindow.addEventListener("scroll", function scrollWaiter(e) {
+ targetWindow.removeEventListener("scroll", scrollWaiter, useCapture);
+ setTimeout(aCallback, 0);
+ }, useCapture);
+ return synthesizeNativeWheel(aElement, aX, aY, aDeltaX, aDeltaY);
+}
+
+// Synthesizes a native mouse move event and returns immediately.
+// aX and aY are relative to the top-left of |aElement|'s containing window.
+function synthesizeNativeMouseMove(aElement, aX, aY) {
+ var pt = coordinatesRelativeToWindow(aX, aY, aElement);
+ var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
+ utils.sendNativeMouseEvent(pt.x, pt.y, nativeMouseMoveEventMsg(), 0, aElement);
+ return true;
+}
+
+// Synthesizes a native mouse move event and invokes the callback once the
+// mouse move event is dispatched to |aElement|'s containing window. If the event
+// targets content in a subdocument, |aElement| should be inside the
+// subdocument. See synthesizeNativeMouseMove for details on the other
+// parameters.
+function synthesizeNativeMouseMoveAndWaitForMoveEvent(aElement, aX, aY, aCallback) {
+ var targetWindow = aElement.ownerDocument.defaultView;
+ targetWindow.addEventListener("mousemove", function mousemoveWaiter(e) {
+ targetWindow.removeEventListener("mousemove", mousemoveWaiter);
+ setTimeout(aCallback, 0);
+ });
+ return synthesizeNativeMouseMove(aElement, aX, aY);
+}
+
+// Synthesizes a native touch event and dispatches it. aX and aY in CSS pixels
+// relative to the top-left of |aElement|'s bounding rect.
+function synthesizeNativeTouch(aElement, aX, aY, aType, aObserver = null, aTouchId = 0) {
+ var pt = coordinatesRelativeToWindow(aX, aY, aElement);
+ var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
+ utils.sendNativeTouchPoint(aTouchId, aType, pt.x, pt.y, 1, 90, aObserver);
+ return true;
+}
+
+function synthesizeNativeDrag(aElement, aX, aY, aDeltaX, aDeltaY, aObserver = null, aTouchId = 0) {
+ synthesizeNativeTouch(aElement, aX, aY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
+ var steps = Math.max(Math.abs(aDeltaX), Math.abs(aDeltaY));
+ for (var i = 1; i < steps; i++) {
+ var dx = i * (aDeltaX / steps);
+ var dy = i * (aDeltaY / steps);
+ synthesizeNativeTouch(aElement, aX + dx, aY + dy, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
+ }
+ synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
+ return synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, aObserver, aTouchId);
+}
+
+function synthesizeNativeTap(aElement, aX, aY, aObserver = null) {
+ var pt = coordinatesRelativeToWindow(aX, aY, aElement);
+ var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
+ utils.sendNativeTouchTap(pt.x, pt.y, false, aObserver);
+ return true;
+}
diff --git a/gfx/layers/apz/test/mochitest/apz_test_utils.js b/gfx/layers/apz/test/mochitest/apz_test_utils.js
index 06eb7984bd..e82eda8de1 100644
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -97,3 +97,26 @@ function flushApzRepaints(aCallback, aWindow = window) {
repaintDone();
}
}
+
+// Flush repaints, APZ pending repaints, and any repaints resulting from that
+// flush. This is particularly useful if the test needs to reach some sort of
+// "idle" state in terms of repaints. Usually just doing waitForAllPaints
+// followed by flushApzRepaints is sufficient to flush all APZ state back to
+// the main thread, but it can leave a paint scheduled which will get triggered
+// at some later time. For tests that specifically test for painting at
+// specific times, this method is the way to go. Even if in doubt, this is the
+// preferred method as the extra step is "safe" and shouldn't interfere with
+// most tests.
+function waitForApzFlushedRepaints(aCallback) {
+ // First flush the main-thread paints and send transactions to the APZ
+ waitForAllPaints(function() {
+ // Then flush the APZ to make sure any repaint requests have been sent
+ // back to the main thread
+ flushApzRepaints(function() {
+ // Then flush the main-thread again to process the repaint requests.
+ // Once this is done, we should be in a stable state with nothing
+ // pending, so we can trigger the callback.
+ waitForAllPaints(aCallback);
+ });
+ });
+}
diff --git a/gfx/layers/apz/test/helper_bug1151663.html b/gfx/layers/apz/test/mochitest/helper_bug1151663.html
similarity index 88%
rename from gfx/layers/apz/test/helper_bug1151663.html
rename to gfx/layers/apz/test/mochitest/helper_bug1151663.html
index 15b3dc011a..ef2fde9a95 100644
--- a/gfx/layers/apz/test/helper_bug1151663.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug1151663.html
@@ -55,15 +55,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1151663
// Convert the test data into a representation that's easier to navigate.
contentTestData = convertTestData(contentTestData);
compositorTestData = convertTestData(compositorTestData);
+ var paint = compositorTestData.paints[lastCompositorPaintSeqNo];
// Reconstruct the APZC tree structure in the last paint.
- var apzcTree = buildApzcTree(compositorTestData.paints[lastCompositorPaintSeqNo]);
+ var apzcTree = buildApzcTree(paint);
// The apzc tree for this page should consist of a single root APZC,
- // and no child APZCs.
- SimpleTest.is(apzcTree.children.length, 1, "expected a single root APZC");
- var rootApzc = apzcTree.children[0];
- SimpleTest.is(rootApzc.children.length, 0, "expected no child APZCs");
+ // which either is the RCD with no child APZCs (e10s/B2G case) or has a
+ // single child APZC which is for the RCD (fennec case).
+ var rcd = findRcdNode(apzcTree);
+ SimpleTest.ok(rcd != null, "found the RCD node");
+ SimpleTest.is(rcd.children.length, 0, "expected no children on the RCD");
window.opener.finishTest();
}
diff --git a/gfx/layers/apz/test/mochitest/helper_bug982141.html b/gfx/layers/apz/test/mochitest/helper_bug982141.html
index d81f65fd03..4167e64935 100644
--- a/gfx/layers/apz/test/mochitest/helper_bug982141.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug982141.html
@@ -5,6 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=982141
-->
+
Test for Bug 982141, helper page
-
+
Mozilla Bug 982141
-
+
+
+ Wide content so that the vertical scrollbar for the parent div
+ doesn't eat into the 50px width and reduce the width of the
+ displayport.
+
Line 1
Line 2
Line 3
diff --git a/gfx/layers/apz/test/mochitest/helper_scrollto_tap.html b/gfx/layers/apz/test/mochitest/helper_scrollto_tap.html
new file mode 100644
index 0000000000..0c021ce9cf
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_scrollto_tap.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+ Sanity touch-tapping test
+
+
+
+
+
+
+
spacer
+
+
+
diff --git a/gfx/layers/apz/test/mochitest/helper_subframe_style.css b/gfx/layers/apz/test/mochitest/helper_subframe_style.css
index a911bea711..5af9640802 100644
--- a/gfx/layers/apz/test/mochitest/helper_subframe_style.css
+++ b/gfx/layers/apz/test/mochitest/helper_subframe_style.css
@@ -3,7 +3,7 @@ body {
}
.inner-frame {
- margin-top: 25%;
+ margin-top: 50px; /* this should be at least 30px */
height: 200%;
width: 75%;
overflow: scroll;
diff --git a/gfx/layers/apz/test/mochitest/helper_tap.html b/gfx/layers/apz/test/mochitest/helper_tap.html
new file mode 100644
index 0000000000..c7cbc4a98c
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_tap.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+ Sanity touch-tapping test
+
+
+
+
+
+
+
+
+
diff --git a/gfx/layers/apz/test/mochitest/mochitest.ini b/gfx/layers/apz/test/mochitest/mochitest.ini
index ea876dfd4e..d1de52a8ea 100644
--- a/gfx/layers/apz/test/mochitest/mochitest.ini
+++ b/gfx/layers/apz/test/mochitest/mochitest.ini
@@ -1,17 +1,22 @@
-[test_bug982141.html]
-skip-if = toolkit != 'gonk' # bug 991198
+[DEFAULT]
support-files =
apz_test_utils.js
+ apz_test_native_event_utils.js
helper_bug982141.html
+ helper_bug1151663.html
helper_iframe1.html
helper_iframe2.html
helper_subframe_style.css
helper_basic_pan.html
helper_div_pan.html
helper_iframe_pan.html
+ helper_scrollto_tap.html
+ helper_tap.html
tags = apz
+[test_bug982141.html]
+[test_bug1151663.html]
[test_wheel_scroll.html]
-skip-if = (os == 'android') || (os == 'b2g') # wheel events not supported
+skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
[test_wheel_transactions.html]
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
[test_bug1151667.html]
@@ -28,3 +33,8 @@ skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel ev
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
[test_scroll_subframe_scrollbar.html]
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
+[test_frame_reconstruction.html]
+[test_tap.html]
+# Windows touch injection doesn't work in automation, but this test can be run locally on a windows touch device.
+# On OS X we don't support touch events at all.
+skip-if = (toolkit == 'windows') || (toolkit == 'cocoa')
diff --git a/gfx/layers/apz/test/mochitest/test_basic_pan.html b/gfx/layers/apz/test/mochitest/test_basic_pan.html
index 455b60135e..d2b2e3267e 100644
--- a/gfx/layers/apz/test/mochitest/test_basic_pan.html
+++ b/gfx/layers/apz/test/mochitest/test_basic_pan.html
@@ -8,7 +8,6 @@
+
+
+
+
+
+
+
+
+Mozilla Bug 1235899
+
+
+
You should be able to fling this list without it stopping abruptly