1 // Copyright (c) 2011 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 #include "chrome/browser/sync/js_event_handler_list.h" 6 7 #include <cstddef> 8 9 #include "base/logging.h" 10 #include "chrome/browser/sync/js_backend.h" 11 #include "chrome/browser/sync/js_event_handler.h" 12 13 namespace browser_sync { 14 15 JsEventHandlerList::PendingMessage::PendingMessage( 16 const std::string& name, const JsArgList& args, 17 const JsEventHandler* sender) 18 : name(name), args(args), sender(sender) {} 19 20 JsEventHandlerList::JsEventHandlerList() : backend_(NULL) {} 21 22 JsEventHandlerList::~JsEventHandlerList() { 23 RemoveBackend(); 24 } 25 26 // We connect to the backend only when necessary, i.e. when there is 27 // at least one handler. 28 29 void JsEventHandlerList::AddHandler(JsEventHandler* handler) { 30 handlers_.AddObserver(handler); 31 if (backend_) { 32 backend_->SetParentJsEventRouter(this); 33 } 34 } 35 36 void JsEventHandlerList::RemoveHandler(JsEventHandler* handler) { 37 handlers_.RemoveObserver(handler); 38 if (backend_ && handlers_.size() == 0) { 39 backend_->RemoveParentJsEventRouter(); 40 } 41 } 42 43 void JsEventHandlerList::SetBackend(JsBackend* backend) { 44 DCHECK(!backend_); 45 DCHECK(backend); 46 backend_ = backend; 47 48 if (handlers_.size() > 0) { 49 backend_->SetParentJsEventRouter(this); 50 51 // Process any queued messages. 52 PendingMessageList pending_messages; 53 pending_messages_.swap(pending_messages); 54 for (PendingMessageList::const_iterator it = pending_messages.begin(); 55 it != pending_messages.end(); ++it) { 56 backend_->ProcessMessage(it->name, it->args, it->sender); 57 } 58 } 59 } 60 61 void JsEventHandlerList::RemoveBackend() { 62 if (backend_) { 63 backend_->RemoveParentJsEventRouter(); 64 backend_ = NULL; 65 } 66 } 67 68 void JsEventHandlerList::ProcessMessage( 69 const std::string& name, const JsArgList& args, 70 const JsEventHandler* sender) { 71 if (backend_) { 72 backend_->ProcessMessage(name, args, sender); 73 } else { 74 pending_messages_.push_back(PendingMessage(name, args, sender)); 75 } 76 } 77 78 void JsEventHandlerList::RouteJsEvent(const std::string& name, 79 const JsArgList& args, 80 const JsEventHandler* target) { 81 if (target) { 82 JsEventHandler* non_const_target(const_cast<JsEventHandler*>(target)); 83 if (handlers_.HasObserver(non_const_target)) { 84 non_const_target->HandleJsEvent(name, args); 85 } else { 86 VLOG(1) << "Unknown target; dropping event " << name 87 << " with args " << args.ToString(); 88 } 89 } else { 90 FOR_EACH_OBSERVER(JsEventHandler, handlers_, HandleJsEvent(name, args)); 91 } 92 } 93 94 } // namespace browser_sync 95