De-dup PrefixSet code in SafeBrowsingDatabaseManager.
[chromium-blink-merge.git] / tools / deep_memory_profiler / visualizer / static / menu-view.js
bloba2aeba2dd55ef212cfd4275c7e815fc4dc8a6ad9
1 // Copyright 2013 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.
5 /**
6  * This is a view class showing tree-menu.
7  * @param {Object} profiler Must have addListener method.
8  * @construct
9  */
10 var MenuView = function(profiler) {
11   this.profiler_ = profiler;
12   this.placeholder_ = '#category-menu';
14   // Update graph view and menu view when profiler model changed.
15   profiler.addListener('changed', this.redraw_.bind(this));
16   profiler.addListener('changed:selected', this.selectNode_.bind(this));
19 /**
20  * Highlight the node being selected.
21  * @param {string|null} id Model id.
22  * @param {Object} pos Clicked position. Not used
23  * @private
24  */
25 MenuView.prototype.selectNode_ = function(id) {
26   var $tree = this.$tree_;
28   if (id == null) {
29     $tree.tree('selectNode', null);
30     return;
31   }
33   var node = $tree.tree('getNodeById', id);
34   $tree.tree('selectNode', node);
37 /**
38  * Update menu view when model updated.
39  * @param {Array.<Object>} models
40  * @private
41  */
42 MenuView.prototype.redraw_ = function(models) {
43   function convert(origin, target) {
44     target.label = origin.name;
45     target.id = origin.id;
47     if ('children' in origin) {
48       target.children = [];
49       origin.children.forEach(function(originChild) {
50         var targetChild = {};
51         target.children.push(targetChild);
52         convert(originChild, targetChild);
53       });
54     }
55   }
57   function merge(origin, target) {
58     if (!('children' in origin))
59       return;
60     if (!('children' in target)) {
61       target.children = origin.children;
62       return;
63     }
65     origin.children.forEach(function(child) {
66       // Find child with the same label in target tree.
67       var index = target.children.reduce(function(previous, current, index) {
68         if (child.label === current.label)
69         return index;
70         return previous;
71       }, -1);
72       if (index === -1)
73         target.children.push(child);
74       else
75         merge(child, target.children[index]);
76     });
77   }
79   var self = this;
81   // Merge trees in all snapshots.
82   var union = null;
83   models.forEach(function(model) {
84     var data = {};
85     convert(model, data);
86     if (!union)
87       union = data;
88     else
89       merge(data, union);
90   });
92   // Draw breakdown menu.
93   var data = [union];
94   if (!this.$tree_) {
95     this.$tree_ = $(this.placeholder_).tree({
96       data: data,
97       autoOpen: true,
98       onCreateLi: function(node, $li) {
99         // TODO(junjianx): Add checkbox to decide the breakdown visibility.
100       }
101     });
103     // Delegate events
104     this.$tree_.bind('tree.click', function(event) {
105       event.preventDefault();
106       self.profiler_.setSelected(event.node.id);
107     });
108     this.$tree_.bind('tree.close', function(event) {
109       event.preventDefault();
110       self.profiler_.unsetSub(event.node.id);
111       self.profiler_.setSelected(event.node.id);
112     });
113   } else {
114     this.$tree_.tree('loadData', data);
115   }