All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.js.util.global.js Maven / Gradle / Ivy

/*
 * Copyright 2016 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Runtime code to store the global object.
 * @suppress {uselessCode}
 */
'require base';

/**
 * Locate and return a reference to the global object.
 *
 * NOTE: This method is marked with `noinline`, because `RemoveUnusedCode` has
 * trouble removing the loop it contains if it gets inlined into the global
 * scope.
 * @param {?Object} passedInThis
 * @return {!Global} The global object.
 * @suppress {undefinedVars|reportUnknownTypes}
 * @noinline
 */
$jscomp.getGlobal = function(passedInThis) {
  var possibleGlobals = [
    // Web Audio Worklets do not have any way to refer to their global object
    // other than `globalThis`.
    // This use of `globalThis` does not prevent removal of the `globalThis`
    // polyfill, because the usage is guarded by a typeof check.
    'object' == typeof globalThis && globalThis,
    // Rhino (used by older Google Docs Script projects) has no `window` or
    // `self`, but `this` from the global scope is the global object. Also,
    // some GWT tests running on Rhino do have a `window` and `self` but, for
    // unknown reasons, see runtime exceptions when we return `window` instead
    // of `passedInThis`.
    // NOTE: If the compiler's output is wrapped in a strict-mode function,
    // this file's code won't actually be executing in global scope, so this
    // value will be undefined.
    passedInThis,
    // Browser windows always have `window`
    'object' == typeof window && window,
    // WebWorkers have `self`
    'object' == typeof self && self,
    // NodeJS has `global`
    'object' == typeof global && global,
  ];
  for (var i = 0; i < possibleGlobals.length; ++i) {
    var maybeGlobal = possibleGlobals[i];
    // It can happen that an environment has, for example, both `global` and
    // `window` defined in the global scope, but one of them isn't actually
    // the global object, so check that it really seems to be the global object.
    // We use `Math` to check for this because it's only 4 characters long,
    // exists in all possible JS environments, and doesn't have the problematic
    // equality behavior of `NaN`.
    if (maybeGlobal && maybeGlobal['Math'] == Math) {
      return /** @type {!Global} */ (maybeGlobal);
    }
  }
  // Throw an exception if we cannot find the global object.
  // We have to be sneaky about it, otherwise the compiler will think this code
  // has a side effect (throwing an exception) that prevents it from being
  // removed, even when all usages of `$jscomp.global` get removed.
  // Casting through unknown is necessary to keep the compiler from rejecting
  // this code.
  return /** @type {!Global} */ (
      /** @type {?} */ ({
        valueOf: function() {
          throw new Error('Cannot find global object');
        }
      }.valueOf()));
};


/**
 * The global object.
 * @const {!Global}
 */
$jscomp.global = $jscomp.getGlobal(this);




© 2015 - 2024 Weber Informatics LLC | Privacy Policy