1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_FOR_CONTENT_ATTRIBUTE_H_
6 #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_FOR_CONTENT_ATTRIBUTE_H_
7 
8 #include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h"
9 #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
10 #include "third_party/blink/renderer/platform/wtf/text/text_position.h"
11 
12 namespace blink {
13 
14 class QualifiedName;
15 
16 // |JSEventHandlerForContentAttribute| supports lazy compilation for content
17 // attribute. This performs in the same way as |JSEventHandler| after it gets
18 // compiled.
19 class JSEventHandlerForContentAttribute final : public JSEventHandler {
20  public:
21   static JSEventHandlerForContentAttribute* Create(
22       ExecutionContext*,
23       const QualifiedName&,
24       const AtomicString& value,
25       JSEventHandler::HandlerType = JSEventHandler::HandlerType::kEventHandler);
26   JSEventHandlerForContentAttribute(ExecutionContext*,
27                                     const QualifiedName&,
28                                     const AtomicString& value,
29                                     JSEventHandler::HandlerType);
30 
31   // blink::EventListener overrides:
IsEventHandlerForContentAttribute()32   bool IsEventHandlerForContentAttribute() const override { return true; }
33 
34   // blink::JSBasedEventListener overrides:
35   v8::Local<v8::Value> GetListenerObject(EventTarget&) override;
36   std::unique_ptr<SourceLocation> GetSourceLocation(EventTarget&) override;
37 
ScriptBody()38   const String& ScriptBody() const override { return script_body_; }
39 
40  protected:
41   // blink::JSBasedEventListener override:
GetIsolate()42   v8::Isolate* GetIsolate() const override { return isolate_; }
GetScriptState()43   ScriptState* GetScriptState() const override {
44     DCHECK(HasCompiledHandler());
45     return JSEventHandler::GetScriptState();
46   }
47 
48   // An assumption here is that the content attributes are used only in the main
49   // world or the isolated world for the content scripts, they are never used in
50   // other isolated worlds nor worker/worklets.
51   // In case of the content scripts, Blink runs script in the main world instead
52   // of the isolated world for the content script by design.
GetWorld()53   DOMWrapperWorld& GetWorld() const override {
54     return DOMWrapperWorld::MainWorld();
55   }
56 
57  private:
58   // Implements Step 3. of "get the current value of the event handler".
59   // The compiled v8::Function is returned and |JSEventHandler::event_handler_|
60   // gets initialized with it if lazy compilation succeeds.
61   // Otherwise, v8::Null is returned.
62   // https://html.spec.whatwg.org/C/#getting-the-current-value-of-the-event-handler
63   v8::Local<v8::Value> GetCompiledHandler(EventTarget&);
64 
65   // Lazy compilation for content attribute should be tried only once, but we
66   // cannot see whether it had never tried to compile or it has already failed
67   // when |HasCompiledHandler()| returns false. |did_compile_| is used for
68   // checking that.
69   bool did_compile_;
70   const AtomicString function_name_;
71   String script_body_;
72   String source_url_;
73   TextPosition position_;
74   v8::Isolate* isolate_;
75 };
76 
77 }  // namespace blink
78 
79 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_FOR_CONTENT_ATTRIBUTE_H_
80