Diff
Modified: trunk/LayoutTests/ChangeLog (239596 => 239597)
--- trunk/LayoutTests/ChangeLog 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/LayoutTests/ChangeLog 2019-01-03 21:58:23 UTC (rev 239597)
@@ -1,3 +1,14 @@
+2019-01-03 Devin Rousso <[email protected]>
+
+ Web Inspector: conic-gradient color picker doesn't accurately show color when saturation value is not 100%
+ https://bugs.webkit.org/show_bug.cgi?id=192729
+ <rdar://problem/46746815>
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/model/color.html:
+ * inspector/model/color-expected.txt:
+
2019-01-03 Brent Fulgham <[email protected]>
Remove logic handling DNT header during redirects
Modified: trunk/LayoutTests/inspector/model/color-expected.txt (239596 => 239597)
--- trunk/LayoutTests/inspector/model/color-expected.txt 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/LayoutTests/inspector/model/color-expected.txt 2019-01-03 21:58:23 UTC (rev 239597)
@@ -98,7 +98,7 @@
PASS: '#11122233' should be not be simple.
PASS: '#11122233' should not be a keyword.
PASS: '#11122233' has rgba of [17, 18, 34, 0.2].
-PASS: '#11122233' has hsla of [236, 33, 10, 0.2].
+PASS: '#11122233' has hsla of [236.47, 33.33, 10, 0.2].
PASS: '#11122233' should not be serializable as a short Hex
PASS: '#11223344' should be serializable as a short Hex
PASS: '#11223345' should not be serializable as a short Hex
@@ -112,16 +112,16 @@
Check components for color 'rgba(128, 128, 128, 0.5)'.
PASS: Should have rgb of [128,128,128].
PASS: Should have rgba of [128,128,128,0.5].
-PASS: Should have hsl of [0,0,50].
-PASS: Should have hsla of [0,0,50,0.5].
+PASS: Should have hsl of [0,0,50.2].
+PASS: Should have hsla of [0,0,50.2,0.5].
Check components for color 'hsl(0, 0%, 50%)'.
-PASS: Should have rgb of [128,128,128].
-PASS: Should have rgba of [128,128,128,1].
+PASS: Should have rgb of [127.5,127.5,127.5].
+PASS: Should have rgba of [127.5,127.5,127.5,1].
PASS: Should have hsl of [0,0,50].
PASS: Should have hsla of [0,0,50,1].
Check components for color 'hsla(0, 0%, 50%, 0.5)'.
-PASS: Should have rgb of [128,128,128].
-PASS: Should have rgba of [128,128,128,0.5].
+PASS: Should have rgb of [127.5,127.5,127.5].
+PASS: Should have rgba of [127.5,127.5,127.5,0.5].
PASS: Should have hsl of [0,0,50].
PASS: Should have hsla of [0,0,50,0.5].
@@ -150,19 +150,29 @@
PASS: Color as 'HEX with Alpha' should be '#64c8ff80'
PASS: Color as 'RGB' should be 'rgba(100, 200, 255, 0.5)'
PASS: Color as 'RGBA' should be 'rgba(100, 200, 255, 0.5)'
-PASS: Color as 'HSL' should be 'hsla(201, 100%, 70%, 0.5)'
-PASS: Color as 'HSLA' should be 'hsla(201, 100%, 70%, 0.5)'
+PASS: Color as 'HSL' should be 'hsla(201.29, 100%, 69.61%, 0.5)'
+PASS: Color as 'HSLA' should be 'hsla(201.29, 100%, 69.61%, 0.5)'
--- Running test case: WI.Color.rgb2hsv
+-- Running test case: WI.Color.rgb2hsl
PASS: Should convert [0,0,0] to [0,0,0].
-PASS: Should convert [255,255,255] to [0,0,1].
-PASS: Should convert [255,0,0] to [0,1,1].
-PASS: Should convert [0,255,0] to [120,1,1].
-PASS: Should convert [0,0,255] to [240,1,1].
+PASS: Should convert [255,255,255] to [0,0,100].
+PASS: Should convert [255,0,0] to [0,100,50].
+PASS: Should convert [0,255,0] to [120,100,50].
+PASS: Should convert [0,0,255] to [240,100,50].
PASS: Should convert [-1,-1,-1] to [0,0,0].
-PASS: Should convert [256,256,256] to [0,0,1].
-PASS: Should convert [254.9,0,0] to [0,1,1].
+PASS: Should convert [256,256,256] to [0,0,100].
+PASS: Should convert [254.9,0,0] to [0,100,50].
+-- Running test case: WI.Color.hsl2rgb
+PASS: Should convert [0,0,0] to [0,0,0].
+PASS: Should convert [0,0,100] to [255,255,255].
+PASS: Should convert [0,100,50] to [255,0,0].
+PASS: Should convert [120,100,50] to [0,255,0].
+PASS: Should convert [240,100,50] to [0,0,255].
+PASS: Should convert [-1,-1,-1] to [0,0,0].
+PASS: Should convert [361,101,50] to [255,0,0].
+PASS: Should convert [361,101,101] to [255,255,255].
+
-- Running test case: WI.Color.cmyk2rgb
PASS: Should convert [0,0,0,1] to [0,0,0].
PASS: Should convert [1,0,0,0] to [0,255,255].
Modified: trunk/LayoutTests/inspector/model/color.html (239596 => 239597)
--- trunk/LayoutTests/inspector/model/color.html 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/LayoutTests/inspector/model/color.html 2019-01-03 21:58:23 UTC (rev 239597)
@@ -32,12 +32,12 @@
}
}
- let suite = InspectorTest.createAsyncSuite("WI.Color");
+ let suite = InspectorTest.createSyncSuite("WI.Color");
suite.addTestCase({
name: "WI.Color.fromString",
description: "Test we can detect colors from strings.",
- test(resolve, reject) {
+ test() {
function testGood(string, expectedFormat) {
let color = WI.Color.fromString(string);
InspectorTest.expectThat(color instanceof WI.Color, `'${string}' should be detected`);
@@ -107,7 +107,7 @@
// testBad("hsl(0, 0, 50)"); // missing %s
// testBad("hsla(0, 0, 50, 1)"); // missing %s
- resolve();
+ return true;
}
});
@@ -114,7 +114,7 @@
suite.addTestCase({
name: "WI.Color properties",
description: "Test different color properties.",
- test(resolve, reject) {
+ test() {
let color;
color = WI.Color.fromString("red");
@@ -142,7 +142,7 @@
InspectorTest.expectThat(color.simple === false, "'#11122233' should be not be simple.");
InspectorTest.expectThat(color.isKeyword() === false, "'#11122233' should not be a keyword.");
InspectorTest.expectShallowEqual(color.rgba, [17, 18, 34, 0.2], "'#11122233' has rgba of [17, 18, 34, 0.2].");
- InspectorTest.expectShallowEqual(color.hsla, [236, 33, 10, 0.2], "'#11122233' has hsla of [236, 33, 10, 0.2].");
+ InspectorTest.expectShallowEqual(color.hsla.map((value) => value.maxDecimals(2)), [236.47, 33.33, 10, 0.2], "'#11122233' has hsla of [236.47, 33.33, 10, 0.2].");
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === false, "'#11122233' should not be serializable as a short Hex");
color = WI.Color.fromString("#11223344");
@@ -151,7 +151,7 @@
color = WI.Color.fromString("#11223345");
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === false, "'#11223345' should not be serializable as a short Hex");
- resolve();
+ return true;
}
});
@@ -158,12 +158,12 @@
suite.addTestCase({
name: "WI.Color from components",
description: "Test different three- and four-component colors.",
- test(resolve, reject) {
+ test() {
function test(color, components) {
InspectorTest.log(`Check components for color '${color.toString()}'.`);
for (let key in components) {
let value = components[key];
- InspectorTest.expectShallowEqual(color[key], value, `Should have ${key} of ${JSON.stringify(value)}.`);
+ InspectorTest.expectShallowEqual(color[key].map((value) => value.maxDecimals(2)), value, `Should have ${key} of ${JSON.stringify(value)}.`);
}
}
@@ -177,25 +177,25 @@
test(new WI.Color(WI.Color.Format.RGBA, [128, 128, 128, 0.5]), {
rgb: [128, 128, 128],
rgba: [128, 128, 128, 0.5],
- hsl: [0, 0, 50],
- hsla: [0, 0, 50, 0.5],
+ hsl: [0, 0, 50.2],
+ hsla: [0, 0, 50.2, 0.5],
});
test(new WI.Color(WI.Color.Format.HSL, [0, 0, 50]), {
- rgb: [128, 128, 128],
- rgba: [128, 128, 128, 1],
+ rgb: [127.5, 127.5, 127.5],
+ rgba: [127.5, 127.5, 127.5, 1],
hsl: [0, 0, 50],
hsla: [0, 0, 50, 1],
});
test(new WI.Color(WI.Color.Format.HSLA, [0, 0, 50, 0.5]), {
- rgb: [128, 128, 128],
- rgba: [128, 128, 128, 0.5],
+ rgb: [127.5, 127.5, 127.5],
+ rgba: [127.5, 127.5, 127.5, 0.5],
hsl: [0, 0, 50],
hsla: [0, 0, 50, 0.5],
});
- resolve();
+ return true;
}
});
@@ -202,7 +202,7 @@
suite.addTestCase({
name: "WI.Color.prototype.nextFormat",
description: "Test we can cycle through color formats for different colors.",
- test(resolve, reject) {
+ test() {
function test(string, phases) {
let color = WI.Color.fromString(string);
color.format = WI.Color.Format.Original;
@@ -250,7 +250,7 @@
WI.Color.Format.HEXAlpha,
]);
- resolve();
+ return true;
}
});
@@ -257,7 +257,7 @@
suite.addTestCase({
name: "WI.Color.prototype.toString",
description: "Test the different toString outputs.",
- test(resolve, reject) {
+ test() {
let color;
function test(expected, format) {
let pass = color.toString(format) === expected;
@@ -288,13 +288,13 @@
test("#64c8ff80", WI.Color.Format.HEXAlpha);
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.RGB); // fallback (rgba)
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.RGBA);
- test("hsla(201, 100%, 70%, 0.5)", WI.Color.Format.HSL); // fallback (hsla)
- test("hsla(201, 100%, 70%, 0.5)", WI.Color.Format.HSLA);
+ test("hsla(201.29, 100%, 69.61%, 0.5)", WI.Color.Format.HSL); // fallback (hsla)
+ test("hsla(201.29, 100%, 69.61%, 0.5)", WI.Color.Format.HSLA);
// FIXME: Should we clamp rgb(300, 300, 300) => rgb(255, 255, 255) in toStrings?
// FIXME: Should we always stash the original string, no matter how poor?
- resolve();
+ return true;
}
});
@@ -304,28 +304,47 @@
}
suite.addTestCase({
- name: "WI.Color.rgb2hsv",
- description: "Test conversion from RGB to HSV.",
- test(resolve, reject) {
- testColorConversion(WI.Color.rgb2hsv, [0, 0, 0], [0, 0, 0]);
- testColorConversion(WI.Color.rgb2hsv, [255, 255, 255], [0, 0, 1]);
- testColorConversion(WI.Color.rgb2hsv, [255, 0, 0], [0, 1, 1]);
- testColorConversion(WI.Color.rgb2hsv, [0, 255, 0], [120, 1, 1]);
- testColorConversion(WI.Color.rgb2hsv, [0, 0, 255], [240, 1, 1]);
+ name: "WI.Color.rgb2hsl",
+ description: "Test conversion from RGB to HSL.",
+ test() {
+ testColorConversion(WI.Color.rgb2hsl, [0, 0, 0], [0, 0, 0]);
+ testColorConversion(WI.Color.rgb2hsl, [255, 255, 255], [0, 0, 100]);
+ testColorConversion(WI.Color.rgb2hsl, [255, 0, 0], [0, 100, 50]);
+ testColorConversion(WI.Color.rgb2hsl, [0, 255, 0], [120, 100, 50]);
+ testColorConversion(WI.Color.rgb2hsl, [0, 0, 255], [240, 100, 50]);
// Out-of-bounds and floating point inputs.
- testColorConversion(WI.Color.rgb2hsv, [-1, -1, -1], [0, 0, 0]);
- testColorConversion(WI.Color.rgb2hsv, [256, 256, 256], [0, 0, 1]);
- testColorConversion(WI.Color.rgb2hsv, [254.9, 0, 0], [0, 1, 1]);
+ testColorConversion(WI.Color.rgb2hsl, [-1, -1, -1], [0, 0, 0]);
+ testColorConversion(WI.Color.rgb2hsl, [256, 256, 256], [0, 0, 100]);
+ testColorConversion(WI.Color.rgb2hsl, [254.9, 0, 0], [0, 100, 50]);
- resolve();
+ return true;
}
});
suite.addTestCase({
+ name: "WI.Color.hsl2rgb",
+ description: "Test conversion from HSL to RGB.",
+ test() {
+ testColorConversion(WI.Color.hsl2rgb, [0, 0, 0], [0, 0, 0]);
+ testColorConversion(WI.Color.hsl2rgb, [0, 0, 100], [255, 255, 255]);
+ testColorConversion(WI.Color.hsl2rgb, [0, 100, 50], [255, 0, 0]);
+ testColorConversion(WI.Color.hsl2rgb, [120, 100, 50], [0, 255, 0]);
+ testColorConversion(WI.Color.hsl2rgb, [240, 100, 50], [0, 0, 255]);
+
+ // Out-of-bounds.
+ testColorConversion(WI.Color.hsl2rgb, [-1, -1, -1], [0, 0, 0]);
+ testColorConversion(WI.Color.hsl2rgb, [361, 101, 50], [255, 0, 0]);
+ testColorConversion(WI.Color.hsl2rgb, [361, 101, 101], [255, 255, 255]);
+
+ return true;
+ }
+ });
+
+ suite.addTestCase({
name: "WI.Color.cmyk2rgb",
description: "Test conversion from CMYK to RGB.",
- test(resolve, reject) {
+ test() {
testColorConversion(WI.Color.cmyk2rgb, [0, 0, 0, 1], [0, 0, 0]);
testColorConversion(WI.Color.cmyk2rgb, [1, 0, 0, 0], [0, 255, 255]);
testColorConversion(WI.Color.cmyk2rgb, [0, 1, 0, 0], [255, 0, 255]);
@@ -336,7 +355,7 @@
testColorConversion(WI.Color.cmyk2rgb, [2, 0, 0, 0], [0, 255, 255]);
testColorConversion(WI.Color.cmyk2rgb, [-1, 0, 0, 0], [255, 255, 255]);
- resolve();
+ return true;
}
});
@@ -343,7 +362,7 @@
suite.addTestCase({
name: "WI.Color.normalized2rgb",
description: "Test conversion from normalized RGB to RGB.",
- test(resolve, reject) {
+ test() {
testColorConversion(WI.Color.normalized2rgb, [0, 0, 0], [0, 0, 0]);
testColorConversion(WI.Color.normalized2rgb, [1, 1, 1], [255, 255, 255]);
testColorConversion(WI.Color.normalized2rgb, [0.24, 0.25, 0.26], [61, 64, 66]); // Values chosen to test round up/down behavior.
@@ -352,7 +371,7 @@
testColorConversion(WI.Color.normalized2rgb, [2, 0, 0], [255, 0, 0]);
testColorConversion(WI.Color.normalized2rgb, [-1, 0, 0], [0, 0, 0]);
- resolve();
+ return true;
}
});
Modified: trunk/Source/WebInspectorUI/ChangeLog (239596 => 239597)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-01-03 21:58:23 UTC (rev 239597)
@@ -1,3 +1,56 @@
+2019-01-03 Devin Rousso <[email protected]>
+
+ Web Inspector: conic-gradient color picker doesn't accurately show color when saturation value is not 100%
+ https://bugs.webkit.org/show_bug.cgi?id=192729
+ <rdar://problem/46746815>
+
+ Reviewed by Joseph Pecoraro.
+
+ Rework `WI.ColorWheel` to use similar canvas drawing logic as `WI.LegacyColorWheel` so that
+ it's able to adjust the saturation value as the pixels gets closer to the center.
+
+ * UserInterface/Models/Color.js:
+ (WI.Color.rgb2hsl): Added.
+ (WI.Color.hsl2rgb): Added.
+ (WI.Color.cmyk2rgb):
+ (WI.Color.prototype.isKeyword):
+ (WI.Color.prototype._toRGBString):
+ (WI.Color.prototype._toRGBAString):
+ (WI.Color.prototype._toHSLString):
+ (WI.Color.prototype._toHSLAString):
+ (WI.Color.prototype._rgbaToHSLA):
+ (WI.Color.prototype._hslaToRGBA):
+ (WI.Color.rgb2hsv): Deleted.
+ (WI.Color.hsv2rgb): Deleted.
+ (WI.Color.prototype._rgbToHSL): Deleted.
+ (WI.Color.prototype._hslToRGB): Deleted.
+ Adjust the conversion functions of `WI.Color` to be more accurate.
+
+ * UserInterface/Views/ColorWheel.js:
+ (WI.ColorWheel):
+ (WI.ColorWheel.prototype.set dimension):
+ (WI.ColorWheel.prototype.set brightness):
+ (WI.ColorWheel.prototype.get tintedColor):
+ (WI.ColorWheel.prototype.set tintedColor):
+ (WI.ColorWheel.prototype._updateColorForMouseEvent):
+ (WI.ColorWheel.prototype._updateCanvas): Added.
+ (WI.ColorWheel.prototype._updateGradient): Deleted.
+ * UserInterface/Views/ColorWheel.css:
+ (.color-wheel > canvas): Added.
+ (.color-wheel > .gradient): Deleted.
+
+ * UserInterface/Views/ColorPicker.js:
+ (WI.ColorPicker):
+ (WI.ColorPicker.prototype.set color):
+ (WI.ColorPicker.prototype.sliderValueDidChange):
+ (WI.ColorPicker.prototype._updateSliders):
+ (WI.ColorPicker.prototype._showColorComponentInputs):
+ (WI.ColorPicker.supportsConicGradient): Deleted.
+
+ * UserInterface/Main.html:
+
+ * UserInterface/Views/LegacyColorWheel.js: Removed.
+
2019-01-02 Nikita Vasilyev <[email protected]>
Web Inspector: Styles: selection lost when inspector is blurred
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (239596 => 239597)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2019-01-03 21:58:23 UTC (rev 239597)
@@ -814,8 +814,6 @@
<script src=""
<script src=""
- <script src=""
-
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Color.js (239596 => 239597)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Color.js 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Color.js 2019-01-03 21:58:23 UTC (rev 239597)
@@ -155,19 +155,19 @@
return null;
}
- static rgb2hsv(r, g, b)
+ static rgb2hsl(r, g, b)
{
r = WI.Color._eightBitChannel(r) / 255;
g = WI.Color._eightBitChannel(g) / 255;
b = WI.Color._eightBitChannel(b) / 255;
- let min = Math.min(Math.min(r, g), b);
- let max = Math.max(Math.max(r, g), b);
+ let min = Math.min(r, g, b);
+ let max = Math.max(r, g, b);
let delta = max - min;
- let h;
- let s;
- let v = max;
+ let h = 0;
+ let s = 0;
+ let l = (max + min) / 2;
if (delta === 0)
h = 0;
@@ -182,50 +182,57 @@
h += 360;
// Saturation
- if (max === 0)
+ if (delta === 0)
s = 0;
else
- s = 1 - (min / max);
+ s = delta / (1 - Math.abs((2 * l) - 1));
- return [h, s, v];
+ return [
+ h,
+ s * 100,
+ l * 100,
+ ];
}
- static hsv2rgb(h, s, v)
+ static hsl2rgb(h, s, l)
{
- if (s === 0)
- return [v, v, v];
+ h = Number.constrain(h, 0, 360) % 360;
+ s = Number.constrain(s, 0, 100) / 100;
+ l = Number.constrain(l, 0, 100) / 100;
- h /= 60;
- let i = Math.floor(h);
- let data = [
- v * (1 - s),
- v * (1 - s * (h - i)),
- v * (1 - s * (1 - (h - i)))
- ];
- let rgb;
+ let c = (1 - Math.abs((2 * l) - 1)) * s;
+ let x = c * (1 - Math.abs(((h / 60) % 2) - 1));
+ let m = l - (c / 2);
- switch (i) {
- case 0:
- rgb = [v, data[2], data[0]];
- break;
- case 1:
- rgb = [data[1], v, data[0]];
- break;
- case 2:
- rgb = [data[0], v, data[2]];
- break;
- case 3:
- rgb = [data[0], data[1], v];
- break;
- case 4:
- rgb = [data[2], data[0], v];
- break;
- default:
- rgb = [v, data[0], data[1]];
- break;
+ let r = 0;
+ let g = 0;
+ let b = 0;
+
+ if (h < 60) {
+ r = c;
+ g = x;
+ } else if (h < 120) {
+ r = x;
+ g = c;
+ } else if (h < 180) {
+ g = c;
+ b = x;
+ } else if (h < 240) {
+ g = x;
+ b = c;
+ } else if (h < 300) {
+ r = x;
+ b = c;
+ } else if (h < 360) {
+ r = c;
+ b = x;
}
- return rgb;
+ return [
+ (r + m) * 255,
+ (g + m) * 255,
+ (b + m) * 255,
+ ];
}
static cmyk2rgb(c, m, y, k)
@@ -234,11 +241,11 @@
m = Number.constrain(m, 0, 1);
y = Number.constrain(y, 0, 1);
k = Number.constrain(k, 0, 1);
-
- let r = 255 - ((Math.min(1, c * (1 - k) + k)) * 255);
- let g = 255 - ((Math.min(1, m * (1 - k) + k)) * 255);
- let b = 255 - ((Math.min(1, y * (1 - k) + k)) * 255);
- return [r, g, b];
+ return [
+ 255 * (1 - c) * (1 - k),
+ 255 * (1 - m) * (1 - k),
+ 255 * (1 - y) * (1 - k),
+ ];
}
static normalized2rgb(r, g, b)
@@ -391,7 +398,7 @@
if (!this.simple)
return Array.shallowEqual(this._rgba, [0, 0, 0, 0]) || Array.shallowEqual(this._hsla, [0, 0, 0, 0]);
- let rgb = (this._rgba && this._rgba.slice(0, 3)) || this._hslToRGB(this._hsla);
+ let rgb = (this._rgba && this._rgba.slice(0, 3)) || WI.Color.hsl2rgb(...this._hsla);
return Object.keys(WI.Color.Keywords).some(key => Array.shallowEqual(WI.Color.Keywords[key], rgb));
}
@@ -511,17 +518,17 @@
if (!this.simple)
return this._toRGBAString();
- let r = WI.Color._eightBitChannel(this.rgb[0]);
- let g = WI.Color._eightBitChannel(this.rgb[1]);
- let b = WI.Color._eightBitChannel(this.rgb[2]);
+ let r = WI.Color._eightBitChannel(Math.round(this.rgba[0]));
+ let g = WI.Color._eightBitChannel(Math.round(this.rgba[1]));
+ let b = WI.Color._eightBitChannel(Math.round(this.rgba[2]));
return `rgb(${r}, ${g}, ${b})`;
}
_toRGBAString()
{
- let r = WI.Color._eightBitChannel(this.rgb[0]);
- let g = WI.Color._eightBitChannel(this.rgb[1]);
- let b = WI.Color._eightBitChannel(this.rgb[2]);
+ let r = WI.Color._eightBitChannel(Math.round(this.rgba[0]));
+ let g = WI.Color._eightBitChannel(Math.round(this.rgba[1]));
+ let b = WI.Color._eightBitChannel(Math.round(this.rgba[2]));
return `rgba(${r}, ${g}, ${b}, ${this.alpha})`;
}
@@ -530,16 +537,18 @@
if (!this.simple)
return this._toHSLAString();
- let hsla = this.hsla;
- hsla = hsla.map((value) => value.maxDecimals(2));
- return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
+ let h = this.hsla[0].maxDecimals(2);
+ let s = this.hsla[1].maxDecimals(2);
+ let l = this.hsla[2].maxDecimals(2);
+ return `hsl(${h}, ${s}%, ${l}%)`;
}
_toHSLAString()
{
- let hsla = this.hsla;
- hsla = hsla.map((value) => value.maxDecimals(2));
- return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")";
+ let h = this.hsla[0].maxDecimals(2);
+ let s = this.hsla[1].maxDecimals(2);
+ let l = this.hsla[2].maxDecimals(2);
+ return `hsla(${h}, ${s}%, ${l}%, ${this.alpha})`;
}
_componentToHexValue(value)
@@ -550,77 +559,16 @@
return hex;
}
- _rgbToHSL(rgb)
- {
- let r = WI.Color._eightBitChannel(rgb[0]) / 255;
- let g = WI.Color._eightBitChannel(rgb[1]) / 255;
- let b = WI.Color._eightBitChannel(rgb[2]) / 255;
- let max = Math.max(r, g, b);
- let min = Math.min(r, g, b);
- let diff = max - min;
- let add = max + min;
-
- let h;
- let s;
- let l = 0.5 * add;
-
- if (min === max)
- h = 0;
- else if (r === max)
- h = ((60 * (g - b) / diff) + 360) % 360;
- else if (g === max)
- h = (60 * (b - r) / diff) + 120;
- else
- h = (60 * (r - g) / diff) + 240;
-
- if (l === 0)
- s = 0;
- else if (l === 1)
- s = 1;
- else if (l <= 0.5)
- s = diff / add;
- else
- s = diff / (2 - add);
-
- return [
- Math.round(h),
- Math.round(s * 100),
- Math.round(l * 100)
- ];
- }
-
- _hslToRGB(hsl)
- {
- let h = parseFloat(hsl[0]) / 360;
- let s = parseFloat(hsl[1]) / 100;
- let l = parseFloat(hsl[2]) / 100;
-
- h *= 6;
- let sArray = [
- l += s *= l < .5 ? l : 1 - l,
- l - h % 1 * s * 2,
- l -= s *= 2,
- l,
- l + h % 1 * s,
- l + s
- ];
- return [
- Math.round(sArray[ ~~h % 6 ] * 255),
- Math.round(sArray[ (h | 16) % 6 ] * 255),
- Math.round(sArray[ (h | 8) % 6 ] * 255)
- ];
- }
-
_rgbaToHSLA(rgba)
{
- let hsl = this._rgbToHSL(rgba);
- hsl.push(rgba[3]);
- return hsl;
+ let hsla = WI.Color.rgb2hsl(...rgba);
+ hsla.push(rgba[3]);
+ return hsla;
}
_hslaToRGBA(hsla)
{
- let rgba = this._hslToRGB(hsla);
+ let rgba = WI.Color.hsl2rgb(...hsla);
rgba.push(hsla[3]);
return rgba;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js (239596 => 239597)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js 2019-01-03 21:58:23 UTC (rev 239597)
@@ -29,9 +29,7 @@
{
super();
- this._colorWheel = WI.ColorPicker.supportsConicGradient() ? new WI.ColorWheel : new WI.LegacyColorWheel;
- this._colorWheel.delegate = this;
- this._colorWheel.dimension = 200;
+ this._colorWheel = new WI.ColorWheel(this, 200);
this._brightnessSlider = new WI.Slider;
this._brightnessSlider.delegate = this;
@@ -90,24 +88,6 @@
this._enableColorComponentInputs = true;
}
- // Static
-
- static supportsConicGradient()
- {
- if (WI.ColorPicker._supportsConicGradient === undefined) {
- const property = "background-image";
- const conicGradient = "conic-gradient(black, white)";
-
- let element = document.body.appendChild(document.createElement("div"));
- element.style.setProperty(property, conicGradient);
-
- WI.ColorPicker._supportsConicGradient = window.getComputedStyle(element).getPropertyValue(property).includes(conicGradient);
-
- element.remove();
- }
- return WI.ColorPicker._supportsConicGradient;
- }
-
// Public
get element()
@@ -156,7 +136,7 @@
this._color = color;
this._colorWheel.tintedColor = this._color;
- this._brightnessSlider.value = this._colorWheel.brightness;
+ this._brightnessSlider.value = this._colorWheel.brightness / 100;
this._opacitySlider.value = this._color.alpha;
this._updateSliders(this._colorWheel.rawColor, this._color);
@@ -187,7 +167,7 @@
if (slider === this._opacitySlider)
this.opacity = value;
else if (slider === this._brightnessSlider)
- this.brightness = value;
+ this.brightness = value * 100;
}
// Private
@@ -229,12 +209,7 @@
var opaque = new WI.Color(WI.Color.Format.RGBA, rgb.concat(1)).toString();
var transparent = new WI.Color(WI.Color.Format.RGBA, rgb.concat(0)).toString();
- let brightnessGradient = "";
- if (WI.ColorPicker.supportsConicGradient())
- brightnessGradient = `linear-gradient(90deg, black, ${rawColor}, white)`;
- else
- brightnessGradient = `linear-gradient(90deg, black, ${rawColor})`;
- this._brightnessSlider.element.style.setProperty("background-image", brightnessGradient);
+ this._brightnessSlider.element.style.setProperty("background-image", `linear-gradient(90deg, black, ${rawColor}, white)`);
this._opacitySlider.element.style.setProperty("background-image", "linear-gradient(90deg, " + transparent + ", " + opaque + "), " + this._opacityPattern);
}
@@ -277,17 +252,17 @@
case WI.Color.Format.ShortHEXAlpha:
case WI.Color.Format.Keyword:
var [r, g, b] = this._color.rgb;
- updateColorInput.call(this, "R", r);
- updateColorInput.call(this, "G", g);
- updateColorInput.call(this, "B", b);
+ updateColorInput.call(this, "R", Math.round(r));
+ updateColorInput.call(this, "G", Math.round(g));
+ updateColorInput.call(this, "B", Math.round(b));
break;
case WI.Color.Format.HSL:
case WI.Color.Format.HSLA:
var [h, s, l] = this._color.hsl;
- updateColorInput.call(this, "H", h);
- updateColorInput.call(this, "S", s);
- updateColorInput.call(this, "L", l);
+ updateColorInput.call(this, "H", h.maxDecimals(2));
+ updateColorInput.call(this, "S", s.maxDecimals(2));
+ updateColorInput.call(this, "L", l.maxDecimals(2));
break;
default:
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.css (239596 => 239597)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.css 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.css 2019-01-03 21:58:23 UTC (rev 239597)
@@ -27,10 +27,9 @@
position: relative;
}
-.color-wheel > .gradient {
+.color-wheel > canvas {
width: 100%;
height: 100%;
- border-radius: 50%;
}
.color-wheel > .crosshair {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js (239596 => 239597)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js 2019-01-03 21:58:23 UTC (rev 239597)
@@ -25,21 +25,28 @@
WI.ColorWheel = class ColorWheel extends WI.Object
{
- constructor()
+ constructor(delegate, dimension)
{
+ console.assert(!isNaN(dimension));
+
super();
- this._brightness = 0.5;
+ this._delegate = delegate;
+ this._brightness = 50;
+
this._element = document.createElement("div");
this._element.className = "color-wheel";
- this._gradientElement = this._element.appendChild(document.createElement("div"));
- this._gradientElement.classList.add("gradient");
- this._gradientElement.addEventListener("mousedown", this);
+ this._canvasElement = this._element.appendChild(document.createElement("canvas"));
+ this._canvasElement.addEventListener("mousedown", this);
+ this._canvasContext = this._canvasElement.getContext("2d");
+
this._crosshairElement = this._element.appendChild(document.createElement("div"));
this._crosshairElement.className = "crosshair";
+
+ this.dimension = dimension;
}
// Public
@@ -48,14 +55,18 @@
set dimension(dimension)
{
+ if (dimension === this._dimension)
+ return;
+
this._dimension = dimension;
this._element.style.width = this.element.style.height = `${this._dimension}px`;
+ this._canvasElement.width = this._canvasElement.height = this._dimension * window.devicePixelRatio;
let center = this._dimension / 2;
this._setCrosshairPosition(new WI.Point(center, center));
- this._updateGradient();
+ this._updateCanvas();
}
get brightness()
@@ -65,14 +76,18 @@
set brightness(brightness)
{
+ if (brightness === this._brightness)
+ return;
+
this._brightness = brightness;
- this._updateGradient();
+
+ this._updateCanvas();
}
get tintedColor()
{
if (this._crosshairPosition)
- return new WI.Color(WI.Color.Format.HSL, [this._hue, this._saturation, this._brightness * 100]);
+ return new WI.Color(WI.Color.Format.HSL, [this._hue, this._saturation, this._brightness]);
return new WI.Color(WI.Color.Format.HSLA, [0, 0, 0, 0]);
}
@@ -87,7 +102,7 @@
let y = center - (cosHue * hsl[1]);
this._setCrosshairPosition(new WI.Point(x, y));
- this.brightness = hsl[2] / 100;
+ this.brightness = hsl[2];
}
get rawColor()
@@ -154,12 +169,12 @@
_updateColorForMouseEvent(event)
{
- var point = window.webkitConvertPointFromPageToNode(this._gradientElement, new WebKitPoint(event.pageX, event.pageY));
+ var point = window.webkitConvertPointFromPageToNode(this._canvasElement, new WebKitPoint(event.pageX, event.pageY));
this._setCrosshairPosition(point);
- if (this.delegate && typeof this.delegate.colorWheelColorDidChange === "function")
- this.delegate.colorWheelColorDidChange(this);
+ if (this._delegate && typeof this._delegate.colorWheelColorDidChange === "function")
+ this._delegate.colorWheelColorDidChange(this);
}
_setCrosshairPosition(point)
@@ -177,12 +192,34 @@
this._crosshairElement.style.setProperty("transform", "translate(" + Math.round(point.x) + "px, " + Math.round(point.y) + "px)");
}
- _updateGradient()
+ _updateCanvas()
{
- let stops = [];
- for (let i = 0; i <= 360; i += 60)
- stops.push(`hsl(${i}, 100%, ${this._brightness * 100}%)`);
+ let dimension = this._dimension * window.devicePixelRatio;
+ let center = dimension / 2;
- this._gradientElement.style.setProperty("background-image", `conic-gradient(${stops.join(",")})`);
+ let imageData = this._canvasContext.createImageData(dimension, dimension);
+ for (let y = 0; y < dimension; ++y) {
+ for (let x = 0; x < dimension; ++x) {
+ let xDis = (x - center) / center;
+ let yDis = (y - center) / center;
+ let saturation = Math.sqrt(Math.pow(xDis, 2) + Math.pow(yDis, 2)) * 100;
+ if (saturation > 100)
+ continue;
+
+ let hue = Math.atan2(x - center, center - y) * 180 / Math.PI;
+ if (hue < 0)
+ hue += 360;
+
+ let rgb = WI.Color.hsl2rgb(hue, saturation, this._brightness);
+
+ let index = ((y * dimension) + x) * 4;
+ imageData.data[index] = rgb[0];
+ imageData.data[index + 1] = rgb[1];
+ imageData.data[index + 2] = rgb[2];
+ imageData.data[index + 3] = 255;
+ }
+ }
+
+ this._canvasContext.putImageData(imageData, 0, 0);
}
};
Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/LegacyColorWheel.js (239596 => 239597)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LegacyColorWheel.js 2019-01-03 18:20:57 UTC (rev 239596)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LegacyColorWheel.js 2019-01-03 21:58:23 UTC (rev 239597)
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-WI.LegacyColorWheel = class LegacyColorWheel extends WI.Object
-{
- constructor()
- {
- super();
-
- this._rawCanvas = document.createElement("canvas");
- this._tintedCanvas = document.createElement("canvas");
- this._finalCanvas = document.createElement("canvas");
-
- this._crosshair = document.createElement("div");
- this._crosshair.className = "crosshair";
-
- this._element = document.createElement("div");
- this._element.className = "color-wheel";
-
- this._element.appendChild(this._finalCanvas);
- this._element.appendChild(this._crosshair);
-
- this._finalCanvas.addEventListener("mousedown", this);
- }
-
- // Public
-
- set dimension(dimension)
- {
- this._element.style.width = this.element.style.height = `${dimension}px`;
-
- this._finalCanvas.width = this._tintedCanvas.width = this._rawCanvas.width = dimension * window.devicePixelRatio;
- this._finalCanvas.height = this._tintedCanvas.height = this._rawCanvas.height = dimension * window.devicePixelRatio;
-
- this._finalCanvas.style.width = this._finalCanvas.style.height = dimension + "px";
-
- this._dimension = dimension;
- // We shrink the radius a bit for better anti-aliasing.
- this._radius = dimension / 2 - 2;
-
- this._setCrosshairPosition(new WI.Point(dimension / 2, dimension / 2));
-
- this._drawRawCanvas();
- this._draw();
- }
-
- get element()
- {
- return this._element;
- }
-
- get brightness()
- {
- return this._brightness;
- }
-
- set brightness(brightness)
- {
- this._brightness = brightness;
- this._draw();
- }
-
- get tintedColor()
- {
- if (this._crosshairPosition)
- return this._colorAtPointWithBrightness(this._crosshairPosition.x * window.devicePixelRatio, this._crosshairPosition.y * window.devicePixelRatio, this._brightness);
-
- return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
- }
-
- set tintedColor(tintedColor)
- {
- var data = ""
- this._setCrosshairPosition(data.point);
- this.brightness = data.brightness;
- }
-
- get rawColor()
- {
- if (this._crosshairPosition)
- return this._colorAtPointWithBrightness(this._crosshairPosition.x * window.devicePixelRatio, this._crosshairPosition.y * window.devicePixelRatio, 1);
-
- return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
- }
-
- // Protected
-
- handleEvent(event)
- {
- switch (event.type) {
- case "mousedown":
- this._handleMousedown(event);
- break;
- case "mousemove":
- this._handleMousemove(event);
- break;
- case "mouseup":
- this._handleMouseup(event);
- break;
- }
- }
-
- // Private
-
- _handleMousedown(event)
- {
- window.addEventListener("mousemove", this, true);
- window.addEventListener("mouseup", this, true);
-
- this._updateColorForMouseEvent(event);
- }
-
- _handleMousemove(event)
- {
- this._updateColorForMouseEvent(event);
- }
-
- _handleMouseup(event)
- {
- window.removeEventListener("mousemove", this, true);
- window.removeEventListener("mouseup", this, true);
- }
-
- _pointInCircleForEvent(event)
- {
- function distance(a, b)
- {
- return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
- }
-
- function angleFromCenterToPoint(center, point)
- {
- return Math.atan2(point.y - center.y, point.x - center.x);
- }
-
- function pointOnCircumference(c, r, a)
- {
- return new WI.Point(c.x + r * Math.cos(a), c.y + r * Math.sin(a));
- }
-
- var dimension = this._dimension;
- var point = window.webkitConvertPointFromPageToNode(this._finalCanvas, new WebKitPoint(event.pageX, event.pageY));
- var center = new WI.Point(dimension / 2, dimension / 2);
- if (distance(point, center) > this._radius) {
- var angle = angleFromCenterToPoint(center, point);
- point = pointOnCircumference(center, this._radius, angle);
- }
- return point;
- }
-
- _updateColorForMouseEvent(event)
- {
- var point = this._pointInCircleForEvent(event);
-
- this._setCrosshairPosition(point);
-
- if (this.delegate && typeof this.delegate.colorWheelColorDidChange === "function")
- this.delegate.colorWheelColorDidChange(this);
- }
-
- _setCrosshairPosition(point)
- {
- this._crosshairPosition = point;
- this._crosshair.style.webkitTransform = "translate(" + Math.round(point.x) + "px, " + Math.round(point.y) + "px)";
- }
-
- _tintedColorToPointAndBrightness(color)
- {
- var rgb = color.rgb;
- var hsv = WI.Color.rgb2hsv(rgb[0], rgb[1], rgb[2]);
- var cosHue = Math.cos(hsv[0] * Math.PI / 180);
- var sinHue = Math.sin(hsv[0] * Math.PI / 180);
- var center = this._dimension / 2;
- var x = center + (center * cosHue * hsv[1]);
- var y = center - (center * sinHue * hsv[1]);
- return {
- point: new WI.Point(x, y),
- brightness: hsv[2]
- };
- }
-
- _drawRawCanvas() {
- var ctx = this._rawCanvas.getContext("2d");
-
- var dimension = this._dimension * window.devicePixelRatio;
-
- ctx.fillStyle = "white";
- ctx.fillRect(0, 0, dimension, dimension);
-
- var imageData = ctx.getImageData(0, 0, dimension, dimension);
- var data = ""
- for (var j = 0; j < dimension; ++j) {
- for (var i = 0; i < dimension; ++i) {
- var color = this._colorAtPointWithBrightness(i, j, 1);
- if (!color)
- continue;
- var pos = (j * dimension + i) * 4;
- data[pos] = color.rgb[0];
- data[pos + 1] = color.rgb[1];
- data[pos + 2] = color.rgb[2];
- }
- }
- ctx.putImageData(imageData, 0, 0);
- }
-
- _colorAtPointWithBrightness(x, y, brightness)
- {
- var center = this._dimension / 2 * window.devicePixelRatio;
- var xDis = x - center;
- var yDis = y - center;
- var distance = Math.sqrt(xDis * xDis + yDis * yDis);
-
- if (distance - center > 0.001)
- return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
-
- var h = Math.atan2(y - center, center - x) * 180 / Math.PI;
- h = (h + 180) % 360;
- var v = brightness;
- var s = Math.max(0, distance) / center;
-
- var rgb = WI.Color.hsv2rgb(h, s, v);
- return new WI.Color(WI.Color.Format.RGBA, [
- Math.round(rgb[0] * 255),
- Math.round(rgb[1] * 255),
- Math.round(rgb[2] * 255),
- 1
- ]);
- }
-
- _drawTintedCanvas()
- {
- var ctx = this._tintedCanvas.getContext("2d");
- var dimension = this._dimension * window.devicePixelRatio;
-
- ctx.save();
- ctx.drawImage(this._rawCanvas, 0, 0, dimension, dimension);
- if (this._brightness !== 1) {
- ctx.globalAlpha = 1 - this._brightness;
- ctx.fillStyle = "black";
- ctx.fillRect(0, 0, dimension, dimension);
- }
- ctx.restore();
- }
-
- _draw()
- {
- this._drawTintedCanvas();
-
- var ctx = this._finalCanvas.getContext("2d");
- var dimension = this._dimension * window.devicePixelRatio;
- var radius = this._radius * window.devicePixelRatio;
-
- ctx.save();
- ctx.clearRect(0, 0, dimension, dimension);
- ctx.beginPath();
- ctx.arc(dimension / 2, dimension / 2, radius + 1, 0, Math.PI * 2, true);
- ctx.closePath();
- ctx.clip();
- ctx.drawImage(this._tintedCanvas, 0, 0, dimension, dimension);
- ctx.restore();
- }
-};