Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Unified Diff: net/tools/ct_mapper/main.js

Issue 1238413004: Framework for iterating over certificates in CT database from Chromium code. (not for review) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make samples page work Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/tools/ct_mapper/index.html ('k') | net/tools/ct_mapper/mapper.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/tools/ct_mapper/main.js
diff --git a/net/tools/ct_mapper/main.js b/net/tools/ct_mapper/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..1c7316380ff0e2ff75da3c77fa48f9fc888981ec
--- /dev/null
+++ b/net/tools/ct_mapper/main.js
@@ -0,0 +1,250 @@
+"use strict";
+
+var dom = (function() {
+ return {
+ add: function(parent, tagName, optText, optClassName) {
+ var node = parent.ownerDocument.createElement(tagName);
+ parent.appendChild(node);
+
+ if (optText != undefined)
+ dom.addText(node, optText);
+ if (optClassName != undefined)
+ node.className = optClassName;
+
+ return node;
+ },
+
+ addLink: function(parent, text, href) {
+ var node = dom.add(parent, 'a');
+ dom.addText(node, text);
+ node.href = href;
+ return node;
+ },
+
+ addActionLink: function(parent, text, onclick) {
+ var node = dom.addLink(parent, text, 'javascript:void(0)');
+ node.onclick = onclick;
+ return node;
+ },
+
+ addText: function(parent, text) {
+ var textNode = parent.ownerDocument.createTextNode(text);
+ parent.appendChild(textNode);
+ return textNode;
+ },
+
+ clear: function(node) {
+ node.innerHTML = '';
+ },
+ };
+})();
+
+function changeSort(parent, metricsItem, newSort) {
+ setSort(metricsItem, newSort);
+ drawMetricsItem(parent, metricsItem);
+}
+
+function setSort(metricsItem, newSort) {
+ function getSortProperty(bucket) {
+ let prop = metricsItem.sort || SORT_BY_COUNT;
+
+ switch (Math.abs(prop)) {
+ case SORT_BY_COUNT:
+ return bucket.total;
+ case SORT_BY_NAME:
+ return bucket.name;
+ }
+ return undefined;
+ }
+
+ if (metricsItem.sort && Math.abs(metricsItem.sort) == Math.abs(newSort)) {
+ // Reverse sort order.
+ metricsItem.sort *= -1;
+ } else {
+ metricsItem.sort = newSort;
+ }
+
+ metricsItem.buckets.sort(function(a, b) {
+ var multiplier = metricsItem.sort < 0 ? -1 : 1;
+
+ var propA = getSortProperty(a);
+ var propB = getSortProperty(b);
+
+ var result = 0;
+
+ if (propA < propB) {
+ result = -1;
+ } else if (propA > propB) {
+ result = 1;
+ }
+
+ return result * multiplier;
+ });
+}
+
+function drawOverviewPage() {
+ var parent = document.body;
+ dom.clear(parent);
+
+ for (let metricsItem of g_data.metrics) {
+ let div = dom.add(parent, 'div', undefined, 'metricsItem');
+ drawMetricsItem(div, metricsItem);
+ }
+}
+
+function prettyPrintBigNumber(x) {
+ let origStr = x + '';
+ let result = '';
+
+ for (let i = 0; i < origStr.length; ++i) {
+ let ch = origStr.charAt(origStr.length - 1 - i);
+
+ if (i > 0 && i % 3 == 0)
+ result = ',' + result;
+
+ result = ch + result
+ }
+
+ return result;
+}
+
+function drawMetricsItem(parent, metricsItem) {
+ dom.clear(parent);
+
+ let includeSamplesColumn = false;
+ for (let bucket of metricsItem.buckets) {
+ if (bucket.samples.length > 0)
+ includeSamplesColumn = true;
+ }
+
+ dom.add(parent, 'h3', metricsItem.name);
+ dom.add(parent, 'p', 'Total: ' + prettyPrintBigNumber(metricsItem.total));
+
+ var table = dom.add(parent, 'table');
+ var thead = dom.add(table, 'thead');
+ var theadTr = dom.add(thead, 'tr');
+
+ var countTh = dom.add(theadTr, 'th');
+ countTh.colSpan = 2;
+ let countSortIndicator = '';
+ let nameSortIndicator = '';
+
+ let kUp = ' \u25B2';
+ let kDown = ' \u25BC';
+
+ if (metricsItem.sort == SORT_BY_COUNT) {
+ countSortIndicator = kUp;
+ } else if (metricsItem.sort == -SORT_BY_COUNT) {
+ countSortIndicator = kDown;
+ } else if (metricsItem.sort == SORT_BY_NAME) {
+ nameSortIndicator = kUp;
+ } else if (metricsItem.sort == -SORT_BY_NAME) {
+ nameSortIndicator = kDown;
+ }
+
+ var countSortCol = dom.addActionLink(countTh, 'Count' + countSortIndicator, changeSort.bind(null, parent, metricsItem, SORT_BY_COUNT));
+
+ var samplesTh;
+ if (includeSamplesColumn)
+ samplesTh = dom.add(theadTr, 'th');
+
+ var descriptionTh = dom.add(theadTr, 'th');
+ var descriptionSortCol = dom.addActionLink(descriptionTh, 'Name' + nameSortIndicator, changeSort.bind(null, parent, metricsItem, SORT_BY_NAME));
+
+ var tbody = dom.add(table, 'tbody');
+
+ for (let bucket of metricsItem.buckets) {
+ var tr = dom.add(tbody, 'tr');
+ dom.add(tr, 'td', prettyPrintBigNumber(bucket.total), 'colTotal');
+ dom.add(tr, 'td', (100 * bucket.total / metricsItem.total).toFixed(3) + ' %', 'colPercent');
+
+ if (includeSamplesColumn) {
+ var samplesTd = dom.add(tr, 'td', undefined, 'colSamples');
+ if (bucket.samples.length > 0)
+ dom.addLink(samplesTd, bucket.samples.length + ' samples', '#samples/' + encodeURIComponent(bucket.id));
+ }
+
+ dom.add(tr, 'td', bucket.name, 'colName');
+ }
+}
+
+function getQueryParams() {
+ var params = {};
+
+ var parts = window.location.hash.substr(1).split('&');
+ for(var i = 0; i < parts.length; i++) {
+ var keyAndValue = parts[i].split('=');
+ params[decodeURIComponent(keyAndValue[0])] = decodeURIComponent(keyAndValue[1]);
+ }
+
+ return params;
+}
+
+function findSamplesForBucket(bucketId) {
+ for (let metricsItem of g_data.metrics) {
+ for (let bucket of metricsItem.buckets) {
+ if (bucket.id == bucketId)
+ return bucket.samples;
+ }
+ }
+ return null;
+}
+
+function drawSamplesPage(bucketId) {
+ var parent = document.body;
+ dom.clear(parent);
+
+ parent = dom.add(parent, 'div', undefined, 'samplesDiv');
+
+ let samples = findSamplesForBucket(bucketId);
+ if (!samples) {
+ dom.add(parent, 'h3', 'No bucket for id=' + bucketId);
+ return;
+ }
+
+ dom.add(parent, 'h3', 'Samples');
+
+ var ul = dom.add(parent, 'ul');
+
+ for (let sampleUrl of samples) {
+ var li = dom.add(ul, 'li');
+ dom.addLink(li, sampleUrl, sampleUrl);
+ }
+}
+
+function onHashChange() {
+ let hash = window.location.hash;
+
+ // Draw the samples page.
+ let regex = /^#samples\/([0-9]+)$/;
+ let match = regex.exec(hash);
+
+ if (match) {
+ drawSamplesPage(parseInt(match[1]));
+ return;
+ }
+
+ // Otherwise draw the overview page.
+ drawOverviewPage();
+}
+
+function onLoad() {
+ // Do an initial sorting of the data, and also assign an ID to each bucket.
+ let bucketId = 0;
+ for (let metricsItem of g_data.metrics) {
+ for (let bucket of metricsItem.buckets) {
+ bucket.id = bucketId++;
+ }
+ setSort(metricsItem, -SORT_BY_COUNT);
+ }
+
+ // Draw the current page based on the URL.
+ onHashChange();
+}
+
+var SORT_BY_COUNT = 1;
+var SORT_BY_NAME = 2;
+
+document.addEventListener("DOMContentLoaded", onLoad);
+window.addEventListener("hashchange", onHashChange);
+
« no previous file with comments | « net/tools/ct_mapper/index.html ('k') | net/tools/ct_mapper/mapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698