Changeset 223978 in webkit


Ignore:
Timestamp:
Oct 25, 2017 2:09:45 PM (7 years ago)
Author:
Nikita Vasilyev
Message:

Web Inspector: [PARITY] Styles Redesign: Add color gradient, bezier curve, and spring inline widgets
https://bugs.webkit.org/show_bug.cgi?id=178404
<rdar://problem/35035992>

Reviewed by Devin Rousso.

Add inline widgets for the following CSS values:

  • Gradients, e.g. background-image: linear-gradient(yellow, orange)
  • Bezier curves, e.g. transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55)
  • Spring functions, e.g. transition-timing-function: spring(1, 2, 2, 4)
  • UserInterface/Models/Color.js:

(WI.Color.prototype.toString):
Don't throw. The are never try/catch blocks on the callsites.

  • UserInterface/Views/SpreadsheetStyleProperty.js:

(WI.SpreadsheetStyleProperty.prototype._renderValue):
(WI.SpreadsheetStyleProperty.prototype._createInlineSwatch):
(WI.SpreadsheetStyleProperty.prototype._addGradientTokens):
(WI.SpreadsheetStyleProperty.prototype._addColorTokens):
(WI.SpreadsheetStyleProperty.prototype._addTimingFunctionTokens):

Location:
trunk/Source/WebInspectorUI
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r223970 r223978  
     12017-10-25  Nikita Vasilyev  <nvasilyev@apple.com>
     2
     3        Web Inspector: [PARITY] Styles Redesign: Add color gradient, bezier curve, and spring inline widgets
     4        https://bugs.webkit.org/show_bug.cgi?id=178404
     5        <rdar://problem/35035992>
     6
     7        Reviewed by Devin Rousso.
     8
     9        Add inline widgets for the following CSS values:
     10        - Gradients, e.g. `background-image: linear-gradient(yellow, orange)`
     11        - Bezier curves, e.g. `transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55)`
     12        - Spring functions, e.g. `transition-timing-function: spring(1, 2, 2, 4)`
     13
     14        * UserInterface/Models/Color.js:
     15        (WI.Color.prototype.toString):
     16        Don't throw. The are never try/catch blocks on the callsites.
     17
     18        * UserInterface/Views/SpreadsheetStyleProperty.js:
     19        (WI.SpreadsheetStyleProperty.prototype._renderValue):
     20        (WI.SpreadsheetStyleProperty.prototype._createInlineSwatch):
     21        (WI.SpreadsheetStyleProperty.prototype._addGradientTokens):
     22        (WI.SpreadsheetStyleProperty.prototype._addColorTokens):
     23        (WI.SpreadsheetStyleProperty.prototype._addTimingFunctionTokens):
     24
    1252017-10-25  Nikita Vasilyev  <nvasilyev@apple.com>
    226
  • trunk/Source/WebInspectorUI/UserInterface/Models/Color.js

    r223575 r223978  
    380380        }
    381381
    382         throw "invalid color format";
     382        console.error("Invalid color format: " + format);
     383        return "";
    383384    }
    384385
  • trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js

    r223970 r223978  
    254254
    255255        if (this._property.enabled) {
    256             // Don't show color widgets for CSS gradients, show dedicated gradient widgets instead.
    257             // FIXME: <https://webkit.org/b/178404> Web Inspector: [PARITY] Styles Redesign: Add bezier curve, color gradient, and CSS variable inline widgets
     256            // FIXME: <https://webkit.org/b/178636> Web Inspector: Styles: Make inline widgets work with CSS functions (var(), calc(), etc.)
     257            tokens = this._addGradientTokens(tokens);
    258258            tokens = this._addColorTokens(tokens);
     259            tokens = this._addTimingFunctionTokens(tokens, "cubic-bezier");
     260            tokens = this._addTimingFunctionTokens(tokens, "spring");
    259261        }
    260262
     
    288290    }
    289291
     292    _createInlineSwatch(type, text, valueObject)
     293    {
     294        let tokenElement = document.createElement("span");
     295        let innerElement = document.createElement("span");
     296        innerElement.textContent = text;
     297
     298        let readOnly = !this._property.editable;
     299        let swatch = new WI.InlineSwatch(type, valueObject, readOnly);
     300
     301        swatch.addEventListener(WI.InlineSwatch.Event.ValueChanged, (event) => {
     302            let value = event.data.value && event.data.value.toString();
     303            if (!value)
     304                return;
     305
     306            innerElement.textContent = value;
     307            this._handleValueChange();
     308        }, this);
     309
     310        tokenElement.append(swatch.element, innerElement);
     311
     312        // Prevent the value from editing when clicking on the swatch.
     313        swatch.element.addEventListener("mousedown", (event) => { event.stop(); });
     314
     315        return tokenElement;
     316    }
     317
     318    _addGradientTokens(tokens)
     319    {
     320        let gradientRegex = /^(repeating-)?(linear|radial)-gradient$/i;
     321        let newTokens = [];
     322        let gradientStartIndex = NaN;
     323        let openParenthesis = 0;
     324
     325        for (let i = 0; i < tokens.length; i++) {
     326            let token = tokens[i];
     327            if (token.type && token.type.includes("atom") && gradientRegex.test(token.value)) {
     328                gradientStartIndex = i;
     329                openParenthesis = 0;
     330            } else if (token.value === "(" && !isNaN(gradientStartIndex))
     331                openParenthesis++;
     332            else if (token.value === ")" && !isNaN(gradientStartIndex)) {
     333                openParenthesis--;
     334                if (openParenthesis > 0) {
     335                    // Matched a CSS function inside of the gradient.
     336                    continue;
     337                }
     338
     339                let rawTokens = tokens.slice(gradientStartIndex, i + 1);
     340                let text = rawTokens.map((token) => token.value).join("");
     341                let gradient = WI.Gradient.fromString(text);
     342                if (gradient)
     343                    newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Gradient, text, gradient));
     344                else
     345                    newTokens.push(...rawTokens);
     346
     347                gradientStartIndex = NaN;
     348            } else if (isNaN(gradientStartIndex))
     349                newTokens.push(token);
     350        }
     351
     352        return newTokens;
     353    }
     354
    290355    _addColorTokens(tokens)
    291356    {
    292357        let newTokens = [];
    293358
    294         let createColorTokenElement = (colorString, color) => {
    295             let colorTokenElement = document.createElement("span");
    296             colorTokenElement.className = "token-color";
    297 
    298             let innerElement = document.createElement("span");
    299             innerElement.className = "token-color-value";
    300             innerElement.textContent = colorString;
    301 
    302             if (color) {
    303                 let readOnly = !this._property.editable;
    304                 let swatch = new WI.InlineSwatch(WI.InlineSwatch.Type.Color, color, readOnly);
    305 
    306                 swatch.addEventListener(WI.InlineSwatch.Event.ValueChanged, (event) => {
    307                     let value = event.data && event.data.value && event.data.value.toString();
    308                     console.assert(value, "Color value is empty.");
    309                     if (!value)
    310                         return;
    311 
    312                     innerElement.textContent = value;
    313                     this._handleValueChange();
    314                 }, this);
    315 
    316                 colorTokenElement.append(swatch.element);
    317 
    318                 // Prevent the value from editing when clicking on the swatch.
    319                 swatch.element.addEventListener("mousedown", (event) => { event.stop(); });
    320             }
    321 
    322             colorTokenElement.append(innerElement);
    323             return colorTokenElement;
    324         };
    325 
    326         let pushPossibleColorToken = (text, ...tokens) => {
     359        let pushPossibleColorToken = (text, ...rawTokens) => {
    327360            let color = WI.Color.fromString(text);
    328361            if (color)
    329                 newTokens.push(createColorTokenElement(text, color));
     362                newTokens.push(this._createInlineSwatch(WI.InlineSwatch.Type.Color, text, color));
    330363            else
    331                 newTokens.push(...tokens);
     364                newTokens.push(...rawTokens);
    332365        };
    333366
     
    361394    }
    362395
     396    _addTimingFunctionTokens(tokens, tokenType)
     397    {
     398        let newTokens = [];
     399        let startIndex = NaN;
     400        let openParenthesis = 0;
     401
     402        for (let i = 0; i < tokens.length; i++) {
     403            let token = tokens[i];
     404            if (token.value === tokenType && token.type && token.type.includes("atom")) {
     405                startIndex = i;
     406                openParenthesis = 0;
     407            } else if (token.value === "(" && !isNaN(startIndex))
     408                openParenthesis++;
     409            else if (token.value === ")" && !isNaN(startIndex)) {
     410
     411                openParenthesis--;
     412                if (openParenthesis > 0)
     413                    continue;
     414
     415                let rawTokens = tokens.slice(startIndex, i + 1);
     416                let text = rawTokens.map((token) => token.value).join("");
     417
     418                let valueObject;
     419                let inlineSwatchType;
     420                if (tokenType === "cubic-bezier") {
     421                    valueObject = WI.CubicBezier.fromString(text);
     422                    inlineSwatchType = WI.InlineSwatch.Type.Bezier;
     423                } else if (tokenType === "spring") {
     424                    valueObject = WI.Spring.fromString(text);
     425                    inlineSwatchType = WI.InlineSwatch.Type.Spring;
     426                }
     427
     428                if (valueObject)
     429                    newTokens.push(this._createInlineSwatch(inlineSwatchType, text, valueObject));
     430                else
     431                    newTokens.push(...rawTokens);
     432
     433                startIndex = NaN;
     434            } else if (isNaN(startIndex))
     435                newTokens.push(token);
     436        }
     437
     438        return newTokens;
     439    }
     440
    363441    _handleNameChange()
    364442    {
Note: See TracChangeset for help on using the changeset viewer.