Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (287408 => 287409)
--- trunk/Source/WebInspectorUI/ChangeLog 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/ChangeLog 2021-12-23 20:54:21 UTC (rev 287409)
@@ -1,5 +1,51 @@
2021-12-23 Tim Nguyen <n...@apple.com>
+ Web Inspector: Support conic gradients in gradient editor and autocompletion
+ https://bugs.webkit.org/show_bug.cgi?id=234562
+
+ Reviewed by Devin Rousso.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Controllers/CSSManager.js:
+ * UserInterface/Models/Gradient.js:
+ (WI.Gradient.angleFromString):
+ (WI.Gradient.fromString):
+ (WI.Gradient.prototype.get angleValue):
+ (WI.Gradient.prototype.set angleValue):
+ (WI.Gradient.prototype.get angleUnits):
+ (WI.Gradient.prototype.set angleUnits):
+ (WI.Gradient.prototype._angleValueForUnits):
+ (WI.Gradient):
+ (WI.LinearGradient.fromComponents):
+ (WI.LinearGradient.prototype.toString):
+ (WI.LinearGradient):
+ (WI.RadialGradient):
+ (WI.RadialGradient.fromComponents):
+ (WI.RadialGradient.prototype.get angleValue):
+ (WI.RadialGradient.prototype.set angleValue):
+ (WI.RadialGradient.prototype.get angleUnits):
+ (WI.RadialGradient.prototype.set angleUnits):
+ (WI.RadialGradient.prototype.copy):
+ (WI.RadialGradient.prototype.toString):
+ (WI.ConicGradient):
+ (WI.ConicGradient.fromComponents):
+ (WI.ConicGradient.prototype.copy):
+ (WI.ConicGradient.prototype.toString):
+ (WI.LinearGradient.prototype.set angleValue): Deleted.
+ (WI.LinearGradient.prototype.get angleValue): Deleted.
+ (WI.LinearGradient.prototype.set angleUnits): Deleted.
+ (WI.LinearGradient.prototype.get angleUnits): Deleted.
+ (WI.LinearGradient.prototype._angleValueForUnits): Deleted.
+ * UserInterface/Views/CodeMirrorTextMarkers.js:
+ * UserInterface/Views/GradientEditor.js:
+ (WI.GradientEditor):
+ (WI.GradientEditor.prototype.set gradient):
+ (WI.GradientEditor.prototype._gradientTypeChanged):
+ * UserInterface/Views/SpreadsheetStyleProperty.js:
+ (WI.SpreadsheetStyleProperty.prototype._addGradientTokens):
+
+2021-12-23 Tim Nguyen <n...@apple.com>
+
Web Inspector: Dark mode: Make gradient editor angle input readable in dark mode
https://bugs.webkit.org/show_bug.cgi?id=234640
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (287408 => 287409)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-12-23 20:54:21 UTC (rev 287409)
@@ -367,6 +367,7 @@
localizedStrings["Connection Closed"] = "Connection Closed";
localizedStrings["Connection ID"] = "Connection ID";
localizedStrings["Connection:"] = "Connection:";
+localizedStrings["Conic Gradient"] = "Conic Gradient";
localizedStrings["Console"] = "Console";
localizedStrings["Console Evaluation"] = "Console Evaluation";
localizedStrings["Console Evaluation %d"] = "Console Evaluation %d";
@@ -1183,6 +1184,7 @@
localizedStrings["Rendering Frames"] = "Rendering Frames";
localizedStrings["Repeating Linear Gradient"] = "Repeating Linear Gradient";
localizedStrings["Repeating Radial Gradient"] = "Repeating Radial Gradient";
+localizedStrings["Repeating Conic Gradient"] = "Repeating Conic Gradient";
localizedStrings["Request"] = "Request";
localizedStrings["Request & Response"] = "Request & Response";
localizedStrings["Request (DOM Tree)"] = "Request (DOM Tree)";
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js (287408 => 287409)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js 2021-12-23 20:54:21 UTC (rev 287409)
@@ -111,6 +111,10 @@
for (let color of WI.CSSKeywordCompletions._colors)
colorKeywordsForCodeMirror[nameForCodeMirror(color)] = true;
+ // TODO: Remove these keywords once they are built-in codemirror or once we get values from WebKit itself.
+ valueKeywordsForCodeMirror["conic-gradient"] = true;
+ valueKeywordsForCodeMirror["repeating-conic-gradient"] = true;
+
function updateCodeMirrorCSSMode(mimeType) {
let modeSpec = CodeMirror.resolveMode(mimeType);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Gradient.js (287408 => 287409)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Gradient.js 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Gradient.js 2021-12-23 20:54:21 UTC (rev 287409)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,15 +33,26 @@
// Static
+ static angleFromString(string)
+ {
+ let match = string.match(/([-\d\.]+)(\w+)/);
+ if (!match || !Object.values(WI.Gradient.AngleUnits).includes(match[2]))
+ return null;
+
+ return {value: parseFloat(match[1]), units: match[2]};
+ }
+
static fromString(cssString)
{
var type;
var openingParenthesisIndex = cssString.indexOf("(");
var typeString = cssString.substring(0, openingParenthesisIndex);
- if (typeString.indexOf(WI.Gradient.Types.Linear) !== -1)
+ if (typeString.includes(WI.Gradient.Types.Linear))
type = WI.Gradient.Types.Linear;
- else if (typeString.indexOf(WI.Gradient.Types.Radial) !== -1)
+ else if (typeString.includes(WI.Gradient.Types.Radial))
type = WI.Gradient.Types.Radial;
+ else if (typeString.includes(WI.Gradient.Types.Conic))
+ type = WI.Gradient.Types.Conic;
else
return null;
@@ -88,12 +99,21 @@
if (openParentheses !== -1)
return null;
- var gradient;
- if (type === WI.Gradient.Types.Linear)
+ let gradient = null;
+ switch (type) {
+ case WI.Gradient.Types.Linear:
gradient = WI.LinearGradient.fromComponents(components);
- else
+ break;
+
+ case WI.Gradient.Types.Radial:
gradient = WI.RadialGradient.fromComponents(components);
+ break;
+ case WI.Gradient.Types.Conic:
+ gradient = WI.ConicGradient.fromComponents(components);
+ break;
+ }
+
if (gradient)
gradient.repeats = typeString.startsWith("repeating");
@@ -149,6 +169,30 @@
// Public
+ get angleValue()
+ {
+ return this._angle.value.maxDecimals(2);
+ }
+
+ set angleValue(value)
+ {
+ this._angle.value = value;
+ }
+
+ get angleUnits()
+ {
+ return this._angle.units;
+ }
+
+ set angleUnits(units)
+ {
+ if (units === this._angle.units)
+ return;
+
+ this._angle.value = this._angleValueForUnits(units);
+ this._angle.units = units;
+ }
+
copy()
{
// Implemented by subclasses.
@@ -158,13 +202,65 @@
{
// Implemented by subclasses.
}
+
+ // Private
+
+ _angleValueForUnits(units)
+ {
+ if (units === this._angle.units)
+ return this._angle.value;
+
+ let deg = 0;
+
+ switch (this._angle.units) {
+ case WI.Gradient.AngleUnits.DEG:
+ deg = this._angle.value;
+ break;
+
+ case WI.Gradient.AngleUnits.RAD:
+ deg = this._angle.value * 180 / Math.PI;
+ break;
+
+ case WI.Gradient.AngleUnits.GRAD:
+ deg = this._angle.value / 400 * 360;
+ break;
+
+ case WI.Gradient.AngleUnits.TURN:
+ deg = this._angle.value * 360;
+ break;
+ }
+
+ switch (units) {
+ case WI.Gradient.AngleUnits.DEG:
+ return deg;
+
+ case WI.Gradient.AngleUnits.RAD:
+ return deg * Math.PI / 180;
+
+ case WI.Gradient.AngleUnits.GRAD:
+ return deg / 360 * 400;
+
+ case WI.Gradient.AngleUnits.TURN:
+ return deg / 360;
+ }
+
+ return 0;
+ }
};
WI.Gradient.Types = {
Linear: "linear-gradient",
- Radial: "radial-gradient"
+ Radial: "radial-gradient",
+ Conic: "conic-gradient",
};
+WI.Gradient.AngleUnits = {
+ DEG: "deg",
+ RAD: "rad",
+ GRAD: "grad",
+ TURN: "turn",
+};
+
WI.LinearGradient = class LinearGradient extends WI.Gradient
{
constructor(angle, stops)
@@ -177,16 +273,14 @@
static fromComponents(components)
{
- let angle = {value: 180, units: WI.LinearGradient.AngleUnits.DEG};
+ let angle = {value: 180, units: WI.Gradient.AngleUnits.DEG};
if (components[0].length === 1 && !WI.Color.fromString(components[0][0])) {
- let match = components[0][0].match(/([-\d\.]+)(\w+)/);
- if (!match || !Object.values(WI.LinearGradient.AngleUnits).includes(match[2]))
+ angle = WI.Gradient.angleFromString(components[0][0]);
+
+ if (!angle)
return null;
- angle.value = parseFloat(match[1]);
- angle.units = match[2];
-
components.shift();
} else if (components[0][0] === "to") {
components[0].shift();
@@ -226,7 +320,7 @@
return null;
}
- var stops = WI.Gradient.stopsWithComponents(components);
+ let stops = WI.Gradient.stopsWithComponents(components);
if (!stops)
return null;
@@ -233,26 +327,6 @@
return new WI.LinearGradient(angle, stops);
}
- // Public
-
- set angleValue(value) { this._angle.value = value; }
-
- get angleValue()
- {
- return this._angle.value.maxDecimals(2);
- }
-
- set angleUnits(units)
- {
- if (units === this._angle.units)
- return;
-
- this._angle.value = this._angleValueForUnits(units);
- this._angle.units = units;
- }
-
- get angleUnits() { return this._angle.units; }
-
copy()
{
return new WI.LinearGradient(this._angle, this.stops.concat());
@@ -280,7 +354,7 @@
else if (deg !== 180)
str += this.angleValue + this.angleUnits;
- if (str !== "")
+ if (str)
str += ", ";
str += this.stringFromStops(this.stops);
@@ -287,75 +361,77 @@
return (this.repeats ? "repeating-" : "") + this.type + "(" + str + ")";
}
+};
- // Private
+WI.RadialGradient = class RadialGradient extends WI.Gradient
+{
+ constructor(sizing, stops)
+ {
+ super(WI.Gradient.Types.Radial, stops);
+ this.sizing = sizing;
+ }
- _angleValueForUnits(units)
+ // Static
+
+ static fromComponents(components)
{
- if (units === this._angle.units)
- return this._angle.value;
+ let sizing = !WI.Color.fromString(components[0].join(" ")) ? components.shift().join(" ") : "";
- let deg = 0;
+ let stops = WI.Gradient.stopsWithComponents(components);
+ if (!stops)
+ return null;
- switch (this._angle.units) {
- case WI.LinearGradient.AngleUnits.DEG:
- deg = this._angle.value;
- break;
+ return new WI.RadialGradient(sizing, stops);
+ }
- case WI.LinearGradient.AngleUnits.RAD:
- deg = this._angle.value * 180 / Math.PI;
- break;
+ // Public
- case WI.LinearGradient.AngleUnits.GRAD:
- deg = this._angle.value / 400 * 360;
- break;
+ get angleValue()
+ {
+ return 0;
+ }
- case WI.LinearGradient.AngleUnits.TURN:
- deg = this._angle.value * 360;
- break;
+ set angleValue(value)
+ {
+ console.assert(false, "CSS conic gradients do not have an angle");
+ }
- default:
- WI.reportInternalError(`Unknown angle units "${this._angle.units}"`);
- return 0;
- }
+ get angleUnits()
+ {
+ return "";
+ }
- let value = 0;
+ set angleUnits(units)
+ {
+ console.assert(false, "CSS conic gradients do not have an angle");
+ }
- switch (units) {
- case WI.LinearGradient.AngleUnits.DEG:
- value = deg;
- break;
+ copy()
+ {
+ return new WI.RadialGradient(this.sizing, this.stops.concat());
+ }
- case WI.LinearGradient.AngleUnits.RAD:
- value = deg * Math.PI / 180;
- break;
+ toString()
+ {
+ let str = this.sizing;
- case WI.LinearGradient.AngleUnits.GRAD:
- value = deg / 360 * 400;
- break;
+ if (str)
+ str += ", ";
- case WI.LinearGradient.AngleUnits.TURN:
- value = deg / 360;
- break;
- }
+ str += this.stringFromStops(this.stops);
- return value;
+ return (this.repeats ? "repeating-" : "") + this.type + "(" + str + ")";
}
};
-WI.LinearGradient.AngleUnits = {
- DEG: "deg",
- RAD: "rad",
- GRAD: "grad",
- TURN: "turn",
-};
-
-WI.RadialGradient = class RadialGradient extends WI.Gradient
+WI.ConicGradient = class ConicGradient extends WI.Gradient
{
- constructor(sizing, stops)
+ constructor(angle, position, stops)
{
- super(WI.Gradient.Types.Radial, stops);
- this.sizing = sizing;
+ super(WI.Gradient.Types.Conic, stops);
+
+ this._angle = angle;
+ this._position = position;
}
// Static
@@ -362,13 +438,34 @@
static fromComponents(components)
{
- var sizing = !WI.Color.fromString(components[0].join(" ")) ? components.shift().join(" ") : "";
+ let angle = {value: 0, units: WI.Gradient.AngleUnits.DEG};
+ let position = null;
+ let hasCustomAngleOrPosition = false;
- var stops = WI.Gradient.stopsWithComponents(components);
+ if (components[0][0] == "from") {
+ components[0].shift();
+ angle = WI.Gradient.angleFromString(components[0][0]);
+ if (!angle)
+ return null;
+ components[0].shift();
+ hasCustomAngleOrPosition = true;
+ }
+ if (components[0][0] == "at") {
+ components[0].shift();
+ // FIXME: <https://webkit.org/b/234643> (Web Inspector: allow editing positions in gradient editor)
+ if (components[0].length <= 0)
+ return null;
+ position = components[0].join(" ");
+ hasCustomAngleOrPosition = true;
+ }
+ if (hasCustomAngleOrPosition)
+ components.shift();
+
+ let stops = WI.Gradient.stopsWithComponents(components);
if (!stops)
return null;
- return new WI.RadialGradient(sizing, stops);
+ return new WI.ConicGradient(angle, position, stops);
}
// Public
@@ -375,14 +472,23 @@
copy()
{
- return new WI.RadialGradient(this.sizing, this.stops.concat());
+ return new WI.ConicGradient(this._angle, this._position, this.stops.concat());
}
toString()
{
- var str = this.sizing;
+ let str = "";
- if (str !== "")
+ if (this._angle.value)
+ str += `from ${this._angle.value}${this._angle.units}`;
+
+ if (this._position) {
+ if (str)
+ str += " ";
+ str += `at ${this._position}`;
+ }
+
+ if (str)
str += ", ";
str += this.stringFromStops(this.stops);
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorTextMarkers.js (287408 => 287409)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorTextMarkers.js 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorTextMarkers.js 2021-12-23 20:54:21 UTC (rev 287409)
@@ -111,7 +111,7 @@
break;
}
- if (/(repeating-)?(linear|radial)-gradient$/.test(lineContent.substring(0, index)))
+ if (/(repeating-)?(linear|radial|conic)-gradient$/.test(lineContent.substring(0, index)))
return false;
// Act as a negative look-behind and disallow the color from being prefixing with certain characters.
@@ -128,7 +128,7 @@
var start = range instanceof WI.TextRange ? range.startLine : 0;
var end = range instanceof WI.TextRange ? range.endLine + 1 : codeMirror.lineCount();
- var gradientRegex = /(repeating-)?(linear|radial)-gradient\s*\(\s*/g;
+ var gradientRegex = /(repeating-)?(linear|radial|conic)-gradient\s*\(\s*/g;
for (var lineNumber = start; lineNumber < end; ++lineNumber) {
var lineContent = codeMirror.getLine(lineNumber);
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js (287408 => 287409)
--- trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/GradientEditor.js 2021-12-23 20:54:21 UTC (rev 287409)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2021 Apple Inc. All rights reserved.
* Copyright (C) 2015 Devin Rousso <web...@devinrousso.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,11 @@
label: WI.UIString("Radial Gradient"),
repeats: false
},
+ "conic-gradient": {
+ type: WI.ConicGradient,
+ label: WI.UIString("Conic Gradient"),
+ repeats: false
+ },
"repeating-linear-gradient": {
type: WI.LinearGradient,
label: WI.UIString("Repeating Linear Gradient"),
@@ -54,7 +59,12 @@
type: WI.RadialGradient,
label: WI.UIString("Repeating Radial Gradient"),
repeats: true
- }
+ },
+ "repeating-conic-gradient": {
+ type: WI.ConicGradient,
+ label: WI.UIString("Repeating Conic Gradient"),
+ repeats: true
+ },
};
this._editingColor = false;
@@ -93,10 +103,10 @@
this._angleUnitsSelectElement.addEventListener("change", this._angleUnitsChanged.bind(this));
const angleUnitsData = [
- {name: WI.LinearGradient.AngleUnits.DEG, min: 0, max: 360, step: 1},
- {name: WI.LinearGradient.AngleUnits.RAD, min: 0, max: 2 * Math.PI, step: 0.01},
- {name: WI.LinearGradient.AngleUnits.GRAD, min: 0, max: 400, step: 1},
- {name: WI.LinearGradient.AngleUnits.TURN, min: 0, max: 1, step: 0.01}
+ {name: WI.Gradient.AngleUnits.DEG, min: 0, max: 360, step: 1},
+ {name: WI.Gradient.AngleUnits.RAD, min: 0, max: 2 * Math.PI, step: 0.01},
+ {name: WI.Gradient.AngleUnits.GRAD, min: 0, max: 400, step: 1},
+ {name: WI.Gradient.AngleUnits.TURN, min: 0, max: 1, step: 0.01}
];
this._angleUnitsConfiguration = new Map(angleUnitsData.map(({name, min, max, step}) => {
@@ -119,8 +129,9 @@
const isLinear = gradient instanceof WI.LinearGradient;
const isRadial = gradient instanceof WI.RadialGradient;
- console.assert(isLinear || isRadial);
- if (!isLinear && !isRadial)
+ const isConic = gradient instanceof WI.ConicGradient;
+ console.assert(isLinear || isRadial || isConic);
+ if (!isLinear && !isRadial && !isConic)
return;
this._gradient = gradient;
@@ -127,10 +138,13 @@
this._gradientSlider.stops = this._gradient.stops;
if (isLinear) {
this._gradientTypePicker.value = this._gradient.repeats ? "repeating-linear-gradient" : "linear-gradient";
-
this._angleUnitsChanged();
- } else
+ } else if (isRadial)
this._gradientTypePicker.value = this._gradient.repeats ? "repeating-radial-gradient" : "radial-gradient";
+ else {
+ this._gradientTypePicker.value = this._gradient.repeats ? "repeating-conic-gradient" : "conic-gradient";
+ this._angleUnitsChanged();
+ }
this._updateCSSClassForGradientType();
}
@@ -185,12 +199,19 @@
{
const descriptor = this._gradientTypes[this._gradientTypePicker.value];
if (!(this._gradient instanceof descriptor.type)) {
- if (descriptor.type === WI.LinearGradient) {
- this._gradient = new WI.LinearGradient({value: 180, units: WI.LinearGradient.AngleUnits.DEG}, this._gradient.stops);
-
+ switch (descriptor.type) {
+ case WI.LinearGradient:
+ this._gradient = new WI.LinearGradient({value: 180, units: WI.Gradient.AngleUnits.DEG}, this._gradient.stops);
this._angleUnitsChanged();
- } else
+ break;
+ case WI.RadialGradient:
this._gradient = new WI.RadialGradient("", this._gradient.stops);
+ break;
+ case WI.ConicGradient:
+ this._gradient = new WI.ConicGradient({value: 0, units: WI.Gradient.AngleUnits.DEG}, null, this._gradient.stops);
+ this._angleUnitsChanged();
+ break;
+ }
this._updateCSSClassForGradientType();
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js (287408 => 287409)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js 2021-12-23 20:45:45 UTC (rev 287408)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js 2021-12-23 20:54:21 UTC (rev 287409)
@@ -648,7 +648,7 @@
_addGradientTokens(tokens)
{
- let gradientRegex = /^(repeating-)?(linear|radial)-gradient$/i;
+ let gradientRegex = /^(repeating-)?(linear|radial|conic)-gradient$/i;
let newTokens = [];
let gradientStartIndex = NaN;
let openParenthesis = 0;