Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/javascript/selenium-webdriver/lib/color.js
8668 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
'use strict'
19
20
/**
21
* @fileoverview Color parsing and formatting utilities mirroring Selenium's Java Color.
22
*/
23
24
class Color {
25
/**
26
* @param {number} red
27
* @param {number} green
28
* @param {number} blue
29
* @param {number} alpha
30
*/
31
constructor(red, green, blue, alpha = 1) {
32
this.red_ = Color.#clamp255(red)
33
this.green_ = Color.#clamp255(green)
34
this.blue_ = Color.#clamp255(blue)
35
this.alpha_ = Color.#clamp01(alpha)
36
}
37
38
/**
39
* Guesses the input color format and returns a Color instance.
40
* @param {string} value
41
* @returns {Color}
42
*/
43
static fromString(value) {
44
const v = String(value)
45
for (const conv of [
46
Color.#fromRgb,
47
Color.#fromRgbPct,
48
Color.#fromRgba,
49
Color.#fromRgbaPct,
50
Color.#fromHex6,
51
Color.#fromHex3,
52
Color.#fromHsl,
53
Color.#fromHsla,
54
Color.#fromNamed,
55
]) {
56
const c = conv(v)
57
if (c) return c
58
}
59
throw new Error(`Did not know how to convert ${value} into color`)
60
}
61
62
/**
63
* Sets opacity (alpha channel).
64
* @param {number} alpha
65
*/
66
setOpacity(alpha) {
67
this.alpha_ = Color.#clamp01(alpha)
68
}
69
70
/**
71
* @returns {string} e.g. "rgb(255, 0, 0)"
72
*/
73
asRgb() {
74
return `rgb(${this.red_}, ${this.green_}, ${this.blue_})`
75
}
76
77
/**
78
* @returns {string} e.g. "rgba(255, 0, 0, 1)"
79
*/
80
asRgba() {
81
let a
82
if (this.alpha_ === 1) {
83
a = '1'
84
} else if (this.alpha_ === 0) {
85
a = '0'
86
} else {
87
a = String(this.alpha_)
88
}
89
return `rgba(${this.red_}, ${this.green_}, ${this.blue_}, ${a})`
90
}
91
92
/**
93
* @returns {string} e.g. "#ff0000"
94
*/
95
asHex() {
96
const toHex = (n) => n.toString(16).padStart(2, '0')
97
return `#${toHex(this.red_)}${toHex(this.green_)}${toHex(this.blue_)}`
98
}
99
100
/** @override */
101
toString() {
102
return `Color: ${this.asRgba()}`
103
}
104
105
/**
106
* @param {*} other
107
* @returns {boolean}
108
*/
109
equals(other) {
110
return other instanceof Color && this.asRgba() === other.asRgba()
111
}
112
113
// Converters
114
static #fromRgb(v) {
115
const m = /^\s*rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)\s*$/i.exec(v)
116
return m ? new Color(+m[1], +m[2], +m[3], 1) : null
117
}
118
119
static #fromRgbPct(v) {
120
const m =
121
/^\s*rgb\(\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,\s*(\d{1,3}|\d{1,2}\.\d+)%\s*\)\s*$/i.exec(
122
v,
123
)
124
if (!m) return null
125
const pct = (i) => Math.floor((Math.min(100, Math.max(0, parseFloat(m[i]))) / 100) * 255)
126
return new Color(pct(1), pct(2), pct(3), 1)
127
}
128
129
static #fromRgba(v) {
130
const m = /^\s*rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0\.\d+)\s*\)\s*$/i.exec(v)
131
return m ? new Color(+m[1], +m[2], +m[3], parseFloat(m[4])) : null
132
}
133
134
static #fromRgbaPct(v) {
135
const m =
136
/^\s*rgba\(\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,\s*(0|1|0\.\d+)\s*\)\s*$/i.exec(
137
v,
138
)
139
if (!m) return null
140
const pct = (i) => Math.floor((Math.min(100, Math.max(0, parseFloat(m[i]))) / 100) * 255)
141
return new Color(pct(1), pct(2), pct(3), parseFloat(m[4]))
142
}
143
144
static #fromHex6(v) {
145
const m = /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i.exec(v)
146
return m ? new Color(parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16), 1) : null
147
}
148
149
static #fromHex3(v) {
150
const m = /^#([\da-f])([\da-f])([\da-f])$/i.exec(v)
151
return m ? new Color(parseInt(m[1] + m[1], 16), parseInt(m[2] + m[2], 16), parseInt(m[3] + m[3], 16), 1) : null
152
}
153
154
static #fromHsl(v) {
155
const m = /^\s*hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\)\s*$/i.exec(v)
156
return m ? Color.#hslToColor(+m[1], +m[2] / 100, +m[3] / 100, 1) : null
157
}
158
159
static #fromHsla(v) {
160
const m = /^\s*hsla\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,\s*(0|1|0\.\d+)\s*\)\s*$/i.exec(v)
161
return m ? Color.#hslToColor(+m[1], +m[2] / 100, +m[3] / 100, parseFloat(m[4])) : null
162
}
163
164
static #hslToColor(hDeg, s, l, a) {
165
const h = (((hDeg % 360) + 360) % 360) / 360
166
if (s === 0) {
167
const v = Math.round(l * 255)
168
return new Color(v, v, v, a)
169
}
170
const luminocity2 = l < 0.5 ? l * (1 + s) : l + s - l * s
171
const luminocity1 = 2 * l - luminocity2
172
const hueToRgb = (l1, l2, hue) => {
173
if (hue < 0) hue += 1
174
if (hue > 1) hue -= 1
175
if (hue < 1 / 6) return l1 + (l2 - l1) * 6 * hue
176
if (hue < 1 / 2) return l2
177
if (hue < 2 / 3) return l1 + (l2 - l1) * (2 / 3 - hue) * 6
178
return l1
179
}
180
const r = Math.round(hueToRgb(luminocity1, luminocity2, h + 1 / 3) * 255)
181
const g = Math.round(hueToRgb(luminocity1, luminocity2, h) * 255)
182
const b = Math.round(hueToRgb(luminocity1, luminocity2, h - 1 / 3) * 255)
183
return new Color(r, g, b, a)
184
}
185
186
static #fromNamed(v) {
187
const name = String(v).trim().toLowerCase()
188
const c = Colors[name]
189
return c ? new Color(c.red_, c.green_, c.blue_, c.alpha_) : null
190
}
191
192
static #clamp255(n) {
193
return Math.max(0, Math.min(255, Math.round(n)))
194
}
195
196
static #clamp01(n) {
197
return Math.max(0, Math.min(1, n))
198
}
199
}
200
201
// Basic colour keywords as defined by the W3C HTML/CSS spec.
202
// Keys are lowercase to match typical CSS usage.
203
const Colors = {
204
transparent: new Color(0, 0, 0, 0),
205
aliceblue: new Color(240, 248, 255, 1),
206
antiquewhite: new Color(250, 235, 215, 1),
207
aqua: new Color(0, 255, 255, 1),
208
aquamarine: new Color(127, 255, 212, 1),
209
azure: new Color(240, 255, 255, 1),
210
beige: new Color(245, 245, 220, 1),
211
bisque: new Color(255, 228, 196, 1),
212
black: new Color(0, 0, 0, 1),
213
blanchedalmond: new Color(255, 235, 205, 1),
214
blue: new Color(0, 0, 255, 1),
215
blueviolet: new Color(138, 43, 226, 1),
216
brown: new Color(165, 42, 42, 1),
217
burlywood: new Color(222, 184, 135, 1),
218
cadetblue: new Color(95, 158, 160, 1),
219
chartreuse: new Color(127, 255, 0, 1),
220
chocolate: new Color(210, 105, 30, 1),
221
coral: new Color(255, 127, 80, 1),
222
cornflowerblue: new Color(100, 149, 237, 1),
223
cornsilk: new Color(255, 248, 220, 1),
224
crimson: new Color(220, 20, 60, 1),
225
cyan: new Color(0, 255, 255, 1),
226
darkblue: new Color(0, 0, 139, 1),
227
darkcyan: new Color(0, 139, 139, 1),
228
darkgoldenrod: new Color(184, 134, 11, 1),
229
darkgray: new Color(169, 169, 169, 1),
230
darkgreen: new Color(0, 100, 0, 1),
231
darkgrey: new Color(169, 169, 169, 1),
232
darkkhaki: new Color(189, 183, 107, 1),
233
darkmagenta: new Color(139, 0, 139, 1),
234
darkolivegreen: new Color(85, 107, 47, 1),
235
darkorange: new Color(255, 140, 0, 1),
236
darkorchid: new Color(153, 50, 204, 1),
237
darkred: new Color(139, 0, 0, 1),
238
darksalmon: new Color(233, 150, 122, 1),
239
darkseagreen: new Color(143, 188, 143, 1),
240
darkslateblue: new Color(72, 61, 139, 1),
241
darkslategray: new Color(47, 79, 79, 1),
242
darkslategrey: new Color(47, 79, 79, 1),
243
darkturquoise: new Color(0, 206, 209, 1),
244
darkviolet: new Color(148, 0, 211, 1),
245
deeppink: new Color(255, 20, 147, 1),
246
deepskyblue: new Color(0, 191, 255, 1),
247
dimgray: new Color(105, 105, 105, 1),
248
dimgrey: new Color(105, 105, 105, 1),
249
dodgerblue: new Color(30, 144, 255, 1),
250
firebrick: new Color(178, 34, 34, 1),
251
floralwhite: new Color(255, 250, 240, 1),
252
forestgreen: new Color(34, 139, 34, 1),
253
fuchsia: new Color(255, 0, 255, 1),
254
gainsboro: new Color(220, 220, 220, 1),
255
ghostwhite: new Color(248, 248, 255, 1),
256
gold: new Color(255, 215, 0, 1),
257
goldenrod: new Color(218, 165, 32, 1),
258
gray: new Color(128, 128, 128, 1),
259
grey: new Color(128, 128, 128, 1),
260
green: new Color(0, 128, 0, 1),
261
greenyellow: new Color(173, 255, 47, 1),
262
honeydew: new Color(240, 255, 240, 1),
263
hotpink: new Color(255, 105, 180, 1),
264
indianred: new Color(205, 92, 92, 1),
265
indigo: new Color(75, 0, 130, 1),
266
ivory: new Color(255, 255, 240, 1),
267
khaki: new Color(240, 230, 140, 1),
268
lavender: new Color(230, 230, 250, 1),
269
lavenderblush: new Color(255, 240, 245, 1),
270
lawngreen: new Color(124, 252, 0, 1),
271
lemonchiffon: new Color(255, 250, 205, 1),
272
lightblue: new Color(173, 216, 230, 1),
273
lightcoral: new Color(240, 128, 128, 1),
274
lightcyan: new Color(224, 255, 255, 1),
275
lightgoldenrodyellow: new Color(250, 250, 210, 1),
276
lightgray: new Color(211, 211, 211, 1),
277
lightgreen: new Color(144, 238, 144, 1),
278
lightgrey: new Color(211, 211, 211, 1),
279
lightpink: new Color(255, 182, 193, 1),
280
lightsalmon: new Color(255, 160, 122, 1),
281
lightseagreen: new Color(32, 178, 170, 1),
282
lightskyblue: new Color(135, 206, 250, 1),
283
lightslategray: new Color(119, 136, 153, 1),
284
lightslategrey: new Color(119, 136, 153, 1),
285
lightsteelblue: new Color(176, 196, 222, 1),
286
lightyellow: new Color(255, 255, 224, 1),
287
lime: new Color(0, 255, 0, 1),
288
limegreen: new Color(50, 205, 50, 1),
289
linen: new Color(250, 240, 230, 1),
290
magenta: new Color(255, 0, 255, 1),
291
maroon: new Color(128, 0, 0, 1),
292
mediumaquamarine: new Color(102, 205, 170, 1),
293
mediumblue: new Color(0, 0, 205, 1),
294
mediumorchid: new Color(186, 85, 211, 1),
295
mediumpurple: new Color(147, 112, 219, 1),
296
mediumseagreen: new Color(60, 179, 113, 1),
297
mediumslateblue: new Color(123, 104, 238, 1),
298
mediumspringgreen: new Color(0, 250, 154, 1),
299
mediumturquoise: new Color(72, 209, 204, 1),
300
mediumvioletred: new Color(199, 21, 133, 1),
301
midnightblue: new Color(25, 25, 112, 1),
302
mintcream: new Color(245, 255, 250, 1),
303
mistyrose: new Color(255, 228, 225, 1),
304
moccasin: new Color(255, 228, 181, 1),
305
navajowhite: new Color(255, 222, 173, 1),
306
navy: new Color(0, 0, 128, 1),
307
oldlace: new Color(253, 245, 230, 1),
308
olive: new Color(128, 128, 0, 1),
309
olivedrab: new Color(107, 142, 35, 1),
310
orange: new Color(255, 165, 0, 1),
311
orangered: new Color(255, 69, 0, 1),
312
orchid: new Color(218, 112, 214, 1),
313
palegoldenrod: new Color(238, 232, 170, 1),
314
palegreen: new Color(152, 251, 152, 1),
315
paleturquoise: new Color(175, 238, 238, 1),
316
palevioletred: new Color(219, 112, 147, 1),
317
papayawhip: new Color(255, 239, 213, 1),
318
peachpuff: new Color(255, 218, 185, 1),
319
peru: new Color(205, 133, 63, 1),
320
pink: new Color(255, 192, 203, 1),
321
plum: new Color(221, 160, 221, 1),
322
powderblue: new Color(176, 224, 230, 1),
323
purple: new Color(128, 0, 128, 1),
324
rebeccapurple: new Color(102, 51, 153, 1),
325
red: new Color(255, 0, 0, 1),
326
rosybrown: new Color(188, 143, 143, 1),
327
royalblue: new Color(65, 105, 225, 1),
328
saddlebrown: new Color(139, 69, 19, 1),
329
salmon: new Color(250, 128, 114, 1),
330
sandybrown: new Color(244, 164, 96, 1),
331
seagreen: new Color(46, 139, 87, 1),
332
seashell: new Color(255, 245, 238, 1),
333
sienna: new Color(160, 82, 45, 1),
334
silver: new Color(192, 192, 192, 1),
335
skyblue: new Color(135, 206, 235, 1),
336
slateblue: new Color(106, 90, 205, 1),
337
slategray: new Color(112, 128, 144, 1),
338
slategrey: new Color(112, 128, 144, 1),
339
snow: new Color(255, 250, 250, 1),
340
springgreen: new Color(0, 255, 127, 1),
341
steelblue: new Color(70, 130, 180, 1),
342
tan: new Color(210, 180, 140, 1),
343
teal: new Color(0, 128, 128, 1),
344
thistle: new Color(216, 191, 216, 1),
345
tomato: new Color(255, 99, 71, 1),
346
turquoise: new Color(64, 224, 208, 1),
347
violet: new Color(238, 130, 238, 1),
348
wheat: new Color(245, 222, 179, 1),
349
white: new Color(255, 255, 255, 1),
350
whitesmoke: new Color(245, 245, 245, 1),
351
yellow: new Color(255, 255, 0, 1),
352
yellowgreen: new Color(154, 205, 50, 1),
353
}
354
355
module.exports = {
356
Color,
357
Colors,
358
}
359
360