Path: blob/trunk/third_party/closure/goog/labs/useragent/highentropy/highentropyvalue.js
4443 views
/**1* @license2* Copyright The Closure Library Authors.3* SPDX-License-Identifier: Apache-2.04*/56/**7* @fileoverview Provides helper classes and objects to work with High Entropy8* user agent values.9*/1011goog.module('goog.labs.userAgent.highEntropy.highEntropyValue');1213const util = goog.require('goog.labs.userAgent.util');14const {compareVersions} = goog.require('goog.string.internal');1516/**17* Represents a value that can be asynchronously loaded.18* @interface19* @template VALUE_TYPE20*/21class AsyncValue {22/**23* Get the value represented by this AsyncValue instance, if it was24* previously requested.25* @return {VALUE_TYPE|undefined}26*/27getIfLoaded() {}2829/**30* Request the value represented by this AsyncValue instance.31* @return {!Promise<VALUE_TYPE>}32*/33load() {}34}35exports.AsyncValue = AsyncValue;3637/**38* Represents a high-entropy value.39* High-entropy values must be specifically requested from the Promise-based40* Client Hints API.41* @template VALUE_TYPE The type of the value wrapped by this HighEntropyValue42* instance.43* @implements {AsyncValue<VALUE_TYPE>}44*/45class HighEntropyValue {46/**47* Constructs a new HighEntropyValue instance.48* @param {string} key The name of the high-entropy value, used when49* requesting it from the browser.50*/51constructor(key) {52/**53* The key used to request the high-entropy value from the browser.54* @const {string}55* @private56*/57this.key_ = key;5859/**60* The value represented by this HighEntropyValue instance. If it hasn't61* been successfully requested yet, its value will be undefined.62* @type {VALUE_TYPE|undefined}63* @protected64*/65this.value_ = undefined;6667/**68* The high-entropy value request. If it hasn't been requested yet, this69* value will be undefined.70* @type {!Promise<VALUE_TYPE>|undefined}71* @private72*/73this.promise_ = undefined;7475this.pending_ = false;76}7778/**79* @return {VALUE_TYPE|undefined}80* @override81*/82getIfLoaded() {83const userAgentData = util.getUserAgentData();84if (!userAgentData) {85return undefined;86}87return this.value_;88}8990/**91* @return {!Promise<VALUE_TYPE>}92* @override93*/94async load() {95const userAgentData = util.getUserAgentData();96if (!userAgentData) return undefined;97if (!this.promise_) {98this.pending_ = true;99this.promise_ = (async () => {100try {101const dataValues =102await userAgentData.getHighEntropyValues([this.key_]);103this.value_ =104/** @type {!Object<string, VALUE_TYPE>} */ (105dataValues)[this.key_];106return this.value_;107} finally {108this.pending_ = false;109}110})();111}112return await this.promise_;113}114115resetForTesting() {116if (this.pending_) {117// There is a pending request that may set this.value_ at any time.118// Therefore, it can't be guaranteed that this object is actually in a119// clean state.120throw new Error('Unsafe call to resetForTesting');121}122this.promise_ = undefined;123this.value_ = undefined;124this.pending_ = false;125}126}127exports.HighEntropyValue = HighEntropyValue;128129/**130* An object that wraps a version string.131* This allows for easy version comparisons.132*/133class Version {134/**135* @param {string} versionString The underlying version string.136*/137constructor(versionString) {138/**139* @const {string}140* @private141*/142this.versionString_ = versionString;143}144145/**146* Returns the underlying version string.147* @return {string}148*/149toVersionStringForLogging() {150return this.versionString_;151}152153/**154* Returns true if the underlying version string is equal to or greater than155* the given version.156* @param {string} version The version to compare against.157* @return {boolean}158*/159isAtLeast(version) {160return compareVersions(this.versionString_, version) >= 0;161}162}163exports.Version = Version;164165166