Bug 1355497: Ignore preventDefault on pointerdown by WebExtensions. r=smaug.

Prevent default on pointerdown will stop firing the subsequent mouse events. Ignore the case that preventDefault by WebExtensions to avoid breaking some websites.

MozReview-Commit-ID: 9ztW1WfEg9a
This commit is contained in:
Stone Shih 2017-07-10 16:42:01 +08:00
Родитель 5b67de0d02
Коммит 6cbc21aa58
6 изменённых файлов: 86 добавлений и 11 удалений

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

@ -27,6 +27,7 @@ support-files =
[browser_permissions_mozAddonManager.js]
[browser_permissions_optional.js]
skip-if = !e10s
[browser_permissions_pointerevent.js]
[browser_permissions_unsigned.js]
skip-if = require_signing
[browser_update_checkForUpdates.js]

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

@ -0,0 +1,48 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(async function test_pointerevent() {
async function contentScript() {
document.addEventListener("pointerdown", async (e) => {
browser.test.assertTrue(true, "Should receive pointerdown");
e.preventDefault();
});
document.addEventListener("mousedown", (e) => {
browser.test.assertTrue(true, "Should receive mousedown");
});
document.addEventListener("mouseup", (e) => {
browser.test.assertTrue(true, "Should receive mouseup");
});
document.addEventListener("pointerup", (e) => {
browser.test.assertTrue(true, "Should receive pointerup");
browser.test.sendMessage("done");
});
browser.test.sendMessage("pageReady");
}
let extension = ExtensionTestUtils.loadExtension({
background() {
browser.test.sendMessage("ready", browser.runtime.getURL("page.html"));
},
files: {
"page.html": `<html><head><script src="page.js"></script></head></html>`,
"page.js": contentScript,
},
});
await extension.startup();
await new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true]]}, resolve);
});
let url = await extension.awaitMessage("ready");
await BrowserTestUtils.withNewTab({gBrowser, url}, async browser => {
await extension.awaitMessage("pageReady");
await BrowserTestUtils.synthesizeMouseAtCenter("html", {type: "mousedown", button: 0}, browser);
await BrowserTestUtils.synthesizeMouseAtCenter("html", {type: "mouseup", button: 0}, browser);
await extension.awaitMessage("done");
});
await extension.unload();
});

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

@ -484,11 +484,15 @@ Event::PreventDefault(JSContext* aCx, CallerType aCallerType)
// Then, JS in content mey be call preventDefault()
// even in the event is in system event group. Therefore, don't refer
// mInSystemGroup here.
PreventDefaultInternal(aCallerType == CallerType::System);
nsIPrincipal* principal = mIsMainThreadEvent ?
nsContentUtils::SubjectPrincipal(aCx) : nullptr;
PreventDefaultInternal(aCallerType == CallerType::System, principal);
}
void
Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
Event::PreventDefaultInternal(bool aCalledByDefaultHandler,
nsIPrincipal* aPrincipal)
{
if (!mEvent->mFlags.mCancelable) {
return;
@ -507,7 +511,7 @@ Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
return;
}
mEvent->PreventDefault(aCalledByDefaultHandler);
mEvent->PreventDefault(aCalledByDefaultHandler, aPrincipal);
if (!IsTrusted()) {
return;

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

@ -244,7 +244,8 @@ public:
* by a call of Event.preventDefault() in
* content script, false.
*/
void PreventDefaultInternal(bool aCalledByDefaultHandler);
void PreventDefaultInternal(bool aCalledByDefaultHandler,
nsIPrincipal* aPrincipal = nullptr);
bool IsMainThreadEvent()
{

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

@ -613,13 +613,9 @@ public:
*/
void StopPropagation() { mFlags.StopPropagation(); }
void StopImmediatePropagation() { mFlags.StopImmediatePropagation(); }
void PreventDefault(bool aCalledByDefaultHandler = true)
{
// Legacy mouse events shouldn't be prevented on ePointerDown by default
// handlers.
MOZ_RELEASE_ASSERT(!aCalledByDefaultHandler || mMessage != ePointerDown);
mFlags.PreventDefault(aCalledByDefaultHandler);
}
void PreventDefault(bool aCalledByDefaultHandler = true,
nsIPrincipal* aPrincipal = nullptr);
void PreventDefaultBeforeDispatch() { mFlags.PreventDefaultBeforeDispatch(); }
bool DefaultPrevented() const { return mFlags.DefaultPrevented(); }
bool DefaultPreventedByContent() const

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

@ -13,6 +13,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
#include "nsContentUtils.h"
#include "nsIContent.h"
#include "nsIDOMEventTarget.h"
#include "nsPrintfCString.h"
@ -515,6 +516,30 @@ WidgetEvent::GetOriginalDOMEventTarget() const
return GetDOMEventTarget();
}
void
WidgetEvent::PreventDefault(bool aCalledByDefaultHandler,
nsIPrincipal* aPrincipal)
{
if (mMessage == ePointerDown) {
if (aCalledByDefaultHandler) {
// Shouldn't prevent default on pointerdown by default handlers to stop
// firing legacy mouse events. Use MOZ_ASSERT to catch incorrect usages
// in debug builds.
MOZ_ASSERT(false);
return;
}
if (aPrincipal) {
nsAutoString addonId;
Unused << NS_WARN_IF(NS_FAILED(aPrincipal->GetAddonId(addonId)));
if (!addonId.IsEmpty()) {
// Ignore the case that it's called by a web extension.
return;
}
}
}
mFlags.PreventDefault(aCalledByDefaultHandler);
}
/******************************************************************************
* mozilla::WidgetInputEvent
******************************************************************************/