Bug 1317646 - Netmonitor: move code for formatting request timings and content sizes to format-utils.js, r=jsnajdr
authorsteveck-chung <schung@mozilla.com>
Fri, 13 Jan 2017 16:08:22 +0800
changeset 329608 725d82b3c79074d070d180c7dbab4dde99cd914d
parent 329607 b7f25749589e49cc42b428c640f33f0b94497b89
child 329609 b04953cd621ec523a9a2437bb3d8e589e559eb4c
push id31217
push userphilringnalda@gmail.com
push dateTue, 17 Jan 2017 05:41:29 +0000
treeherdermozilla-central@792c6f70dde5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjsnajdr
bugs1317646
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1317646 - Netmonitor: move code for formatting request timings and content sizes to format-utils.js, r=jsnajdr MozReview-Commit-ID: 3PaUca62s9W
devtools/client/netmonitor/components/request-list-header.js
devtools/client/netmonitor/components/summary-button.js
devtools/client/netmonitor/constants.js
devtools/client/netmonitor/statistics-view.js
devtools/client/netmonitor/utils/format-utils.js
--- a/devtools/client/netmonitor/components/request-list-header.js
+++ b/devtools/client/netmonitor/components/request-list-header.js
@@ -9,24 +9,23 @@
 const { createClass, PropTypes, DOM } = require("devtools/client/shared/vendor/react");
 const { div, button } = DOM;
 const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 const { L10N } = require("../l10n");
 const { getWaterfallScale } = require("../selectors/index");
 const Actions = require("../actions/index");
 const WaterfallBackground = require("../waterfall-background");
+const { getFormattedTime } = require("../utils/format-utils");
 
 // ms
 const REQUESTS_WATERFALL_HEADER_TICKS_MULTIPLE = 5;
 // px
 const REQUESTS_WATERFALL_HEADER_TICKS_SPACING_MIN = 60;
 
-const REQUEST_TIME_DECIMALS = 2;
-
 const HEADERS = [
   { name: "status", label: "status3" },
   { name: "method" },
   { name: "file", boxName: "icon-and-file" },
   { name: "domain", boxName: "security-and-domain" },
   { name: "cause" },
   { name: "type" },
   { name: "transferred" },
@@ -134,37 +133,26 @@ function waterfallDivisionLabels(waterfa
   // Ignore any divisions that would end up being too close to each other.
   while (scaledStep < REQUESTS_WATERFALL_HEADER_TICKS_SPACING_MIN) {
     scaledStep *= 2;
   }
 
   // Insert one label for each division on the current scale.
   for (let x = 0; x < waterfallWidth; x += scaledStep) {
     let millisecondTime = x / scale;
-
-    let normalizedTime = millisecondTime;
     let divisionScale = "millisecond";
 
     // If the division is greater than 1 minute.
-    if (normalizedTime > 60000) {
-      normalizedTime /= 60000;
+    if (millisecondTime > 60000) {
       divisionScale = "minute";
-    } else if (normalizedTime > 1000) {
+    } else if (millisecondTime > 1000) {
       // If the division is greater than 1 second.
-      normalizedTime /= 1000;
       divisionScale = "second";
     }
 
-    // Showing too many decimals is bad UX.
-    if (divisionScale == "millisecond") {
-      normalizedTime |= 0;
-    } else {
-      normalizedTime = L10N.numberWithDecimals(normalizedTime, REQUEST_TIME_DECIMALS);
-    }
-
     let width = (x + scaledStep | 0) - (x | 0);
     // Adjust the first marker for the borders
     if (x == 0) {
       width -= 2;
     }
     // Last marker doesn't need a width specified at all
     if (x + scaledStep >= waterfallWidth) {
       width = undefined;
@@ -172,17 +160,17 @@ function waterfallDivisionLabels(waterfa
 
     labels.push(div(
       {
         key: labels.length,
         className: "requests-menu-timings-division",
         "data-division-scale": divisionScale,
         style: { width }
       },
-      L10N.getFormatStr("networkMenu." + divisionScale, normalizedTime)
+      getFormattedTime(millisecondTime)
     ));
   }
 
   return labels;
 }
 
 function WaterfallLabel(waterfallWidth, scale, label) {
   let className = "button-text requests-menu-waterfall-label-wrapper";
--- a/devtools/client/netmonitor/components/summary-button.js
+++ b/devtools/client/netmonitor/components/summary-button.js
@@ -1,37 +1,37 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const {
-  CONTENT_SIZE_DECIMALS,
-  REQUEST_TIME_DECIMALS,
-} = require("../constants");
 const { DOM, PropTypes } = require("devtools/client/shared/vendor/react");
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 const { PluralForm } = require("devtools/shared/plural-form");
 const { L10N } = require("../l10n");
 const { getDisplayedRequestsSummary } = require("../selectors/index");
 const Actions = require("../actions/index");
+const {
+  getSizeWithDecimals,
+  getTimeWithDecimals,
+} = require("../utils/format-utils");
 
 const { button, span } = DOM;
 
 function SummaryButton({
   summary,
   triggerSummary,
 }) {
   let { count, bytes, millis } = summary;
   const text = (count === 0) ? L10N.getStr("networkMenu.empty") :
     PluralForm.get(count, L10N.getStr("networkMenu.summary"))
     .replace("#1", count)
-    .replace("#2", L10N.numberWithDecimals(bytes / 1024, CONTENT_SIZE_DECIMALS))
-    .replace("#3", L10N.numberWithDecimals(millis / 1000, REQUEST_TIME_DECIMALS));
+    .replace("#2", getSizeWithDecimals(bytes / 1024))
+    .replace("#3", getTimeWithDecimals(millis / 1000));
 
   return button({
     id: "requests-menu-network-summary-button",
     className: "devtools-button",
     title: count ? text : L10N.getStr("netmonitor.toolbar.perf"),
     onClick: triggerSummary,
   },
   span({ className: "summary-info-icon" }),
--- a/devtools/client/netmonitor/constants.js
+++ b/devtools/client/netmonitor/constants.js
@@ -1,18 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const general = {
-  CONTENT_SIZE_DECIMALS: 2,
   FILTER_SEARCH_DELAY: 200,
-  REQUEST_TIME_DECIMALS: 2,
   // 100 KB in bytes
   SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE: 102400,
 };
 
 const actionTypes = {
   ADD_REQUEST: "ADD_REQUEST",
   ADD_TIMING_MARKER: "ADD_TIMING_MARKER",
   BATCH_ACTIONS: "BATCH_ACTIONS",
--- a/devtools/client/netmonitor/statistics-view.js
+++ b/devtools/client/netmonitor/statistics-view.js
@@ -11,19 +11,20 @@ const { PluralForm } = require("devtools
 const { Filters } = require("./filter-predicates");
 const { L10N } = require("./l10n");
 const { EVENTS } = require("./events");
 const { DOM } = require("devtools/client/shared/vendor/react");
 const { button } = DOM;
 const ReactDOM = require("devtools/client/shared/vendor/react-dom");
 const Actions = require("./actions/index");
 const { Chart } = require("devtools/client/shared/widgets/Chart");
-
-const REQUEST_TIME_DECIMALS = 2;
-const CONTENT_SIZE_DECIMALS = 2;
+const {
+  getSizeWithDecimals,
+  getTimeWithDecimals
+} = require("./utils/format-utils");
 
 // px
 const NETWORK_ANALYSIS_PIE_CHART_DIAMETER = 200;
 
 /**
  * Functions handling the performance statistics view.
  */
 function StatisticsView() {
@@ -109,32 +110,32 @@ StatisticsView.prototype = {
   },
 
   /**
    * Common stringifier predicates used for items and totals in both the
    * "primed" and "empty" cache charts.
    */
   _commonChartStrings: {
     size: value => {
-      let string = L10N.numberWithDecimals(value / 1024, CONTENT_SIZE_DECIMALS);
+      let string = getSizeWithDecimals(value / 1024);
       return L10N.getFormatStr("charts.sizeKB", string);
     },
     time: value => {
-      let string = L10N.numberWithDecimals(value / 1000, REQUEST_TIME_DECIMALS);
+      let string = getTimeWithDecimals(value / 1000);
       return L10N.getFormatStr("charts.totalS", string);
     }
   },
   _commonChartTotals: {
     size: total => {
-      let string = L10N.numberWithDecimals(total / 1024, CONTENT_SIZE_DECIMALS);
+      let string = getSizeWithDecimals(total / 1024);
       return L10N.getFormatStr("charts.totalSize", string);
     },
     time: total => {
       let seconds = total / 1000;
-      let string = L10N.numberWithDecimals(seconds, REQUEST_TIME_DECIMALS);
+      let string = getTimeWithDecimals(seconds);
       return PluralForm.get(seconds,
         L10N.getStr("charts.totalSeconds")).replace("#1", string);
     },
     cached: total => {
       return L10N.getFormatStr("charts.totalCached", total);
     },
     count: total => {
       return L10N.getFormatStr("charts.totalCount", total);
--- a/devtools/client/netmonitor/utils/format-utils.js
+++ b/devtools/client/netmonitor/utils/format-utils.js
@@ -9,35 +9,64 @@ const { L10N } = require("../l10n");
 // Constants for formatting bytes.
 const BYTES_IN_KB = 1024;
 const BYTES_IN_MB = Math.pow(BYTES_IN_KB, 2);
 const BYTES_IN_GB = Math.pow(BYTES_IN_KB, 3);
 const MAX_BYTES_SIZE = 1000;
 const MAX_KB_SIZE = 1000 * BYTES_IN_KB;
 const MAX_MB_SIZE = 1000 * BYTES_IN_MB;
 
+// Constants for formatting time.
+const MAX_MILLISECOND = 1000;
+const MAX_SECOND = 60 * MAX_MILLISECOND;
+
+const CONTENT_SIZE_DECIMALS = 2;
+const REQUEST_TIME_DECIMALS = 2;
+
+function getSizeWithDecimals(size, decimals = REQUEST_TIME_DECIMALS) {
+  return L10N.numberWithDecimals(size, CONTENT_SIZE_DECIMALS);
+}
+
+function getTimeWithDecimals(time) {
+  return L10N.numberWithDecimals(time, REQUEST_TIME_DECIMALS);
+}
+
 /**
  * Get a human-readable string from a number of bytes, with the B, KB, MB, or
  * GB value. Note that the transition between abbreviations is by 1000 rather
  * than 1024 in order to keep the displayed digits smaller as "1016 KB" is
  * more awkward than 0.99 MB"
  */
-function getFormattedSize(bytes, decimals = 2) {
+function getFormattedSize(bytes, decimals = REQUEST_TIME_DECIMALS) {
   if (bytes < MAX_BYTES_SIZE) {
     return L10N.getFormatStr("networkMenu.sizeB", bytes);
   } else if (bytes < MAX_KB_SIZE) {
     let kb = bytes / BYTES_IN_KB;
-    let size = L10N.numberWithDecimals(kb, decimals);
-    return L10N.getFormatStr("networkMenu.sizeKB", size);
+    return L10N.getFormatStr("networkMenu.sizeKB", getSizeWithDecimals(kb, decimals));
   } else if (bytes < MAX_MB_SIZE) {
     let mb = bytes / BYTES_IN_MB;
-    let size = L10N.numberWithDecimals(mb, decimals);
-    return L10N.getFormatStr("networkMenu.sizeMB", size);
+    return L10N.getFormatStr("networkMenu.sizeMB", getSizeWithDecimals(mb, decimals));
   }
   let gb = bytes / BYTES_IN_GB;
-  let size = L10N.numberWithDecimals(gb, decimals);
-  return L10N.getFormatStr("networkMenu.sizeGB", size);
+  return L10N.getFormatStr("networkMenu.sizeGB", getSizeWithDecimals(gb, decimals));
+}
+
+/**
+ * Get a human-readable string from a number of time, with the ms, s, or min
+ * value.
+ */
+function getFormattedTime(ms) {
+  if (ms < MAX_MILLISECOND) {
+    return L10N.getFormatStr("networkMenu.millisecond", ms | 0);
+  } else if (ms < MAX_SECOND) {
+    let sec = ms / MAX_MILLISECOND;
+    return L10N.getFormatStr("networkMenu.second", getTimeWithDecimals(sec));
+  }
+  let min = ms / MAX_SECOND;
+  return L10N.getFormatStr("networkMenu.minute", getTimeWithDecimals(min));
 }
 
 module.exports = {
   getFormattedSize,
+  getFormattedTime,
+  getSizeWithDecimals,
+  getTimeWithDecimals,
 };
-