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// Expose this type globally as a temporary work around until 16// https://github.com/google/closure-compiler/issues/544 is fixed. 17/** @constructor */ 18function LoadTimeData() {} 19 20(function() { 21 'use strict'; 22 23 LoadTimeData.prototype = { 24 /** 25 * Sets the backing object. 26 * 27 * Note that there is no getter for |data_| to discourage abuse of the form: 28 * 29 * var value = loadTimeData.data()['key']; 30 * 31 * @param {Object} value The de-serialized page data. 32 */ 33 set data(value) { 34 expect(!this.data_, 'Re-setting data.'); 35 this.data_ = value; 36 }, 37 38 /** 39 * Returns a JsEvalContext for |data_|. 40 * @returns {JsEvalContext} 41 */ 42 createJsEvalContext: function() { 43 return new JsEvalContext(this.data_); 44 }, 45 46 /** 47 * @param {string} id An ID of a value that might exist. 48 * @return {boolean} True if |id| is a key in the dictionary. 49 */ 50 valueExists: function(id) { 51 return id in this.data_; 52 }, 53 54 /** 55 * Fetches a value, expecting that it exists. 56 * @param {string} id The key that identifies the desired value. 57 * @return {*} The corresponding value. 58 */ 59 getValue: function(id) { 60 expect(this.data_, 'No data. Did you remember to include strings.js?'); 61 var value = this.data_[id]; 62 expect(typeof value != 'undefined', 'Could not find value for ' + id); 63 return value; 64 }, 65 66 /** 67 * As above, but also makes sure that the value is a string. 68 * @param {string} id The key that identifies the desired string. 69 * @return {string} The corresponding string value. 70 */ 71 getString: function(id) { 72 var value = this.getValue(id); 73 expectIsType(id, value, 'string'); 74 return /** @type {string} */ (value); 75 }, 76 77 /** 78 * Returns a formatted localized string where $1 to $9 are replaced by the 79 * second to the tenth argument. 80 * @param {string} id The ID of the string we want. 81 * @param {...string} var_args The extra values to include in the formatted 82 * output. 83 * @return {string} The formatted string. 84 */ 85 getStringF: function(id, var_args) { 86 var value = this.getString(id); 87 if (!value) 88 return ''; 89 90 var varArgs = arguments; 91 return value.replace(/\$[$1-9]/g, function(m) { 92 return m == '$$' ? '$' : varArgs[m[1]]; 93 }); 94 }, 95 96 /** 97 * As above, but also makes sure that the value is a boolean. 98 * @param {string} id The key that identifies the desired boolean. 99 * @return {boolean} The corresponding boolean value. 100 */ 101 getBoolean: function(id) { 102 var value = this.getValue(id); 103 expectIsType(id, value, 'boolean'); 104 return /** @type {boolean} */ (value); 105 }, 106 107 /** 108 * As above, but also makes sure that the value is an integer. 109 * @param {string} id The key that identifies the desired number. 110 * @return {number} The corresponding number value. 111 */ 112 getInteger: function(id) { 113 var value = this.getValue(id); 114 expectIsType(id, value, 'number'); 115 expect(value == Math.floor(value), 'Number isn\'t integer: ' + value); 116 return /** @type {number} */ (value); 117 }, 118 119 /** 120 * Override values in loadTimeData with the values found in |replacements|. 121 * @param {Object} replacements The dictionary object of keys to replace. 122 */ 123 overrideValues: function(replacements) { 124 expect(typeof replacements == 'object', 125 'Replacements must be a dictionary object.'); 126 for (var key in replacements) { 127 this.data_[key] = replacements[key]; 128 } 129 } 130 }; 131 132 /** 133 * Checks condition, displays error message if expectation fails. 134 * @param {*} condition The condition to check for truthiness. 135 * @param {string} message The message to display if the check fails. 136 */ 137 function expect(condition, message) { 138 if (!condition) { 139 console.error('Unexpected condition on ' + document.location.href + ': ' + 140 message); 141 } 142 } 143 144 /** 145 * Checks that the given value has the given type. 146 * @param {string} id The id of the value (only used for error message). 147 * @param {*} value The value to check the type on. 148 * @param {string} type The type we expect |value| to be. 149 */ 150 function expectIsType(id, value, type) { 151 expect(typeof value == type, '[' + value + '] (' + id + 152 ') is not a ' + type); 153 } 154 155 expect(!loadTimeData, 'should only include this file once'); 156 loadTimeData = new LoadTimeData; 157})(); 158