Home | History | Annotate | Download | only in webui
      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/ui/webui/cookies_tree_model_adapter.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/string_number_conversions.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/ui/webui/cookies_tree_model_util.h"
     11 #include "content/browser/webui/web_ui.h"
     12 #include "grit/generated_resources.h"
     13 #include "ui/base/l10n/l10n_util.h"
     14 
     15 namespace {
     16 
     17 // Returns a unique callback name for |adapter|'s requestChildren.
     18 std::string GetRequestChildrenCallbackName(CookiesTreeModelAdapter* adapter) {
     19   static const char kPrefixLoadCookie[] = "requestChildren";
     20   return std::string(kPrefixLoadCookie) +
     21          base::HexEncode(&adapter, sizeof(adapter));
     22 }
     23 
     24 }  // namespace
     25 
     26 CookiesTreeModelAdapter::CookiesTreeModelAdapter()
     27     : web_ui_(NULL),
     28       model_(NULL),
     29       batch_update_(false) {
     30 }
     31 
     32 CookiesTreeModelAdapter::~CookiesTreeModelAdapter() {
     33   if (model_)
     34     model_->RemoveCookiesTreeObserver(this);
     35 }
     36 
     37 void CookiesTreeModelAdapter::Init(WebUI* web_ui) {
     38   web_ui_ = web_ui;
     39 
     40   web_ui_->RegisterMessageCallback(GetRequestChildrenCallbackName(this),
     41       NewCallback(this, &CookiesTreeModelAdapter::RequestChildren));
     42 }
     43 
     44 void CookiesTreeModelAdapter::Bind(const std::string& tree_id,
     45                                    CookiesTreeModel* model) {
     46   DCHECK(web_ui_);  // We should have been initialized.
     47   DCHECK(tree_id_.empty() && !model_);  // No existing bindings.
     48 
     49   tree_id_ = tree_id;
     50   model_ = model;
     51   model_->AddCookiesTreeObserver(this);
     52 
     53   StringValue tree_id_value(tree_id_);
     54   StringValue message_name(GetRequestChildrenCallbackName(this));
     55   web_ui_->CallJavascriptFunction("ui.CookiesTree.setCallback",
     56       tree_id_value, message_name);
     57 
     58   SendChildren(model_->GetRoot());
     59 }
     60 
     61 void CookiesTreeModelAdapter::TreeNodesAdded(ui::TreeModel* model,
     62                                              ui::TreeModelNode* parent,
     63                                              int start,
     64                                              int count) {
     65   // Skip if there is a batch update in progress.
     66   if (batch_update_)
     67     return;
     68 
     69   CookieTreeNode* parent_node = model_->AsNode(parent);
     70 
     71   StringValue tree_id(tree_id_);
     72   scoped_ptr<Value> parend_id(GetTreeNodeId(parent_node));
     73   FundamentalValue start_value(start);
     74   ListValue children;
     75   cookies_tree_model_util::GetChildNodeList(parent_node, start, count,
     76                                             &children);
     77   web_ui_->CallJavascriptFunction("ui.CookiesTree.onTreeItemAdded",
     78       tree_id, *parend_id.get(), start_value, children);
     79 }
     80 
     81 void CookiesTreeModelAdapter::TreeNodesRemoved(ui::TreeModel* model,
     82                                                ui::TreeModelNode* parent,
     83                                                int start,
     84                                                int count) {
     85   // Skip if there is a batch update in progress.
     86   if (batch_update_)
     87     return;
     88 
     89   StringValue tree_id(tree_id_);
     90   scoped_ptr<Value> parend_id(GetTreeNodeId(model_->AsNode(parent)));
     91   FundamentalValue start_value(start);
     92   FundamentalValue count_value(count);
     93   web_ui_->CallJavascriptFunction("ui.CookiesTree.onTreeItemRemoved",
     94       tree_id, *parend_id.get(), start_value, count_value);
     95 }
     96 
     97 void CookiesTreeModelAdapter::TreeModelBeginBatch(CookiesTreeModel* model) {
     98   DCHECK(!batch_update_);  // There should be no nested batch begin.
     99   batch_update_ = true;
    100 }
    101 
    102 void CookiesTreeModelAdapter::TreeModelEndBatch(CookiesTreeModel* model) {
    103   DCHECK(batch_update_);
    104   batch_update_ = false;
    105 
    106   SendChildren(model_->GetRoot());
    107 }
    108 
    109 void CookiesTreeModelAdapter::RequestChildren(const ListValue* args) {
    110   std::string node_path;
    111   CHECK(args->GetString(0, &node_path));
    112 
    113   CookieTreeNode* node = cookies_tree_model_util::GetTreeNodeFromPath(
    114       model_->GetRoot(), node_path);
    115   if (node)
    116     SendChildren(node);
    117 }
    118 
    119 void CookiesTreeModelAdapter::SendChildren(CookieTreeNode* parent) {
    120   StringValue tree_id(tree_id_);
    121   scoped_ptr<Value> parend_id(GetTreeNodeId(model_->AsNode(parent)));
    122   ListValue children;
    123   cookies_tree_model_util::GetChildNodeList(parent, 0, parent->child_count(),
    124       &children);
    125   web_ui_->CallJavascriptFunction("ui.CookiesTree.setChildren",
    126       tree_id, *parend_id.get(), children);
    127 }
    128 
    129 Value* CookiesTreeModelAdapter::GetTreeNodeId(CookieTreeNode* node) {
    130   if (node == model_->GetRoot())
    131     return Value::CreateNullValue();
    132 
    133   return Value::CreateStringValue(
    134       cookies_tree_model_util::GetTreeNodeId(node));
    135 }
    136