| // Copyright 2018 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. |
| |
| #include "cobalt/dom/generic_event_handler_reference.h" |
| |
| #include "base/debug/trace_event.h" |
| #include "cobalt/dom/event.h" |
| #include "cobalt/dom/event_target.h" |
| #include "cobalt/dom/script_event_log.h" |
| |
| namespace cobalt { |
| namespace dom { |
| |
| GenericEventHandlerReference::GenericEventHandlerReference( |
| script::Wrappable* wrappable, |
| const EventListenerScriptValue& script_value) { |
| if (!script_value.IsNull()) { |
| event_listener_reference_.reset( |
| new EventListenerScriptValue::Reference(wrappable, script_value)); |
| } |
| } |
| |
| GenericEventHandlerReference::GenericEventHandlerReference( |
| script::Wrappable* wrappable, |
| const OnErrorEventListenerScriptValue& script_value) { |
| if (!script_value.IsNull()) { |
| on_error_event_listener_reference_.reset( |
| new OnErrorEventListenerScriptValue::Reference(wrappable, |
| script_value)); |
| } |
| } |
| |
| GenericEventHandlerReference::GenericEventHandlerReference( |
| script::Wrappable* wrappable, const GenericEventHandlerReference& other) { |
| if (other.event_listener_reference_) { |
| event_listener_reference_.reset(new EventListenerScriptValue::Reference( |
| wrappable, other.event_listener_reference_->referenced_value())); |
| } else if (other.on_error_event_listener_reference_) { |
| on_error_event_listener_reference_.reset( |
| new OnErrorEventListenerScriptValue::Reference( |
| wrappable, |
| other.on_error_event_listener_reference_->referenced_value())); |
| } |
| } |
| |
| void GenericEventHandlerReference::HandleEvent( |
| const scoped_refptr<Event>& event, bool is_attribute, |
| bool unpack_error_event) { |
| TRACE_EVENT1("cobalt::dom", "GenericEventHandlerReference::HandleEvent", |
| "Event Name", TRACE_STR_COPY(event->type().c_str())); |
| script_event_log.Get().PushEvent(event); |
| |
| bool had_exception; |
| base::optional<bool> result; |
| |
| // Forward the HandleEvent() call to the appropriate internal object. |
| if (event_listener_reference_) { |
| // Non-onerror event handlers cannot have their parameters unpacked. |
| result = event_listener_reference_->value().HandleEvent( |
| event->current_target(), event, &had_exception); |
| } else if (on_error_event_listener_reference_) { |
| result = on_error_event_listener_reference_->value().HandleEvent( |
| event->current_target(), event, &had_exception, unpack_error_event); |
| } else { |
| NOTREACHED(); |
| had_exception = true; |
| } |
| |
| script_event_log.Get().PopEvent(); |
| |
| if (had_exception) { |
| return; |
| } |
| // EventHandlers (EventListeners set as attributes) may return false rather |
| // than call event.preventDefault() in the handler function. |
| if (is_attribute && result && !result.value()) { |
| event->PreventDefault(); |
| } |
| } |
| |
| bool GenericEventHandlerReference::EqualTo( |
| const EventListenerScriptValue& other) { |
| return (IsNull() && other.IsNull()) || |
| (event_listener_reference_ && |
| event_listener_reference_->referenced_value().EqualTo(other)); |
| } |
| |
| bool GenericEventHandlerReference::EqualTo( |
| const GenericEventHandlerReference& other) { |
| if (IsNull() && other.IsNull()) { |
| return true; |
| } |
| |
| if (event_listener_reference_ && other.event_listener_reference_) { |
| return event_listener_reference_->referenced_value().EqualTo( |
| other.event_listener_reference_->referenced_value()); |
| } |
| if (on_error_event_listener_reference_ && |
| other.on_error_event_listener_reference_) { |
| return on_error_event_listener_reference_->referenced_value().EqualTo( |
| other.on_error_event_listener_reference_->referenced_value()); |
| } |
| return false; |
| } |
| |
| bool GenericEventHandlerReference::IsNull() const { |
| return (!event_listener_reference_ || |
| event_listener_reference_->referenced_value().IsNull()) && |
| (!on_error_event_listener_reference_ || |
| on_error_event_listener_reference_->referenced_value().IsNull()); |
| } |
| |
| } // namespace dom |
| } // namespace cobalt |