| // Copyright 2015 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef COBALT_DOM_EVENT_H_ |
| #define COBALT_DOM_EVENT_H_ |
| |
| #include <string> |
| |
| #include "base/memory/weak_ptr.h" |
| #include "cobalt/base/token.h" |
| #include "cobalt/dom/event_init.h" |
| #include "cobalt/script/wrappable.h" |
| |
| namespace cobalt { |
| namespace dom { |
| |
| // The forward declaration is necessary for breaking the bi-directional |
| // dependency between Event and EventTarget. |
| class EventTarget; |
| |
| // The Event interface can be passed from the event target to event listener to |
| // pass information between them. |
| // https://www.w3.org/TR/2014/WD-dom-20140710/#interface-event |
| // |
| // TODO: We only support the attributes/methods that are in use. |
| // We need to investigate the exact subset of them required in Cobalt. |
| class Event : public script::Wrappable { |
| public: |
| // Web API: Event |
| // EventPhase values as defined by Web API Event.eventPhase. |
| // |
| typedef uint16 EventPhase; |
| enum EventPhaseInternal : uint16 { |
| kNone, |
| kCapturingPhase, |
| kAtTarget, |
| kBubblingPhase |
| }; |
| |
| // Custom, not in any spec. |
| // |
| enum Bubbles { kNotBubbles, kBubbles }; |
| |
| enum Cancelable { kNotCancelable, kCancelable }; |
| |
| enum UninitializedFlag { Uninitialized }; |
| |
| // Creates an event with its "initialized flag" unset. |
| explicit Event(UninitializedFlag uninitialized_flag); |
| |
| // Creates an event that cannot be bubbled and cancelled. |
| explicit Event(const std::string& type); |
| explicit Event(base::Token type); |
| Event(const std::string& type, const EventInit& init_dict); |
| Event(base::Token type, Bubbles bubbles, Cancelable cancelable); |
| Event(base::Token type, const EventInit& init_dict); |
| |
| ~Event() override; |
| |
| // Web API: Event |
| // |
| base::Token type() const { return type_; } |
| const scoped_refptr<EventTarget>& target() const; |
| const scoped_refptr<EventTarget>& current_target() const; |
| EventPhase event_phase() const { return event_phase_; } |
| |
| void StopPropagation() { propagation_stopped_ = true; } |
| void StopImmediatePropagation() { |
| propagation_stopped_ = true; |
| immediate_propagation_stopped_ = true; |
| } |
| |
| bool bubbles() const { return bubbles_; } |
| bool cancelable() const { return cancelable_; } |
| void PreventDefault() { |
| if (cancelable()) { |
| default_prevented_ = true; |
| } |
| } |
| bool default_prevented() const { return default_prevented_; } |
| |
| uint64 time_stamp() const { return time_stamp_; } |
| |
| void InitEvent(const std::string& type, bool bubbles, bool cancelable); |
| |
| // Custom, not in any spec. |
| // |
| bool IsBeingDispatched() const { return event_phase() != kNone; } |
| void set_target(const scoped_refptr<EventTarget>& target); |
| void set_current_target(const scoped_refptr<EventTarget>& target); |
| void set_event_phase(EventPhase event_phase) { event_phase_ = event_phase; } |
| // We link whether the event has the "initialized flag" set to whether it has |
| // a non-empty type. Note that the spec doesn't explicitly prevent an Event |
| // to have empty string as its type but it is reasonable to make this |
| // assumption and Chrome has the same behavior. |
| bool initialized_flag() const { return type_ != ""; } |
| |
| // The event dispatching process usually looks like: |
| // |
| // for (each event target) { |
| // for (each event listener in the current target) { |
| // listener->handleEvent(event); |
| // if (event->immediate_propagation_stopped()) break; |
| // } |
| // if (event->propagation_stopped()) break; |
| // } |
| // |
| // When propagation_stopped() returns true, the inside loop will continue but |
| // the outside loop will break. |
| bool propagation_stopped() const { return propagation_stopped_; } |
| // When immediate_propagation_stopped() returns true, the inside loop will |
| // break. As StopImmediatePropagation() will also set propagation_stopped_ to |
| // true. This implies the outside loop will be break too. |
| bool immediate_propagation_stopped() const { |
| return immediate_propagation_stopped_; |
| } |
| |
| // https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp |
| // An event's timeStamp should represent time since document creation, not |
| // real time. However, the old spec specifies time since 1970. To facilitate |
| // the transition to the new spec, use this function to calculate an event's |
| // time stamp. |
| static uint64 GetEventTime(SbTimeMonotonic monotonic_time); |
| |
| DEFINE_WRAPPABLE_TYPE(Event); |
| void TraceMembers(script::Tracer* tracer) override; |
| |
| private: |
| void InitEventInternal(base::Token type, bool bubbles, bool cancelable); |
| |
| base::Token type_; |
| |
| scoped_refptr<EventTarget> target_; |
| scoped_refptr<EventTarget> current_target_; |
| EventPhase event_phase_; |
| |
| bool propagation_stopped_; |
| bool immediate_propagation_stopped_; |
| |
| bool bubbles_; |
| bool cancelable_; |
| bool default_prevented_; |
| |
| uint64 time_stamp_; |
| }; |
| |
| } // namespace dom |
| } // namespace cobalt |
| |
| #endif // COBALT_DOM_EVENT_H_ |