BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / resources / certificate_viewer.js
blobe95a1d9d993eea7f5c55259b57486f2427ac31c7
1 // Copyright (c) 2012 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 cr.define('cert_viewer', function() {
6   'use strict';
8   /**
9    * Initialize the certificate viewer dialog by wiring up the close button,
10    * substituting in translated strings and requesting certificate details.
11    */
12   function initialize() {
13     cr.ui.decorate('tabbox', cr.ui.TabBox);
15     var args = JSON.parse(chrome.getVariableValue('dialogArguments'));
16     getCertificateInfo(args);
18     /**
19      * Initialize the second tab's contents.
20      * This is a 'oneShot' function, meaning it will only be invoked once,
21      * no matter how many times it is called.  This is done for unit-testing
22      * purposes in case a test needs to initialize the tab before the timer
23      * fires.
24      */
25     var initializeDetailTab = oneShot(function() {
26       initializeTree($('hierarchy'), showCertificateFields);
27       initializeTree($('cert-fields'), showCertificateFieldValue);
28       createCertificateHierarchy(args.hierarchy);
29     });
31     // The second tab's contents aren't visible on startup, so we can
32     // shorten startup by not populating those controls until after we
33     // have had a chance to draw the visible controls the first time.
34     // The value of 200ms is quick enough that the user couldn't open the
35     // tab in that time but long enough to allow the first tab to draw on
36     // even the slowest machine.
37     setTimeout(initializeDetailTab, 200);
39     $('tabbox').addEventListener('selectedChange', function f(e) {
40       $('tabbox').removeEventListener('selectedChange', f);
41       initializeDetailTab();
42     }, true);
44     stripGtkAccessorKeys();
46     $('export').onclick = exportCertificate;
47   }
49   /**
50    * Decorate a function so that it can only be invoked once.
51    */
52   function oneShot(fn) {
53     var fired = false;
54     return function() {
55        if (fired) return;
56        fired = true;
57        fn();
58     };
59   }
61   /**
62    * Initialize a cr.ui.Tree object from a given element using the specified
63    * change handler.
64    * @param {HTMLElement} tree The HTMLElement to style as a tree.
65    * @param {function()} handler Function to call when a node is selected.
66    */
67   function initializeTree(tree, handler) {
68     cr.ui.decorate(tree, cr.ui.Tree);
69     tree.detail = {payload: {}, children: {}};
70     tree.addEventListener('change', handler);
71   }
73   /**
74    * The tab name strings in the languages file have accessor keys indicated
75    * by a preceding & sign. Strip these out for now.
76    * TODO(flackr) These accessor keys could be implemented with Javascript or
77    *     translated strings could be added / modified to remove the & sign.
78    */
79   function stripGtkAccessorKeys() {
80     // Copy all the tab labels into an array.
81     var nodes = Array.prototype.slice.call($('tabs').childNodes, 0);
82     nodes.push($('export'));
83     for (var i = 0; i < nodes.length; i++)
84       nodes[i].textContent = nodes[i].textContent.replace('&', '');
85   }
87   /**
88    * Expand all nodes of the given tree object.
89    * @param {cr.ui.Tree} tree The tree object to expand all nodes on.
90    */
91   function revealTree(tree) {
92     tree.expanded = true;
93     for (var key in tree.detail.children) {
94       revealTree(tree.detail.children[key]);
95     }
96   }
98   /**
99    * This function is called from certificate_viewer_ui.cc with the certificate
100    * information. Display all returned information to the user.
101    * @param {Object} certInfo Certificate information in named fields.
102    */
103   function getCertificateInfo(certInfo) {
104     for (var key in certInfo.general) {
105       $(key).textContent = certInfo.general[key];
106     }
107   }
109   /**
110    * This function populates the certificate hierarchy.
111    * @param {Object} hierarchy A dictionary containing the hierarchy.
112    */
113   function createCertificateHierarchy(hierarchy) {
114     var treeItem = $('hierarchy');
115     var root = constructTree(hierarchy[0]);
116     treeItem.detail.children['root'] = root;
117     treeItem.add(root);
119     // Select the last item in the hierarchy (really we have a list here - each
120     // node has at most one child).  This will reveal the parent nodes and
121     // populate the fields view.
122     var last = root;
123     while (last.detail.children && last.detail.children[0])
124       last = last.detail.children[0];
125     last.selected = true;
126   }
128   /**
129    * Constructs a cr.ui.TreeItem corresponding to the passed in tree
130    * @param {Object} tree Dictionary describing the tree structure.
131    * @return {cr.ui.TreeItem} Tree node corresponding to the input dictionary.
132    */
133   function constructTree(tree)
134   {
135     var treeItem = new cr.ui.TreeItem({
136         label: tree.label,
137         detail: {payload: tree.payload ? tree.payload : {},
138             children: {}
139         }});
140     if (tree.children) {
141       for (var i = 0; i < tree.children.length; i++) {
142         treeItem.add(treeItem.detail.children[i] =
143             constructTree(tree.children[i]));
144       }
145     }
146     return treeItem;
147   }
149   /**
150    * Clear any previous certificate fields in the tree.
151    */
152   function clearCertificateFields() {
153     var treeItem = $('cert-fields');
154     for (var key in treeItem.detail.children) {
155       treeItem.remove(treeItem.detail.children[key]);
156       delete treeItem.detail.children[key];
157     }
158   }
160   /**
161    * Request certificate fields for the selected certificate in the hierarchy.
162    */
163   function showCertificateFields() {
164     clearCertificateFields();
165     var item = $('hierarchy').selectedItem;
166     if (item && item.detail.payload.index !== undefined)
167       chrome.send('requestCertificateFields', [item.detail.payload.index]);
168   }
170   /**
171    * Show the returned certificate fields for the selected certificate.
172    * @param {Object} certFields A dictionary containing the fields tree
173    *     structure.
174    */
175   function getCertificateFields(certFields) {
176     clearCertificateFields();
177     var treeItem = $('cert-fields');
178     treeItem.add(treeItem.detail.children['root'] =
179         constructTree(certFields[0]));
180     revealTree(treeItem);
181     // Ensure the list is scrolled to the top by selecting the first item.
182     treeItem.children[0].selected = true;
183   }
185   /**
186    * Show certificate field value for a selected certificate field.
187    */
188   function showCertificateFieldValue() {
189     var item = $('cert-fields').selectedItem;
190     if (item && item.detail.payload.val)
191       $('cert-field-value').textContent = item.detail.payload.val;
192     else
193       $('cert-field-value').textContent = '';
194   }
196   /**
197    * Export the selected certificate.
198    */
199   function exportCertificate() {
200     var item = $('hierarchy').selectedItem;
201     if (item && item.detail.payload.index !== undefined)
202       chrome.send('exportCertificate', [item.detail.payload.index]);
203   }
205   return {
206     initialize: initialize,
207     getCertificateFields: getCertificateFields,
208   };
211 document.addEventListener('DOMContentLoaded', cert_viewer.initialize);