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.
4
5/**
6 * @fileoverview This file defines a singleton which provides access to all data
7 * that is available as soon as the page's resources are loaded (before DOM
8 * content has finished loading). This data includes both localized strings and
9 * any data that is important to have ready from a very early stage (e.g. things
10 * that must be displayed right away).
11 */
12
13var loadTimeData;
14
15(function() {
16  'use strict';
17
18  function LoadTimeData() {
19  }
20
21  LoadTimeData.prototype = {
22    /**
23     * Sets the backing object.
24     * @param {Object} value The de-serialized page data.
25     */
26    set data(value) {
27      expect(!this.data_, 'Re-setting data.');
28      this.data_ = value;
29    },
30
31    /**
32     * @return {boolean} True if |id| is a key in the dictionary.
33     */
34    valueExists: function(id) {
35      return id in this.data_;
36    },
37
38    /**
39     * Fetches a value, expecting that it exists.
40     * @param {string} id The key that identifies the desired value.
41     * @return {*} The corresponding value.
42     */
43    getValue: function(id) {
44      expect(this.data_, 'No data. Did you remember to include strings.js?');
45      var value = this.data_[id];
46      expect(typeof value != 'undefined', 'Could not find value for ' + id);
47      return value;
48    },
49
50    /**
51     * As above, but also makes sure that the value is a string.
52     * @param {string} id The key that identifies the desired string.
53     * @return {string} The corresponding string value.
54     */
55    getString: function(id) {
56      var value = this.getValue(id);
57      expectIsType(id, value, 'string');
58      return value;
59    },
60
61    /**
62     * Returns a formatted localized string where $1 to $9 are replaced by the
63     * second to the tenth argument.
64     * @param {string} id The ID of the string we want.
65     * @param {...string} The extra values to include in the formatted output.
66     * @return {string} The formatted string.
67     */
68    getStringF: function(id) {
69      var value = this.getString(id);
70      if (!value)
71        return;
72
73      var varArgs = arguments;
74      return value.replace(/\$[$1-9]/g, function(m) {
75        return m == '$$' ? '$' : varArgs[m[1]];
76      });
77    },
78
79    /**
80     * As above, but also makes sure that the value is a boolean.
81     * @param {string} id The key that identifies the desired boolean.
82     * @return {boolean} The corresponding boolean value.
83     */
84    getBoolean: function(id) {
85      var value = this.getValue(id);
86      expectIsType(id, value, 'boolean');
87      return value;
88    },
89
90    /**
91     * As above, but also makes sure that the value is an integer.
92     * @param {string} id The key that identifies the desired number.
93     * @return {number} The corresponding number value.
94     */
95    getInteger: function(id) {
96      var value = this.getValue(id);
97      expectIsType(id, value, 'number');
98      expect(value == Math.floor(value), 'Number isn\'t integer: ' + value);
99      return value;
100    },
101
102    /**
103     * Override values in loadTimeData with the values found in |replacements|.
104     * @param {Object} replacements The dictionary object of keys to replace.
105     */
106    overrideValues: function(replacements) {
107      expect(typeof replacements == 'object',
108             'Replacements must be a dictionary object.');
109      for (var key in replacements) {
110        this.data_[key] = replacements[key];
111      }
112    }
113  };
114
115  /**
116   * Checks condition, displays error message if expectation fails.
117   * @param {*} condition The condition to check for truthiness.
118   * @param {string} message The message to display if the check fails.
119   */
120  function expect(condition, message) {
121    if (!condition)
122      console.error(message);
123  }
124
125  /**
126   * Checks that the given value has the given type.
127   * @param {string} id The id of the value (only used for error message).
128   * @param {*} value The value to check the type on.
129   * @param {string} type The type we expect |value| to be.
130   */
131  function expectIsType(id, value, type) {
132    expect(typeof value == type, '[' + value + '] (' + id +
133                                 ') is not a ' + type);
134  }
135
136  expect(!loadTimeData, 'should only include this file once');
137  loadTimeData = new LoadTimeData;
138})();
139