summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/discards/discards.js
blob: 1e8740a01f1712e3764f1d42b2424be61f6e36d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('discards', function() {
  'use strict';

  // The following variables are initialized by 'initialize'.
  // Points to the DiscardsDetailsProviderRemote.
  let discardsDetailsProvider;

  /**
   * @return {!mojom.DiscardsDetailsProviderRemote} Provides discards details.
   */
  function getOrCreateDetailsProvider() {
    if (!discardsDetailsProvider) {
      discardsDetailsProvider = mojom.DiscardsDetailsProvider.getRemote();
    }
    return discardsDetailsProvider;
  }

  /**
   * Pluralizes a string according to the given count. Assumes that appending an
   * 's' is sufficient to make a string plural.
   * @param {string} s The string to be made plural if necessary.
   * @param {number} n The count of the number of ojects.
   * @return {string} The plural version of |s| if n != 1, otherwise |s|.
   */
  function maybeMakePlural(s, n) {
    return n == 1 ? s : s + 's';
  }

  /**
   * Converts a |seconds| interval to a user friendly string.
   * @param {number} seconds The interval to render.
   * @return {string} An English string representing the interval.
   */
  function secondsToString(seconds) {
    // These constants aren't perfect, but close enough.
    const SECONDS_PER_MINUTE = 60;
    const MINUTES_PER_HOUR = 60;
    const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
    const HOURS_PER_DAY = 24;
    const SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
    const DAYS_PER_WEEK = 7;
    const SECONDS_PER_WEEK = SECONDS_PER_DAY * DAYS_PER_WEEK;
    const SECONDS_PER_MONTH = SECONDS_PER_DAY * 30.5;
    const SECONDS_PER_YEAR = SECONDS_PER_DAY * 365;

    // Seconds.
    if (seconds < SECONDS_PER_MINUTE) {
      return seconds.toString() + maybeMakePlural(' second', seconds);
    }

    // Minutes.
    let minutes = Math.floor(seconds / SECONDS_PER_MINUTE);
    if (minutes < MINUTES_PER_HOUR) {
      return minutes.toString() + maybeMakePlural(' minute', minutes);
    }

    // Hours and minutes.
    const hours = Math.floor(seconds / SECONDS_PER_HOUR);
    minutes = minutes % MINUTES_PER_HOUR;
    if (hours < HOURS_PER_DAY) {
      let s = hours.toString() + maybeMakePlural(' hour', hours);
      if (minutes > 0) {
        s += ' and ' + minutes.toString() + maybeMakePlural(' minute', minutes);
      }
      return s;
    }

    // Days.
    const days = Math.floor(seconds / SECONDS_PER_DAY);
    if (days < DAYS_PER_WEEK) {
      return days.toString() + maybeMakePlural(' day', days);
    }

    // Weeks. There's an awkward gap to bridge where 4 weeks can have
    // elapsed but not quite 1 month. Be sure to use weeks to report that.
    const weeks = Math.floor(seconds / SECONDS_PER_WEEK);
    const months = Math.floor(seconds / SECONDS_PER_MONTH);
    if (months < 1) {
      return 'over ' + weeks.toString() + maybeMakePlural(' week', weeks);
    }

    // Months.
    const years = Math.floor(seconds / SECONDS_PER_YEAR);
    if (years < 1) {
      return 'over ' + months.toString() + maybeMakePlural(' month', months);
    }

    // Years.
    return 'over ' + years.toString() + maybeMakePlural(' year', years);
  }

  /**
   * Converts a |secondsAgo| duration to a user friendly string.
   * @param {number} secondsAgo The duration to render.
   * @return {string} An English string representing the duration.
   */
  function durationToString(secondsAgo) {
    const ret = secondsToString(secondsAgo);

    if (ret.endsWith(' seconds') || ret.endsWith(' second')) {
      return 'just now';
    }

    return ret + ' ago';
  }

  /**
   * Returns a string representation of a boolean value for display in a table.
   * @param {boolean} bool A boolean value.
   * @return {string} A string representing the bool.
   */
  function boolToString(bool) {
    return bool ? '✔' : '✘️';
  }

  // These functions are exposed on the 'discards' object created by
  // cr.define. This allows unittesting of these functions.
  return {
    boolToString: boolToString,
    durationToString: durationToString,
    getOrCreateDetailsProvider: getOrCreateDetailsProvider,
    maybeMakePlural: maybeMakePlural,
    secondsToString: secondsToString
  };
});