Diff
Modified: trunk/LayoutTests/ChangeLog (248278 => 248279)
--- trunk/LayoutTests/ChangeLog 2019-08-05 23:25:45 UTC (rev 248278)
+++ trunk/LayoutTests/ChangeLog 2019-08-05 23:40:40 UTC (rev 248279)
@@ -1,3 +1,13 @@
+2019-08-05 Devin Rousso <[email protected]>
+
+ Web Inspector: Styles: variable swatch not shown for var() with a fallback
+ https://bugs.webkit.org/show_bug.cgi?id=200237
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/css/resolve-variable-value.html: Added.
+ * inspector/css/resolve-variable-value-expected.txt: Added.
+
2019-08-05 Chris Dumez <[email protected]>
navigator.geolocation wrapper should not become GC-collectable once its frame is detached
Added: trunk/LayoutTests/inspector/css/resolve-variable-value-expected.txt (0 => 248279)
--- trunk/LayoutTests/inspector/css/resolve-variable-value-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/resolve-variable-value-expected.txt 2019-08-05 23:40:40 UTC (rev 248279)
@@ -0,0 +1,43 @@
+Test that WI.CSSStyleDeclaration.prototype.resolveVariableValue works as expected.
+
+
+== Running test suite: WI.CSSStyleDeclaration.prototype.resolveVariableValue
+-- Running test case: NotVariable
+PASS: "red" should resolve to null.
+
+-- Running test case: EmptyVariable
+PASS: "var()" should resolve to null.
+
+-- Running test case: InvalidVariable
+PASS: "var(invalid)" should resolve to null.
+
+-- Running test case: NonExistentVariable
+PASS: "var(--DNE)" should resolve to null.
+
+-- Running test case: ValidVariable
+PASS: "var(--a)" should resolve to "blue".
+
+-- Running test case: InvalidFallbackValue
+PASS: "var(--DNE, )" should resolve to null.
+
+-- Running test case: ValidFallbackValue
+PASS: "var(--DNE, red)" should resolve to "red".
+
+-- Running test case: InvalidFallbackVariable
+PASS: "var(--DNE, var(--DNE))" should resolve to null.
+
+-- Running test case: ValidFallbackVariable
+PASS: "var(--DNE, var(--b, red))" should resolve to "green".
+
+-- Running test case: ValidVariableWithInvalidFallbackValue
+PASS: "var(--a, )" should resolve to "blue".
+
+-- Running test case: ValidVariableWithValidFallbackValue
+PASS: "var(--a, red)" should resolve to "blue".
+
+-- Running test case: ValidVariableWithInvalidFallbackVariable
+PASS: "var(--a, var(--DNE))" should resolve to "blue".
+
+-- Running test case: ValidVariableWithValidFallbackVariable
+PASS: "var(--a, var(--b))" should resolve to "blue".
+
Added: trunk/LayoutTests/inspector/css/resolve-variable-value.html (0 => 248279)
--- trunk/LayoutTests/inspector/css/resolve-variable-value.html (rev 0)
+++ trunk/LayoutTests/inspector/css/resolve-variable-value.html 2019-08-05 23:40:40 UTC (rev 248279)
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+#foo {
+ --a: blue;
+ --b: green;
+}
+</style>
+<script>
+function test() {
+ let suite = InspectorTest.createSyncSuite("WI.CSSStyleDeclaration.prototype.resolveVariableValue");
+
+ let computedStyle = null;
+
+ function addTest({name, _expression_, expected}) {
+ suite.addTestCase({
+ name,
+ test() {
+ InspectorTest.expectEqual(computedStyle.resolveVariableValue(_expression_), expected, `"${_expression_}" should resolve to ${JSON.stringify(expected)}.`);
+ },
+ })
+ }
+ addTest({
+ name: "NotVariable",
+ _expression_: "red",
+ expected: null,
+ });
+ addTest({
+ name: "EmptyVariable",
+ _expression_: "var()",
+ expected: null,
+ });
+ addTest({
+ name: "InvalidVariable",
+ _expression_: "var(invalid)",
+ expected: null,
+ });
+ addTest({
+ name: "NonExistentVariable",
+ _expression_: "var(--DNE)",
+ expected: null,
+ });
+ addTest({
+ name: "ValidVariable",
+ _expression_: "var(--a)",
+ expected: "blue",
+ });
+ addTest({
+ name: "InvalidFallbackValue",
+ _expression_: "var(--DNE, )",
+ expected: null,
+ });
+ addTest({
+ name: "ValidFallbackValue",
+ _expression_: "var(--DNE, red)",
+ expected: "red",
+ });
+ addTest({
+ name: "InvalidFallbackVariable",
+ _expression_: "var(--DNE, var(--DNE))",
+ expected: null,
+ });
+ addTest({
+ name: "ValidFallbackVariable",
+ _expression_: "var(--DNE, var(--b, red))",
+ expected: "green",
+ });
+ addTest({
+ name: "ValidVariableWithInvalidFallbackValue",
+ _expression_: "var(--a, )",
+ expected: "blue",
+ });
+ addTest({
+ name: "ValidVariableWithValidFallbackValue",
+ _expression_: "var(--a, red)",
+ expected: "blue",
+ });
+ addTest({
+ name: "ValidVariableWithInvalidFallbackVariable",
+ _expression_: "var(--a, var(--DNE))",
+ expected: "blue",
+ });
+ addTest({
+ name: "ValidVariableWithValidFallbackVariable",
+ _expression_: "var(--a, var(--b))",
+ expected: "blue",
+ });
+
+
+ WI.domManager.requestDocument((documentNode) => {
+ WI.domManager.querySelector(documentNode.id, "#foo", (contentNodeId) => {
+ if (!contentNodeId) {
+ InspectorTest.fail("DOM node not found.");
+ InspectorTest.completeTest();
+ return;
+ }
+
+ let domNode = WI.domManager.nodeForId(contentNodeId);
+ nodeStyles = WI.cssManager.stylesForNode(domNode);
+
+ if (nodeStyles.needsRefresh) {
+ nodeStyles.singleFireEventListener(WI.DOMNodeStyles.Event.Refreshed, (event) => {
+ computedStyle = nodeStyles.computedStyle;
+ suite.runTestCasesAndFinish();
+ });
+ return;
+ }
+
+ computedStyle = nodeStyles.computedStyle;
+ suite.runTestCasesAndFinish();
+ });
+ });
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Test that WI.CSSStyleDeclaration.prototype.resolveVariableValue works as expected.</p>
+<div id="foo"></div>
+</body>
+</html>
Modified: trunk/Source/WebInspectorUI/ChangeLog (248278 => 248279)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-08-05 23:25:45 UTC (rev 248278)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-08-05 23:40:40 UTC (rev 248279)
@@ -1,5 +1,44 @@
2019-08-05 Devin Rousso <[email protected]>
+ Web Inspector: Styles: variable swatch not shown for var() with a fallback
+ https://bugs.webkit.org/show_bug.cgi?id=200237
+
+ Reviewed by Joseph Pecoraro.
+
+ * UserInterface/Views/SpreadsheetStyleProperty.js:
+ (WI.SpreadsheetStyleProperty.prototype._createInlineSwatch):
+ (WI.SpreadsheetStyleProperty.prototype._replaceSpecialTokens): Added.
+ (WI.SpreadsheetStyleProperty.prototype._addGradientTokens):
+ (WI.SpreadsheetStyleProperty.prototype._addColorTokens):
+ (WI.SpreadsheetStyleProperty.prototype._addTimingFunctionTokens):
+ (WI.SpreadsheetStyleProperty.prototype._addVariableTokens):
+ Check to see if there's a fallback value in the `var()` and tokenize it if there is. Mark
+ the property as invalid if the `var()` doesn't end up resolving to anything.
+
+ * UserInterface/Views/InlineSwatch.js:
+ (WI.InlineSwatch):
+ (WI.InlineSwatch.prototype.get value):
+ (WI.InlineSwatch.prototype._updateSwatch):
+ (WI.InlineSwatch.prototype._handleContextMenuEvent):
+ (WI.InlineSwatch.prototype._getNextValidHEXFormat.hexMatchesCurrentColor):
+ (WI.InlineSwatch.prototype._getNextValidHEXFormat):
+ Allow the `value` to be a function. In that case, use the getter `this.value` instead of the
+ value `this._value` directly so that the function is invoked.
+ This is needed for variable swatches because the fallback value could change after the
+ swatch has been created (e.g. another swatch in a CSS property value that just modifies the
+ text, rather than re-renders the entire CSS property value).
+
+ * UserInterface/Models/CSSStyleDeclaration.js:
+ (WI.CSSStyleDeclaration.prototype.resolveVariableValue): Added.
+ Follow the variable chain until an ultimate value is reached.
+
+ * UserInterface/Models/CSSKeywordCompletions.js:
+ (WI.CSSKeywordCompletions.isColorAwareProperty):
+ (WI.CSSKeywordCompletions.isTimingFunctionAwareProperty): Added.
+ Limit `cubic-bezier` and `spring` tokens to only be shown for timing function properties.
+
+2019-08-05 Devin Rousso <[email protected]>
+
Web Inspector: rename "Stylesheet" to "Style Sheet" to match spec text
https://bugs.webkit.org/show_bug.cgi?id=200422
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSKeywordCompletions.js (248278 => 248279)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSKeywordCompletions.js 2019-08-05 23:25:45 UTC (rev 248278)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSKeywordCompletions.js 2019-08-05 23:40:40 UTC (rev 248279)
@@ -75,11 +75,11 @@
WI.CSSKeywordCompletions.isColorAwareProperty = function(name)
{
- if (name in WI.CSSKeywordCompletions._colorAwareProperties)
+ if (WI.CSSKeywordCompletions._colorAwareProperties.has(name))
return true;
let isNotPrefixed = name.charAt(0) !== "-";
- if (isNotPrefixed && ("-webkit-" + name) in WI.CSSKeywordCompletions._colorAwareProperties)
+ if (isNotPrefixed && WI.CSSKeywordCompletions._colorAwareProperties.has("-webkit-" + name))
return true;
if (name.endsWith("color"))
@@ -88,6 +88,18 @@
return false;
};
+WI.CSSKeywordCompletions.isTimingFunctionAwareProperty = function(name)
+{
+ if (WI.CSSKeywordCompletions._timingFunctionAwareProperties.has(name))
+ return true;
+
+ let isNotPrefixed = name.charAt(0) !== "-";
+ if (isNotPrefixed && WI.CSSKeywordCompletions._timingFunctionAwareProperties.has("-webkit-" + name))
+ return true;
+
+ return false;
+};
+
WI.CSSKeywordCompletions.forFunction = function(functionName)
{
let suggestions = ["var()"];
@@ -302,18 +314,53 @@
"wheat", "whitesmoke", "yellowgreen", "rgb()", "rgba()", "hsl()", "hsla()"
];
-WI.CSSKeywordCompletions._colorAwareProperties = [
- "background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
- "border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
- "fill", "outline", "outline-color", "stroke", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
- "text-shadow", "text-underline", "text-underline-color", "-webkit-box-shadow", "-webkit-column-rule", "-webkit-column-rule-color",
- "-webkit-text-emphasis", "-webkit-text-emphasis-color", "-webkit-text-fill-color", "-webkit-text-stroke", "-webkit-text-stroke-color",
- "-webkit-text-decoration-color",
+WI.CSSKeywordCompletions._colorAwareProperties = new Set([
+ "background",
+ "background-color",
+ "background-image",
+ "border",
+ "border-color",
+ "border-bottom",
+ "border-bottom-color",
+ "border-left",
+ "border-left-color",
+ "border-right",
+ "border-right-color",
+ "border-top",
+ "border-top-color",
+ "box-shadow", "-webkit-box-shadow",
+ "color",
+ "column-rule", "-webkit-column-rule",
+ "column-rule-color", "-webkit-column-rule-color",
+ "fill",
+ "outline",
+ "outline-color",
+ "stroke",
+ "text-decoration-color", "-webkit-text-decoration-color",
+ "text-emphasis", "-webkit-text-emphasis",
+ "text-emphasis-color", "-webkit-text-emphasis-color",
+ "text-line-through",
+ "text-line-through-color",
+ "text-overline",
+ "text-overline-color",
+ "text-shadow",
+ "text-underline",
+ "text-underline-color",
+ "-webkit-text-fill-color",
+ "-webkit-text-stroke",
+ "-webkit-text-stroke-color",
// iOS Properties
- "-webkit-tap-highlight-color"
-].keySet();
+ "-webkit-tap-highlight-color",
+]);
+WI.CSSKeywordCompletions._timingFunctionAwareProperties = new Set([
+ "animation", "-webkit-animation",
+ "animation-timing-function", "-webkit-animation-timing-function",
+ "transition", "-webkit-transition",
+ "transition-timing-function", "-webkit-transition-timing-function",
+]);
+
WI.CSSKeywordCompletions._propertyKeywordMap = {
"content": [
"list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote", "attr()", "counter()", "counters()", "url()", "linear-gradient()", "radial-gradient()", "repeating-linear-gradient()", "repeating-radial-gradient()", "-webkit-canvas()", "cross-fade()", "image-set()"
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js (248278 => 248279)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js 2019-08-05 23:25:45 UTC (rev 248278)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js 2019-08-05 23:40:40 UTC (rev 248279)
@@ -348,6 +348,62 @@
return newProperty;
}
+ resolveVariableValue(text)
+ {
+ const invalid = Symbol("invalid");
+
+ let checkTokens = (tokens) => {
+ let startIndex = NaN;
+ let openParenthesis = 0;
+ for (let i = 0; i < tokens.length; i++) {
+ let token = tokens[i];
+ if (token.value === "var" && token.type && token.type.includes("atom")) {
+ if (isNaN(startIndex)) {
+ startIndex = i;
+ openParenthesis = 0;
+ }
+ continue;
+ }
+
+ if (isNaN(startIndex))
+ continue;
+
+ if (token.value === "(") {
+ ++openParenthesis;
+ continue;
+ }
+
+ if (token.value === ")") {
+ --openParenthesis;
+ if (openParenthesis > 0)
+ continue;
+
+ let variableTokens = tokens.slice(startIndex, i + 1);
+ startIndex = NaN;
+
+ let variableNameIndex = variableTokens.findIndex((token) => token.value.startsWith("--") && /\bvariable-2\b/.test(token.type));
+ if (variableNameIndex === -1)
+ continue;
+
+ let variableProperty = this.propertyForName(variableTokens[variableNameIndex].value, true);
+ if (variableProperty)
+ return variableProperty.value.trim();
+
+ let fallbackStartIndex = variableTokens.findIndex((value, j) => j > variableNameIndex + 1 && /\bm-css\b/.test(value.type));
+ if (fallbackStartIndex === -1)
+ return invalid;
+
+ let fallbackTokens = variableTokens.slice(fallbackStartIndex, i);
+ return checkTokens(fallbackTokens) || fallbackTokens.reduce((accumulator, token) => accumulator + token.value, "").trim();
+ }
+ }
+ return null;
+ };
+
+ let resolved = checkTokens(WI.tokenizeCSSValue(text));
+ return resolved === invalid ? null : resolved;
+ }
+
newBlankProperty(propertyIndex)
{
let text, name, value, priority, overridden, implicit, anonymous;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js (248278 => 248279)
--- trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js 2019-08-05 23:25:45 UTC (rev 248278)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/InlineSwatch.js 2019-08-05 23:40:40 UTC (rev 248279)
@@ -90,6 +90,8 @@
get value()
{
+ if (typeof this._value === "function")
+ return this._value();
return this._value;
}
@@ -137,13 +139,15 @@
_updateSwatch(dontFireEvents)
{
+ let value = this.value;
+
if (this._type === WI.InlineSwatch.Type.Color || this._type === WI.InlineSwatch.Type.Gradient)
- this._swatchInnerElement.style.background = "" ? this._value.toString() : null;
+ this._swatchInnerElement.style.background = "" ? value.toString() : null;
else if (this._type === WI.InlineSwatch.Type.Image)
- this._swatchInnerElement.style.setProperty("background-image", `url(${this._value.src})`);
+ this._swatchInnerElement.style.setProperty("background-image", `url(${value.src})`);
if (!dontFireEvents)
- this.dispatchEventToListeners(WI.InlineSwatch.Event.ValueChanged, {value: this._value});
+ this.dispatchEventToListeners(WI.InlineSwatch.Event.ValueChanged, {value});
}
_swatchElementClicked(event)
@@ -150,12 +154,14 @@
{
event.stop();
- if (event.shiftKey && this._value) {
+ let value = this.value;
+
+ if (event.shiftKey && value) {
if (this._type === WI.InlineSwatch.Type.Color) {
- let nextFormat = this._value.nextFormat();
+ let nextFormat = value.nextFormat();
console.assert(nextFormat);
if (nextFormat) {
- this._value.format = nextFormat;
+ value.format = nextFormat;
this._updateSwatch();
}
return;
@@ -172,6 +178,9 @@
if (this._valueEditor)
return;
+ if (!value)
+ value = this._fallbackValue();
+
let bounds = WI.Rect.rectFromClientRect(this._swatchElement.getBoundingClientRect());
let popover = new WI.Popover(this);
@@ -220,12 +229,14 @@
break;
case WI.InlineSwatch.Type.Image:
- this._valueEditor = {};
- this._valueEditor.element = document.createElement("img");
- this._valueEditor.element.src = ""
- this._valueEditor.element.classList.add("show-grid");
- this._valueEditor.element.style.setProperty("max-width", "50vw");
- this._valueEditor.element.style.setProperty("max-height", "50vh");
+ if (value.src) {
+ this._valueEditor = {};
+ this._valueEditor.element = document.createElement("img");
+ this._valueEditor.element.src = ""
+ this._valueEditor.element.classList.add("show-grid");
+ this._valueEditor.element.style.setProperty("max-width", "50vw");
+ this._valueEditor.element.style.setProperty("max-height", "50vh");
+ }
break;
}
@@ -237,7 +248,6 @@
this.dispatchEventToListeners(WI.InlineSwatch.Event.Activated);
- let value = this._value || this._fallbackValue();
switch (this._type) {
case WI.InlineSwatch.Type.Color:
this._valueEditor.color = value;
@@ -294,14 +304,15 @@
_handleContextMenuEvent(event)
{
- if (!this._value)
+ let value = this.value;
+ if (!value)
return;
let contextMenu = WI.ContextMenu.createFromEvent(event);
- if (this._value.isKeyword() && this._value.format !== WI.Color.Format.Keyword) {
+ if (value.isKeyword() && value.format !== WI.Color.Format.Keyword) {
contextMenu.appendItem(WI.UIString("Format: Keyword"), () => {
- this._value.format = WI.Color.Format.Keyword;
+ value.format = WI.Color.Format.Keyword;
this._updateSwatch();
});
}
@@ -309,31 +320,31 @@
let hexInfo = this._getNextValidHEXFormat();
if (hexInfo) {
contextMenu.appendItem(hexInfo.title, () => {
- this._value.format = hexInfo.format;
+ value.format = hexInfo.format;
this._updateSwatch();
});
}
- if (this._value.simple && this._value.format !== WI.Color.Format.HSL) {
+ if (value.simple && value.format !== WI.Color.Format.HSL) {
contextMenu.appendItem(WI.UIString("Format: HSL"), () => {
- this._value.format = WI.Color.Format.HSL;
+ value.format = WI.Color.Format.HSL;
this._updateSwatch();
});
- } else if (this._value.format !== WI.Color.Format.HSLA) {
+ } else if (value.format !== WI.Color.Format.HSLA) {
contextMenu.appendItem(WI.UIString("Format: HSLA"), () => {
- this._value.format = WI.Color.Format.HSLA;
+ value.format = WI.Color.Format.HSLA;
this._updateSwatch();
});
}
- if (this._value.simple && this._value.format !== WI.Color.Format.RGB) {
+ if (value.simple && value.format !== WI.Color.Format.RGB) {
contextMenu.appendItem(WI.UIString("Format: RGB"), () => {
- this._value.format = WI.Color.Format.RGB;
+ value.format = WI.Color.Format.RGB;
this._updateSwatch();
});
- } else if (this._value.format !== WI.Color.Format.RGBA) {
+ } else if (value.format !== WI.Color.Format.RGBA) {
contextMenu.appendItem(WI.UIString("Format: RGBA"), () => {
- this._value.format = WI.Color.Format.RGBA;
+ value.format = WI.Color.Format.RGBA;
this._updateSwatch();
});
}
@@ -344,13 +355,15 @@
if (this._type !== WI.InlineSwatch.Type.Color)
return false;
+ let value = this.value;
+
function hexMatchesCurrentColor(hexInfo) {
let nextIsSimple = hexInfo.format === WI.Color.Format.ShortHEX || hexInfo.format === WI.Color.Format.HEX;
- if (nextIsSimple && !this._value.simple)
+ if (nextIsSimple && !value.simple)
return false;
let nextIsShort = hexInfo.format === WI.Color.Format.ShortHEX || hexInfo.format === WI.Color.Format.ShortHEXAlpha;
- if (nextIsShort && !this._value.canBeSerializedAsShortHEX())
+ if (nextIsShort && !value.canBeSerializedAsShortHEX())
return false;
return true;
@@ -375,15 +388,15 @@
}
];
- let currentColorIsHEX = hexFormats.some((info) => info.format === this._value.format);
+ let currentColorIsHEX = hexFormats.some((info) => info.format === value.format);
for (let i = 0; i < hexFormats.length; ++i) {
- if (currentColorIsHEX && this._value.format !== hexFormats[i].format)
+ if (currentColorIsHEX && value.format !== hexFormats[i].format)
continue;
for (let j = ~~currentColorIsHEX; j < hexFormats.length; ++j) {
let nextIndex = (i + j) % hexFormats.length;
- if (hexMatchesCurrentColor.call(this, hexFormats[nextIndex]))
+ if (hexMatchesCurrentColor(hexFormats[nextIndex]))
return hexFormats[nextIndex];
}
return null;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js (248278 => 248279)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js 2019-08-05 23:25:45 UTC (rev 248278)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js 2019-08-05 23:40:40 UTC (rev 248279)
@@ -447,19 +447,9 @@
const maxValueLength = 150;
let tokens = WI.tokenizeCSSValue(value);
- if (this._property.enabled) {
- // FIXME: <https://webkit.org/b/178636> Web Inspector: Styles: Make inline widgets work with CSS functions (var(), calc(), etc.)
+ if (this._property.enabled)
+ tokens = this._replaceSpecialTokens(tokens);
- // CSS variables may contain color - display color picker for them.
- if (this._property.variable || WI.CSSKeywordCompletions.isColorAwareProperty(this._property.name)) {
- tokens = this._addGradientTokens(tokens);
- tokens = this._addColorTokens(tokens);
- }
- tokens = this._addTimingFunctionTokens(tokens, "cubic-bezier");
- tokens = this._addTimingFunctionTokens(tokens, "spring");
- tokens = this._addVariableTokens(tokens);
- }
-
tokens = tokens.map((token) => {
if (token instanceof Element)
return token;
@@ -493,11 +483,18 @@
this._valueElement.append(...tokens);
}
- _createInlineSwatch(type, text, valueObject)
+ _createInlineSwatch(type, contents, valueObject)
{
let tokenElement = document.createElement("span");
let innerElement = document.createElement("span");
- innerElement.textContent = text;
+ for (let item of contents) {
+ if (item instanceof Node)
+ innerElement.appendChild(item);
+ else if (typeof item === "object")
+ innerElement.append(item.value);
+ else
+ innerElement.append(item);
+ }
let readOnly = !this._isEditable();
let swatch = new WI.InlineSwatch(type, valueObject, readOnly);
@@ -514,6 +511,12 @@
this._renderValue(this._property.rawValue);
}, this);
+ if (type === WI.InlineSwatch.Type.Variable) {
+ swatch.value = () => {
+ return this._property.ownerStyle.nodeStyles.computedStyle.resolveVariableValue(innerElement.textContent);
+ };
+ }
+
if (this._delegate && typeof this._delegate.stylePropertyInlineSwatchActivated === "function") {
swatch.addEventListener(WI.InlineSwatch.Event.Activated, () => {
this._delegate.stylePropertyInlineSwatchActivated();
@@ -531,6 +534,25 @@
return tokenElement;
}
+ _replaceSpecialTokens(tokens)
+ {
+ // FIXME: <https://webkit.org/b/178636> Web Inspector: Styles: Make inline widgets work with CSS functions (var(), calc(), etc.)
+
+ tokens = this._addVariableTokens(tokens);
+
+ if (this._property.variable || WI.CSSKeywordCompletions.isColorAwareProperty(this._property.name)) {
+ tokens = this._addGradientTokens(tokens);
+ tokens = this._addColorTokens(tokens);
+ }
+
+ if (this._property.variable || WI.CSSKeywordCompletions.isTimingFunctionAwareProperty(this._property.name)) {
+ tokens = this._addTimingFunctionTokens(tokens, "cubic-bezier");
+ tokens = this._addTimingFunctionTokens(tokens, "spring");
+ }
+
+ return tokens;
+ }
+
_addGradientTokens(tokens)
{
let gradientRegex = /^(repeating-)?(linear|radial)-gradient$/i;
@@ -556,7 +578,7 @@
let text = rawTokens.map((token) => token.value).join("");
let gradient = WI.Gradient.fromString(text);
if (gradient)
- newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Gradient, text, gradient));
+ newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Gradient, rawTokens, gradient));
else
newTokens.push(...rawTokens);
@@ -575,7 +597,7 @@
let pushPossibleColorToken = (text, ...rawTokens) => {
let color = WI.Color.fromString(text);
if (color)
- newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Color, text, color));
+ newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Color, rawTokens, color));
else
newTokens.push(...rawTokens);
};
@@ -642,7 +664,7 @@
}
if (valueObject)
- newTokens.push(this._createInlineSwatch(inlineSwatchType, text, valueObject));
+ newTokens.push(this._createInlineSwatch(inlineSwatchType, rawTokens, valueObject));
else
newTokens.push(...rawTokens);
@@ -663,8 +685,10 @@
for (let i = 0; i < tokens.length; i++) {
let token = tokens[i];
if (token.value === "var" && token.type && token.type.includes("atom")) {
- startIndex = i;
- openParenthesis = 0;
+ if (isNaN(startIndex)) {
+ startIndex = i;
+ openParenthesis = 0;
+ }
} else if (token.value === "(" && !isNaN(startIndex))
++openParenthesis;
else if (token.value === ")" && !isNaN(startIndex)) {
@@ -673,14 +697,22 @@
continue;
let rawTokens = tokens.slice(startIndex, i + 1);
- let tokenValues = rawTokens.map((token) => token.value);
- let variableName = tokenValues.find((value, i) => value.startsWith("--") && /\bvariable-2\b/.test(rawTokens[i].type));
+ let variableNameIndex = rawTokens.findIndex((token) => token.value.startsWith("--") && /\bvariable-2\b/.test(token.type));
+ if (variableNameIndex !== -1) {
+ let contents = [];
+ let fallbackStartIndex = rawTokens.findIndex((value, i) => i > variableNameIndex + 1 && /\bm-css\b/.test(value.type));
+ if (fallbackStartIndex !== -1) {
+ contents = contents.concat(rawTokens.slice(0, fallbackStartIndex));
+ contents = contents.concat(this._replaceSpecialTokens(rawTokens.slice(fallbackStartIndex, i)));
+ } else
+ contents = contents.concat(rawTokens.slice(0, i));
+ contents.push(token);
- const dontCreateIfMissing = true;
- let variableProperty = this._property.ownerStyle.nodeStyles.computedStyle.propertyForName(variableName, dontCreateIfMissing);
- if (variableProperty) {
- let valueObject = variableProperty.value.trim();
- newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Variable, tokenValues.join(""), valueObject));
+ let text = rawTokens.reduce((accumulator, token) => accumulator + token.value, "");
+ if (this._property.ownerStyle.nodeStyles.computedStyle.resolveVariableValue(text))
+ newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Variable, contents));
+ else
+ newTokens = newTokens.concat(contents);
} else {
this._hasInvalidVariableValue = true;
newTokens.push(...rawTokens);