Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/third_party/closure/goog/labs/useragent/highentropy/highentropyvalue.js
4443 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
7
/**
8
* @fileoverview Provides helper classes and objects to work with High Entropy
9
* user agent values.
10
*/
11
12
goog.module('goog.labs.userAgent.highEntropy.highEntropyValue');
13
14
const util = goog.require('goog.labs.userAgent.util');
15
const {compareVersions} = goog.require('goog.string.internal');
16
17
/**
18
* Represents a value that can be asynchronously loaded.
19
* @interface
20
* @template VALUE_TYPE
21
*/
22
class AsyncValue {
23
/**
24
* Get the value represented by this AsyncValue instance, if it was
25
* previously requested.
26
* @return {VALUE_TYPE|undefined}
27
*/
28
getIfLoaded() {}
29
30
/**
31
* Request the value represented by this AsyncValue instance.
32
* @return {!Promise<VALUE_TYPE>}
33
*/
34
load() {}
35
}
36
exports.AsyncValue = AsyncValue;
37
38
/**
39
* Represents a high-entropy value.
40
* High-entropy values must be specifically requested from the Promise-based
41
* Client Hints API.
42
* @template VALUE_TYPE The type of the value wrapped by this HighEntropyValue
43
* instance.
44
* @implements {AsyncValue<VALUE_TYPE>}
45
*/
46
class HighEntropyValue {
47
/**
48
* Constructs a new HighEntropyValue instance.
49
* @param {string} key The name of the high-entropy value, used when
50
* requesting it from the browser.
51
*/
52
constructor(key) {
53
/**
54
* The key used to request the high-entropy value from the browser.
55
* @const {string}
56
* @private
57
*/
58
this.key_ = key;
59
60
/**
61
* The value represented by this HighEntropyValue instance. If it hasn't
62
* been successfully requested yet, its value will be undefined.
63
* @type {VALUE_TYPE|undefined}
64
* @protected
65
*/
66
this.value_ = undefined;
67
68
/**
69
* The high-entropy value request. If it hasn't been requested yet, this
70
* value will be undefined.
71
* @type {!Promise<VALUE_TYPE>|undefined}
72
* @private
73
*/
74
this.promise_ = undefined;
75
76
this.pending_ = false;
77
}
78
79
/**
80
* @return {VALUE_TYPE|undefined}
81
* @override
82
*/
83
getIfLoaded() {
84
const userAgentData = util.getUserAgentData();
85
if (!userAgentData) {
86
return undefined;
87
}
88
return this.value_;
89
}
90
91
/**
92
* @return {!Promise<VALUE_TYPE>}
93
* @override
94
*/
95
async load() {
96
const userAgentData = util.getUserAgentData();
97
if (!userAgentData) return undefined;
98
if (!this.promise_) {
99
this.pending_ = true;
100
this.promise_ = (async () => {
101
try {
102
const dataValues =
103
await userAgentData.getHighEntropyValues([this.key_]);
104
this.value_ =
105
/** @type {!Object<string, VALUE_TYPE>} */ (
106
dataValues)[this.key_];
107
return this.value_;
108
} finally {
109
this.pending_ = false;
110
}
111
})();
112
}
113
return await this.promise_;
114
}
115
116
resetForTesting() {
117
if (this.pending_) {
118
// There is a pending request that may set this.value_ at any time.
119
// Therefore, it can't be guaranteed that this object is actually in a
120
// clean state.
121
throw new Error('Unsafe call to resetForTesting');
122
}
123
this.promise_ = undefined;
124
this.value_ = undefined;
125
this.pending_ = false;
126
}
127
}
128
exports.HighEntropyValue = HighEntropyValue;
129
130
/**
131
* An object that wraps a version string.
132
* This allows for easy version comparisons.
133
*/
134
class Version {
135
/**
136
* @param {string} versionString The underlying version string.
137
*/
138
constructor(versionString) {
139
/**
140
* @const {string}
141
* @private
142
*/
143
this.versionString_ = versionString;
144
}
145
146
/**
147
* Returns the underlying version string.
148
* @return {string}
149
*/
150
toVersionStringForLogging() {
151
return this.versionString_;
152
}
153
154
/**
155
* Returns true if the underlying version string is equal to or greater than
156
* the given version.
157
* @param {string} version The version to compare against.
158
* @return {boolean}
159
*/
160
isAtLeast(version) {
161
return compareVersions(this.versionString_, version) >= 0;
162
}
163
}
164
exports.Version = Version;
165
166