Commit 0e41c539 authored by dtapuska's avatar dtapuska Committed by Commit bot

Clarify devtools console log when a passive event listener is preventDefaulted.

Add a reference to the chromestatus entry regarding document level
passive event listeners.

BUG=627104

Review-Url: https://codereview.chromium.org/2272993004
Cr-Commit-Position: refs/heads/master@{#414462}
parent 5aba5ce9
......@@ -80,8 +80,8 @@ Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableAr
, m_cancelBubble(false)
, m_wasInitialized(true)
, m_isTrusted(false)
, m_handlingPassive(false)
, m_preventDefaultCalledOnUncancelableEvent(false)
, m_handlingPassive(PassiveMode::NotPassive)
, m_eventPhase(0)
, m_currentTarget(nullptr)
, m_platformTimeStamp(platformTimeStamp)
......@@ -225,11 +225,26 @@ bool Event::isBeforeUnloadEvent() const
void Event::preventDefault()
{
if (m_handlingPassive) {
if (m_handlingPassive != PassiveMode::NotPassive) {
m_preventDefaultCalledDuringPassive = true;
const LocalDOMWindow* window = m_eventPath ? m_eventPath->windowEventContext().window() : 0;
if (window)
window->printErrorMessage("Unable to preventDefault inside passive event listener invocation.");
if (window) {
const char* devToolsMsg = nullptr;
switch (m_handlingPassive) {
case PassiveMode::NotPassive:
NOTREACHED();
break;
case PassiveMode::Passive:
devToolsMsg = "Unable to preventDefault inside passive event listener invocation.";
break;
case PassiveMode::PassiveForcedDocumentLevel:
devToolsMsg = "Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080";
break;
}
if (devToolsMsg)
window->printErrorMessage(devToolsMsg);
}
return;
}
......@@ -281,9 +296,9 @@ HeapVector<Member<EventTarget>> Event::composedPath(ScriptState* scriptState) co
return pathInternal(scriptState, EmptyAfterDispatch);
}
void Event::setHandlingPassive(bool value)
void Event::setHandlingPassive(PassiveMode mode)
{
m_handlingPassive = value;
m_handlingPassive = mode;
m_preventDefaultCalledDuringPassive = false;
}
......
......@@ -79,6 +79,12 @@ public:
Scoped,
};
enum class PassiveMode {
NotPassive,
Passive,
PassiveForcedDocumentLevel,
};
static Event* create()
{
return new Event;
......@@ -211,7 +217,7 @@ public:
bool isTrusted() const { return m_isTrusted; }
void setTrusted(bool value) { m_isTrusted = value; }
void setHandlingPassive(bool value);
void setHandlingPassive(PassiveMode);
bool preventDefaultCalledDuringPassive() const { return m_preventDefaultCalledDuringPassive; }
......@@ -230,6 +236,8 @@ protected:
void setCanBubble(bool bubble) { m_canBubble = bubble; }
PassiveMode handlingPassive() const { return m_handlingPassive; }
private:
enum EventPathMode {
......@@ -252,7 +260,6 @@ private:
unsigned m_cancelBubble:1;
unsigned m_wasInitialized:1;
unsigned m_isTrusted : 1;
unsigned m_handlingPassive : 1;
// Whether preventDefault was called when |m_handlingPassive| is
// true. This field is reset on each call to setHandlingPassive.
......@@ -260,6 +267,7 @@ private:
// Whether preventDefault was called on uncancelable event.
unsigned m_preventDefaultCalledOnUncancelableEvent : 1;
PassiveMode m_handlingPassive;
unsigned short m_eventPhase;
Member<EventTarget> m_currentTarget;
Member<EventTarget> m_target;
......
......@@ -65,6 +65,15 @@ enum PassiveForcedListenerResultType {
PassiveForcedListenerResultTypeMax
};
Event::PassiveMode eventPassiveMode(const RegisteredEventListener& eventListener)
{
if (!eventListener.passive())
return Event::PassiveMode::NotPassive;
if (eventListener.passiveForcedForDocumentTarget())
return Event::PassiveMode::PassiveForcedDocumentLevel;
return Event::PassiveMode::Passive;
}
Settings* windowSettings(LocalDOMWindow* executingWindow)
{
if (executingWindow) {
......@@ -627,7 +636,7 @@ bool EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventList
if (event->immediatePropagationStopped())
break;
event->setHandlingPassive(registeredListener.passive());
event->setHandlingPassive(eventPassiveMode(registeredListener));
bool passiveForced = registeredListener.passiveForcedForDocumentTarget();
InspectorInstrumentation::NativeBreakpoint nativeBreakpoint(context, this, event);
......@@ -655,7 +664,7 @@ bool EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventList
passiveForcedHistogram.count(breakageType);
}
event->setHandlingPassive(false);
event->setHandlingPassive(Event::PassiveMode::NotPassive);
CHECK_LE(i, size);
}
......
......@@ -204,7 +204,7 @@ void TouchEvent::preventDefault()
// A common developer error is to wait too long before attempting to stop
// scrolling by consuming a touchmove event. Generate a warning if this
// event is uncancelable.
if (!cancelable() && view() && view()->isLocalDOMWindow() && view()->frame()) {
if (!cancelable() && handlingPassive() == PassiveMode::NotPassive && view() && view()->isLocalDOMWindow() && view()->frame()) {
toLocalDOMWindow(view())->frame()->console().addMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel,
"Ignored attempt to cancel a " + type() + " event with cancelable=false, for example because scrolling is in progress and cannot be interrupted."));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment