From 2801fa0a90557f585e641da52d34efb33f2044de Mon Sep 17 00:00:00 2001 From: Avi Halachmi Date: Fri, 29 Nov 2013 19:31:14 +0200 Subject: [PATCH] Bug 840097: Add clipboard copy for about:telemetry histograms. r=vladan --- toolkit/content/aboutTelemetry.css | 16 +++++++ toolkit/content/aboutTelemetry.js | 46 +++++++++++++++++-- .../chrome/global/aboutTelemetry.properties | 2 + 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/toolkit/content/aboutTelemetry.css b/toolkit/content/aboutTelemetry.css index 99081a831ba..70cc150573e 100644 --- a/toolkit/content/aboutTelemetry.css +++ b/toolkit/content/aboutTelemetry.css @@ -78,6 +78,7 @@ h2 { border: 1px solid gray; white-space: nowrap; padding: 10px; + position: relative; /* required for position:absolute of the contained .copy-node */ } body[dir="rtl"] .histogram { @@ -128,3 +129,18 @@ caption { body[dir="rtl"] caption { text-align: right; } + +.copy-node { + visibility: hidden; + position: absolute; + bottom: 1px; + right: 1px; +} + +body[dir="rtl"] .copy-node { + left: 1px; +} + +.histogram:hover .copy-node { + visibility: visible; +} diff --git a/toolkit/content/aboutTelemetry.js b/toolkit/content/aboutTelemetry.js index 747e73bb194..9404df25984 100644 --- a/toolkit/content/aboutTelemetry.js +++ b/toolkit/content/aboutTelemetry.js @@ -19,8 +19,9 @@ const brandBundle = Services.strings.createBundle( const TelemetryPing = Cc["@mozilla.org/base/telemetry-ping;1"]. getService(Ci.nsITelemetryPing); -// Maximum height of a histogram bar (in em) +// Maximum height of a histogram bar (in em for html, in chars for text) const MAX_BAR_HEIGHT = 18; +const MAX_BAR_CHARS = 25; const PREF_TELEMETRY_SERVER_OWNER = "toolkit.telemetry.server_owner"; #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabledPreRelease"; @@ -31,6 +32,12 @@ const PREF_DEBUG_SLOW_SQL = "toolkit.telemetry.debugSlowSql"; const PREF_SYMBOL_SERVER_URI = "profiler.symbolicationUrl"; const DEFAULT_SYMBOL_SERVER_URI = "http://symbolapi.mozilla.org"; +#ifdef XP_WIN +const EOL = "\r\n"; +#else +const EOL = "\n"; +#endif + // Cached value of document's RTL mode let documentRTLMode = ""; @@ -407,6 +414,8 @@ let Histogram = { hgramSumCaption: bundle.GetStringFromName("histogramSum"), + hgramCopyCaption: bundle.GetStringFromName("histogramCopy"), + /** * Renders a single Telemetry histogram * @@ -437,7 +446,18 @@ let Histogram = { if (isRTL()) hgram.values.reverse(); - this.renderValues(outerDiv, hgram.values, hgram.max); + let textData = this.renderValues(outerDiv, hgram.values, hgram.max, hgram.sample_count); + + // The 'Copy' button contains the textual data, copied to clipboard on click + let copyButton = document.createElement("button"); + copyButton.className = "copy-node"; + copyButton.appendChild(document.createTextNode(this.hgramCopyCaption)); + copyButton.histogramText = aName + EOL + stats + EOL + EOL + textData; + copyButton.addEventListener("click", function(){ + Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper) + .copyString(this.histogramText); + }); + outerDiv.appendChild(copyButton); aParent.appendChild(outerDiv); }, @@ -491,14 +511,28 @@ let Histogram = { }, /** - * Create histogram bars + * Create histogram HTML bars, also returns a textual representation + * Both aMaxValue and aSumValues must be positive. + * Values are assumed to use 0 as baseline. * * @param aDiv Outer parent div * @param aValues Histogram values - * @param aMaxValue Largest histogram value in set + * @param aMaxValue Value of the longest bar (length, not label) + * @param aSumValues Sum of all bar values */ - renderValues: function Histogram_renderValues(aDiv, aValues, aMaxValue) { + renderValues: function Histogram_renderValues(aDiv, aValues, aMaxValue, aSumValues) { + let text = ""; + // If the last label is not the longest string, alignment will break a little + let labelPadTo = String(aValues[aValues.length -1][0]).length; + for (let [label, value] of aValues) { + // Create a text representation: | + text += EOL + + " ".repeat(Math.max(0, labelPadTo - String(label).length)) + label // Right-aligned label + + " |" + "#".repeat(Math.round(MAX_BAR_CHARS * value / aMaxValue)) + value // Bars and value + + " " + Math.round(100 * value / aSumValues) + "%"; // Percentage + + // Construct the HTML labels + bars let belowEm = Math.round(MAX_BAR_HEIGHT * (value / aMaxValue) * 10) / 10; let aboveEm = MAX_BAR_HEIGHT - belowEm; @@ -520,6 +554,8 @@ let Histogram = { aDiv.appendChild(barDiv); } + + return text.substr(EOL.length); // Trim the EOL before the first line } }; diff --git a/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties b/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties index f7620c97f09..3c48b1a70ec 100644 --- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties +++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties @@ -38,6 +38,8 @@ histogramAverage = average histogramSum = sum +histogramCopy = Copy + disableTelemetry = Disable Telemetry enableTelemetry = Enable Telemetry