15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @fileoverview This file defines a singleton which provides access to all data 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that is available as soon as the page's resources are loaded (before DOM 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * content has finished loading). This data includes both localized strings and 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * any data that is important to have ready from a very early stage (e.g. things 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that must be displayed right away). 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var loadTimeData; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Expose this type globally as a temporary work around until 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// https://github.com/google/closure-compiler/issues/544 is fixed. 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/** @constructor */ 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)function LoadTimeData() {} 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(function() { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'use strict'; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadTimeData.prototype = { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Sets the backing object. 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Note that there is no getter for |data_| to discourage abuse of the form: 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * var value = loadTimeData.data()['key']; 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} value The de-serialized page data. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set data(value) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expect(!this.data_, 'Re-setting data.'); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.data_ = value; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Returns a JsEvalContext for |data_|. 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @returns {JsEvalContext} 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci createJsEvalContext: function() { 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return new JsEvalContext(this.data_); 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {string} id An ID of a value that might exist. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} True if |id| is a key in the dictionary. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valueExists: function(id) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return id in this.data_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Fetches a value, expecting that it exists. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} id The key that identifies the desired value. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {*} The corresponding value. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getValue: function(id) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expect(this.data_, 'No data. Did you remember to include strings.js?'); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var value = this.data_[id]; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expect(typeof value != 'undefined', 'Could not find value for ' + id); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * As above, but also makes sure that the value is a string. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} id The key that identifies the desired string. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} The corresponding string value. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getString: function(id) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var value = this.getValue(id); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expectIsType(id, value, 'string'); 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return /** @type {string} */ (value); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a formatted localized string where $1 to $9 are replaced by the 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second to the tenth argument. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} id The ID of the string we want. 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {...string} var_args The extra values to include in the formatted 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * output. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} The formatted string. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) getStringF: function(id, var_args) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var value = this.getString(id); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value) 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ''; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var varArgs = arguments; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value.replace(/\$[$1-9]/g, function(m) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return m == '$$' ? '$' : varArgs[m[1]]; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * As above, but also makes sure that the value is a boolean. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} id The key that identifies the desired boolean. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} The corresponding boolean value. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getBoolean: function(id) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var value = this.getValue(id); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expectIsType(id, value, 'boolean'); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return /** @type {boolean} */ (value); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * As above, but also makes sure that the value is an integer. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} id The key that identifies the desired number. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {number} The corresponding number value. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getInteger: function(id) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var value = this.getValue(id); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expectIsType(id, value, 'number'); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expect(value == Math.floor(value), 'Number isn\'t integer: ' + value); 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return /** @type {number} */ (value); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Override values in loadTimeData with the values found in |replacements|. 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {Object} replacements The dictionary object of keys to replace. 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overrideValues: function(replacements) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expect(typeof replacements == 'object', 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'Replacements must be a dictionary object.'); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var key in replacements) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.data_[key] = replacements[key]; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks condition, displays error message if expectation fails. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {*} condition The condition to check for truthiness. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} message The message to display if the check fails. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function expect(condition, message) { 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!condition) { 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) console.error('Unexpected condition on ' + document.location.href + ': ' + 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) message); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks that the given value has the given type. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} id The id of the value (only used for error message). 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {*} value The value to check the type on. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} type The type we expect |value| to be. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function expectIsType(id, value, type) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expect(typeof value == type, '[' + value + '] (' + id + 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ') is not a ' + type); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expect(!loadTimeData, 'should only include this file once'); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loadTimeData = new LoadTimeData; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)})(); 158