blob: 11b430b15fcbe3acfeed2e442e4d6596b9605cb8 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "v8/include/v8.h"
namespace blink {
class DOMWrapperWorld;
class Event;
class EventTarget;
class SourceLocation;
// |JSBasedEventListener| is the base class for JS-based event listeners,
// i.e. EventListener and EventHandler in the standards.
// This provides the essential APIs of JS-based event listeners and also
// implements the common features.
class CORE_EXPORT JSBasedEventListener : public EventListener {
static const JSBasedEventListener* Cast(const EventListener* listener) {
return listener && listener->IsJSBased()
? static_cast<const JSBasedEventListener*>(listener)
: nullptr;
static JSBasedEventListener* Cast(EventListener* listener) {
return const_cast<JSBasedEventListener*>(
Cast(const_cast<const EventListener*>(listener)));
// TODO(bindings): consider to remove this (and use GetListenerObject()
// instead) because this method is used in mostly only generated classes.
static v8::Local<v8::Value> GetListenerOrNull(v8::Isolate* isolate,
EventTarget* event_target,
EventListener* listener) {
if (auto* v8_listener = Cast(listener))
return v8_listener->GetListenerObject(*event_target);
return v8::Null(isolate);
~JSBasedEventListener() override;
// blink::EventListener overrides:
bool BelongsToTheCurrentWorld(ExecutionContext*) const final;
// Implements step 2. of "inner invoke".
// See:
void Invoke(ExecutionContext*, Event*) final;
// |GetListenerObject()| and |GetEffectiveFunction()| may cause JS in the
// content attribute to get compiled, potentially unsuccessfully.
// Implements "get the current value of the event handler".
// Returns v8::Null with firing error event instead of throwing an exception
// on failing to compile the uncompiled script body in eventHandler's value.
// Also, this can return empty because of .
virtual v8::Local<v8::Value> GetListenerObject(EventTarget&) = 0;
// Returns v8::Function that handles invoked event or v8::Undefined without
// throwing any exception.
virtual v8::Local<v8::Value> GetEffectiveFunction(EventTarget&) = 0;
// Only DevTools is allowed to use this method.
DOMWrapperWorld& GetWorldForInspector() const { return GetWorld(); }
virtual std::unique_ptr<SourceLocation> GetSourceLocation(EventTarget&);
explicit JSBasedEventListener(ListenerType);
virtual v8::Isolate* GetIsolate() const = 0;
virtual ScriptState* GetScriptState() const = 0;
virtual DOMWrapperWorld& GetWorld() const = 0;
// Performs "call a user object's operation", required in "inner-invoke".
// "The event handler processing algorithm" corresponds to this in the case of
// EventHandler.
// This may throw an exception on invoking the listener.
// See step 2-10:
virtual void InvokeInternal(EventTarget&,
v8::Local<v8::Value> js_event) = 0;
} // namespace blink