Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/javascript/atoms/color.js
2884 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
/**
19
* @fileoverview Utilities related to color and color conversion.
20
* Some of this code is borrowed and modified from goog.color and
21
* goog.color.alpha.
22
*/
23
24
goog.provide('bot.color');
25
26
goog.require('goog.array');
27
goog.require('goog.color.names');
28
29
30
/**
31
* Returns a property, with a standardized color if it contains a
32
* convertible color.
33
* @param {string} propertyName Name of the CSS property in camelCase.
34
* @param {string} propertyValue The value of the CSS property.
35
* @return {string} The value, in a standardized format
36
* if it is a color property.
37
*/
38
bot.color.standardizeColor = function (propertyName, propertyValue) {
39
if (!goog.array.contains(bot.color.COLOR_PROPERTIES_, propertyName)) {
40
return propertyValue;
41
}
42
var rgba =
43
bot.color.maybeParseRgbaColor_(propertyValue) ||
44
bot.color.maybeParseRgbColor_(propertyValue) ||
45
bot.color.maybeConvertHexOrColorName_(propertyValue);
46
return rgba ? 'rgba(' + rgba.join(', ') + ')' : propertyValue;
47
};
48
49
50
/**
51
* Used to determine whether a css property contains a color and
52
* should therefore be standardized to rgba.
53
* These are extracted from the W3C CSS spec:
54
*
55
* http://www.w3.org/TR/CSS/#properties
56
*
57
* @const
58
* @private {!Array.<string>}
59
*/
60
bot.color.COLOR_PROPERTIES_ = [
61
'backgroundColor',
62
'borderTopColor',
63
'borderRightColor',
64
'borderBottomColor',
65
'borderLeftColor',
66
'color',
67
'outlineColor'
68
];
69
70
71
/**
72
* Regular expression for extracting the digits in a hex color triplet.
73
* @private {!RegExp}
74
* @const
75
*/
76
bot.color.HEX_TRIPLET_RE_ = /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/;
77
78
79
/**
80
* Converts a hex representation of a color to RGB.
81
* @param {string} hexOrColorName Color to convert.
82
* @return {?Array} array containing [r, g, b, 1] as ints in [0, 255] or null
83
* for invalid colors.
84
* @private
85
*/
86
bot.color.maybeConvertHexOrColorName_ = function (hexOrColorName) {
87
hexOrColorName = hexOrColorName.toLowerCase();
88
var hex = goog.color.names[hexOrColorName.toLowerCase()];
89
if (!hex) {
90
hex = hexOrColorName.charAt(0) == '#' ?
91
hexOrColorName : '#' + hexOrColorName;
92
if (hex.length == 4) { // of the form #RGB
93
hex = hex.replace(bot.color.HEX_TRIPLET_RE_, '#$1$1$2$2$3$3');
94
}
95
96
if (!bot.color.VALID_HEX_COLOR_RE_.test(hex)) {
97
return null;
98
}
99
}
100
101
var r = parseInt(hex.substr(1, 2), 16);
102
var g = parseInt(hex.substr(3, 2), 16);
103
var b = parseInt(hex.substr(5, 2), 16);
104
105
return [r, g, b, 1];
106
};
107
108
109
/**
110
* Helper for isValidHexColor_.
111
* @private {!RegExp}
112
* @const
113
*/
114
bot.color.VALID_HEX_COLOR_RE_ = /^#(?:[0-9a-f]{3}){1,2}$/i;
115
116
117
/**
118
* Regular expression for matching and capturing RGBA style strings.
119
* @private {!RegExp}
120
* @const
121
*/
122
bot.color.RGBA_COLOR_RE_ =
123
/^(?:rgba)?\((\d{1,3}),\s?(\d{1,3}),\s?(\d{1,3}),\s?(0|1|0\.\d*)\)$/i;
124
125
126
/**
127
* Attempts to parse a string as an rgba color. We expect strings of the
128
* format '(r, g, b, a)', or 'rgba(r, g, b, a)', where r, g, b are ints in
129
* [0, 255] and a is a float in [0, 1].
130
* @param {string} str String to check.
131
* @return {?Array.<number>} the integers [r, g, b, a] for valid colors or null
132
* for invalid colors.
133
* @private
134
*/
135
bot.color.maybeParseRgbaColor_ = function (str) {
136
// Each component is separate (rather than using a repeater) so we can
137
// capture the match. Also, we explicitly set each component to be either 0,
138
// or start with a non-zero, to prevent octal numbers from slipping through.
139
var regExpResultArray = str.match(bot.color.RGBA_COLOR_RE_);
140
if (regExpResultArray) {
141
var r = Number(regExpResultArray[1]);
142
var g = Number(regExpResultArray[2]);
143
var b = Number(regExpResultArray[3]);
144
var a = Number(regExpResultArray[4]);
145
if (r >= 0 && r <= 255 &&
146
g >= 0 && g <= 255 &&
147
b >= 0 && b <= 255 &&
148
a >= 0 && a <= 1) {
149
return [r, g, b, a];
150
}
151
}
152
return null;
153
};
154
155
156
/**
157
* Regular expression for matching and capturing RGB style strings.
158
* @private {!RegExp}
159
* @const
160
*/
161
bot.color.RGB_COLOR_RE_ =
162
/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;
163
164
165
/**
166
* Attempts to parse a string as an rgb color. We expect strings of the format
167
* '(r, g, b)', or 'rgb(r, g, b)', where each color component is an int in
168
* [0, 255].
169
* @param {string} str String to check.
170
* @return {?Array.<number>} the integers [r, g, b, 1] for valid colors or null
171
* for invalid colors.
172
* @private
173
*/
174
bot.color.maybeParseRgbColor_ = function (str) {
175
// Each component is separate (rather than using a repeater) so we can
176
// capture the match. Also, we explicitly set each component to be either 0,
177
// or start with a non-zero, to prevent octal numbers from slipping through.
178
var regExpResultArray = str.match(bot.color.RGB_COLOR_RE_);
179
if (regExpResultArray) {
180
var r = Number(regExpResultArray[1]);
181
var g = Number(regExpResultArray[2]);
182
var b = Number(regExpResultArray[3]);
183
if (r >= 0 && r <= 255 &&
184
g >= 0 && g <= 255 &&
185
b >= 0 && b <= 255) {
186
return [r, g, b, 1];
187
}
188
}
189
return null;
190
};
191
192