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 13namespace browser_sync { 14 15JsEventHandlerList::PendingMessage::PendingMessage( 16 const std::string& name, const JsArgList& args, 17 const JsEventHandler* sender) 18 : name(name), args(args), sender(sender) {} 19 20JsEventHandlerList::JsEventHandlerList() : backend_(NULL) {} 21 22JsEventHandlerList::~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 29void JsEventHandlerList::AddHandler(JsEventHandler* handler) { 30 handlers_.AddObserver(handler); 31 if (backend_) { 32 backend_->SetParentJsEventRouter(this); 33 } 34} 35 36void JsEventHandlerList::RemoveHandler(JsEventHandler* handler) { 37 handlers_.RemoveObserver(handler); 38 if (backend_ && handlers_.size() == 0) { 39 backend_->RemoveParentJsEventRouter(); 40 } 41} 42 43void 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 61void JsEventHandlerList::RemoveBackend() { 62 if (backend_) { 63 backend_->RemoveParentJsEventRouter(); 64 backend_ = NULL; 65 } 66} 67 68void 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 78void 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