# _base.js

    1// Copyright 2012 Selenium committers2// Copyright 2012 Software Freedom Conservancy3//4// Licensed under the Apache License, Version 2.0 (the "License");5// you may not use this file except in compliance with the License.6//     You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS,12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13// See the License for the specific language governing permissions and14// limitations under the License.1516/**17 * @fileoverview The base module responsible for bootstrapping the Closure18 * library and providing a means of loading Closure-based modules.19 *20 * <p>Each script loaded by this module will be granted access to this module's21 * {@code require} function; all required non-native modules must be specified22 * relative to <em>this</em> module.23 *24 * <p>This module will load all scripts from the "lib" subdirectory, unless the25 * SELENIUM_DEV_MODE environment variable has been set to 1, in which case all26 * scripts will be loaded from the Selenium client containing this script.27 */2829'use strict';3031var fs = require('fs'),32    path = require('path'),33    vm = require('vm');343536/**37 * If this script was loaded from the Selenium project repo, it will operate in38 * development mode, adjusting how it loads Closure-based dependencies.39 * @type {boolean}40 */41var devMode = (function() {42  var buildDescFile = path.join(__dirname, '..', 'build.desc');43  return fs.existsSync(buildDescFile);44})();454647/** @return {boolean} Whether this script was loaded in dev mode. */48function isDevMode() {49  return devMode;50}515253/**54 * @type {string} Path to Closure's base file, relative to this module.55 * @const56 */57var CLOSURE_BASE_FILE_PATH = (function() {58  var relativePath = isDevMode() ?59      '../../../third_party/closure/goog/base.js' :60      './lib/goog/base.js';61  return path.join(__dirname, relativePath);62})();636465/**66 * @type {string} Path to Closure's base file, relative to this module.67 * @const68 */69var DEPS_FILE_PATH = (function() {70  var relativePath = isDevMode() ?71      '../../../javascript/deps.js' :72      './lib/goog/deps.js';73  return path.join(__dirname, relativePath);74})();75767778/**79 * Synchronously loads a script into the protected Closure context.80 * @param {string} src Path to the file to load.81 */82function loadScript(src) {83  src = path.normalize(src);84  var contents = fs.readFileSync(src, 'utf8');85  vm.runInContext(contents, closure, src);86}878889/**90 * The protected context to host the Closure library.91 * @type {!Object}92 * @const93 */94var closure = vm.createContext({95  console: console,96  setTimeout: setTimeout,97  setInterval: setInterval,98  clearTimeout: clearTimeout,99  clearInterval: clearInterval,100  process: process,101  require: require,102  Buffer: Buffer,103  Error: Error,104  CLOSURE_BASE_PATH: path.dirname(CLOSURE_BASE_FILE_PATH) + '/',105  CLOSURE_IMPORT_SCRIPT: function(src) {106    loadScript(src);107    return true;108  },109  CLOSURE_NO_DEPS: !isDevMode(),110  goog: {}111});112closure.window = closure;113114115loadScript(CLOSURE_BASE_FILE_PATH);116loadScript(DEPS_FILE_PATH);117118119/**120 * Loads a symbol by name from the protected Closure context.121 * @param {string} symbol The symbol to load.122 * @return {?} The loaded symbol, or {@code null} if not found.123 * @throws {Error} If the symbol has not been defined.124 */125function closureRequire(symbol) {126  closure.goog.require(symbol);127  return closure.goog.getObjectByName(symbol);128}129130131// PUBLIC API132133134/**135 * Loads a symbol by name from the protected Closure context and exports its136 * public API to the provided object. This function relies on Closure code137 * conventions to define the public API of an object as those properties whose138 * name does not end with "_".139 * @param {string} symbol The symbol to load. This must resolve to an object.140 * @return {!Object} An object with the exported API.141 * @throws {Error} If the symbol has not been defined or does not resolve to142 *     an object.143 */144exports.exportPublicApi = function(symbol) {145  var src = closureRequire(symbol);146  if (typeof src != 'object' || src === null) {147    throw Error('"' + symbol + '" must resolve to an object');148  }149150  var dest = {};151  Object.keys(src).forEach(function(key) {152    if (key[key.length - 1] != '_') {153      dest[key] = src[key];154    }155  });156157  return dest;158};159160161if (isDevMode()) {162  exports.closure = closure;163}164exports.isDevMode = isDevMode;165exports.require = closureRequire;