// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/webui/cookies_tree_model_adapter.h" #include "base/memory/scoped_ptr.h" #include "base/string_number_conversions.h" #include "base/values.h" #include "chrome/browser/ui/webui/cookies_tree_model_util.h" #include "content/browser/webui/web_ui.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" namespace { // Returns a unique callback name for |adapter|'s requestChildren. std::string GetRequestChildrenCallbackName(CookiesTreeModelAdapter* adapter) { static const char kPrefixLoadCookie[] = "requestChildren"; return std::string(kPrefixLoadCookie) + base::HexEncode(&adapter, sizeof(adapter)); } } // namespace CookiesTreeModelAdapter::CookiesTreeModelAdapter() : web_ui_(NULL), model_(NULL), batch_update_(false) { } CookiesTreeModelAdapter::~CookiesTreeModelAdapter() { if (model_) model_->RemoveCookiesTreeObserver(this); } void CookiesTreeModelAdapter::Init(WebUI* web_ui) { web_ui_ = web_ui; web_ui_->RegisterMessageCallback(GetRequestChildrenCallbackName(this), NewCallback(this, &CookiesTreeModelAdapter::RequestChildren)); } void CookiesTreeModelAdapter::Bind(const std::string& tree_id, CookiesTreeModel* model) { DCHECK(web_ui_); // We should have been initialized. DCHECK(tree_id_.empty() && !model_); // No existing bindings. tree_id_ = tree_id; model_ = model; model_->AddCookiesTreeObserver(this); StringValue tree_id_value(tree_id_); StringValue message_name(GetRequestChildrenCallbackName(this)); web_ui_->CallJavascriptFunction("ui.CookiesTree.setCallback", tree_id_value, message_name); SendChildren(model_->GetRoot()); } void CookiesTreeModelAdapter::TreeNodesAdded(ui::TreeModel* model, ui::TreeModelNode* parent, int start, int count) { // Skip if there is a batch update in progress. if (batch_update_) return; CookieTreeNode* parent_node = model_->AsNode(parent); StringValue tree_id(tree_id_); scoped_ptr<Value> parend_id(GetTreeNodeId(parent_node)); FundamentalValue start_value(start); ListValue children; cookies_tree_model_util::GetChildNodeList(parent_node, start, count, &children); web_ui_->CallJavascriptFunction("ui.CookiesTree.onTreeItemAdded", tree_id, *parend_id.get(), start_value, children); } void CookiesTreeModelAdapter::TreeNodesRemoved(ui::TreeModel* model, ui::TreeModelNode* parent, int start, int count) { // Skip if there is a batch update in progress. if (batch_update_) return; StringValue tree_id(tree_id_); scoped_ptr<Value> parend_id(GetTreeNodeId(model_->AsNode(parent))); FundamentalValue start_value(start); FundamentalValue count_value(count); web_ui_->CallJavascriptFunction("ui.CookiesTree.onTreeItemRemoved", tree_id, *parend_id.get(), start_value, count_value); } void CookiesTreeModelAdapter::TreeModelBeginBatch(CookiesTreeModel* model) { DCHECK(!batch_update_); // There should be no nested batch begin. batch_update_ = true; } void CookiesTreeModelAdapter::TreeModelEndBatch(CookiesTreeModel* model) { DCHECK(batch_update_); batch_update_ = false; SendChildren(model_->GetRoot()); } void CookiesTreeModelAdapter::RequestChildren(const ListValue* args) { std::string node_path; CHECK(args->GetString(0, &node_path)); CookieTreeNode* node = cookies_tree_model_util::GetTreeNodeFromPath( model_->GetRoot(), node_path); if (node) SendChildren(node); } void CookiesTreeModelAdapter::SendChildren(CookieTreeNode* parent) { StringValue tree_id(tree_id_); scoped_ptr<Value> parend_id(GetTreeNodeId(model_->AsNode(parent))); ListValue children; cookies_tree_model_util::GetChildNodeList(parent, 0, parent->child_count(), &children); web_ui_->CallJavascriptFunction("ui.CookiesTree.setChildren", tree_id, *parend_id.get(), children); } Value* CookiesTreeModelAdapter::GetTreeNodeId(CookieTreeNode* node) { if (node == model_->GetRoot()) return Value::CreateNullValue(); return Value::CreateStringValue( cookies_tree_model_util::GetTreeNodeId(node)); }