Changeset 224174 in webkit


Ignore:
Timestamp:
Oct 30, 2017 1:43:53 AM (6 years ago)
Author:
Nikita Vasilyev
Message:

Web Inspector: [PARITY] Styles Redesign: clicking on the white space after the property should create a blank property
https://bugs.webkit.org/show_bug.cgi?id=178022
<rdar://problem/34861687>

Reviewed by Matt Baker.

  • Clicking on the whitespace on the right side of a property should insert a blank property after the clicked one.
  • Clicking on the whitespace at the end of a CSS rule should append a blank property.
  • Clicking on the whitespace before the first property should insert a blank property before the first one.
  • UserInterface/Models/CSSProperty.js:

(WI.CSSProperty.prototype.remove):
(WI.CSSProperty.prototype._updateOwnerStyleText):
Remove method previously didn't do anything for a newly added property.

  • UserInterface/Models/CSSStyleDeclaration.js:

(WI.CSSStyleDeclaration.prototype.newBlankProperty):
Update indices of all properties after the newly added property.

  • UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:

(WI.SpreadsheetCSSStyleDeclarationEditor):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.startEditingFirstProperty):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.startEditingLastProperty):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.isFocused):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.addBlankProperty):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetCSSStyleDeclarationEditorFocusMoved):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype._propertiesChanged):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype._addBlankProperty): Deleted.
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype._isFocused): Deleted.
Re-layout SpreadsheetCSSStyleDeclarationEditor after adding a new property. Preserve edited property
so we can restore editing state after the re-layout.

  • UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:

(WI.SpreadsheetCSSStyleDeclarationSection):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._handleMouseDown):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._handleClick):
Clicking should add a new property only when we aren't editing an existing property.

  • UserInterface/Views/SpreadsheetStyleProperty.js:

(WI.SpreadsheetStyleProperty):
(WI.SpreadsheetStyleProperty.prototype.updateClassNames):
(WI.SpreadsheetStyleProperty.prototype.spreadsheetTextFieldDidCommit):
Remove newlyAdded property of SpreadsheetStyleProperty. During layout SpreadsheetCSSStyleDeclarationEditor
recreates SpreadsheetStyleProperty views and newlyAdded property gets lost.

  • UserInterface/Views/SpreadsheetTextField.js:

(WI.SpreadsheetTextField.prototype.get valueBeforeEditing):
(WI.SpreadsheetTextField.prototype.startEditing):
(WI.SpreadsheetTextField.prototype.stopEditing):
(WI.SpreadsheetTextField.prototype._discardChange):

Location:
trunk/Source/WebInspectorUI
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r224142 r224174  
     12017-10-30  Nikita Vasilyev  <nvasilyev@apple.com>
     2
     3        Web Inspector: [PARITY] Styles Redesign: clicking on the white space after the property should create a blank property
     4        https://bugs.webkit.org/show_bug.cgi?id=178022
     5        <rdar://problem/34861687>
     6
     7        Reviewed by Matt Baker.
     8
     9        - Clicking on the whitespace on the right side of a property should insert a blank property after the clicked one.
     10        - Clicking on the whitespace at the end of a CSS rule should append a blank property.
     11        - Clicking on the whitespace before the first property should insert a blank property before the first one.
     12
     13        * UserInterface/Models/CSSProperty.js:
     14        (WI.CSSProperty.prototype.remove):
     15        (WI.CSSProperty.prototype._updateOwnerStyleText):
     16        Remove method previously didn't do anything for a newly added property.
     17
     18        * UserInterface/Models/CSSStyleDeclaration.js:
     19        (WI.CSSStyleDeclaration.prototype.newBlankProperty):
     20        Update indices of all properties after the newly added property.
     21
     22        * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
     23        (WI.SpreadsheetCSSStyleDeclarationEditor):
     24        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
     25        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.startEditingFirstProperty):
     26        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.startEditingLastProperty):
     27        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.isFocused):
     28        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.addBlankProperty):
     29        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetCSSStyleDeclarationEditorFocusMoved):
     30        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype._propertiesChanged):
     31        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype._addBlankProperty): Deleted.
     32        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype._isFocused): Deleted.
     33        Re-layout SpreadsheetCSSStyleDeclarationEditor after adding a new property. Preserve edited property
     34        so we can restore editing state after the re-layout.
     35
     36        * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
     37        (WI.SpreadsheetCSSStyleDeclarationSection):
     38        (WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
     39        (WI.SpreadsheetCSSStyleDeclarationSection.prototype._handleMouseDown):
     40        (WI.SpreadsheetCSSStyleDeclarationSection.prototype._handleClick):
     41        Clicking should add a new property only when we aren't editing an existing property.
     42
     43        * UserInterface/Views/SpreadsheetStyleProperty.js:
     44        (WI.SpreadsheetStyleProperty):
     45        (WI.SpreadsheetStyleProperty.prototype.updateClassNames):
     46        (WI.SpreadsheetStyleProperty.prototype.spreadsheetTextFieldDidCommit):
     47        Remove newlyAdded property of SpreadsheetStyleProperty. During layout SpreadsheetCSSStyleDeclarationEditor
     48        recreates SpreadsheetStyleProperty views and newlyAdded property gets lost.
     49
     50        * UserInterface/Views/SpreadsheetTextField.js:
     51        (WI.SpreadsheetTextField.prototype.get valueBeforeEditing):
     52        (WI.SpreadsheetTextField.prototype.startEditing):
     53        (WI.SpreadsheetTextField.prototype.stopEditing):
     54        (WI.SpreadsheetTextField.prototype._discardChange):
     55
    1562017-10-27  Devin Rousso  <webkit@devinrousso.com>
    257
  • trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js

    r222959 r224174  
    122122    {
    123123        // Setting name or value to an empty string removes the entire CSSProperty.
    124         this.name = "";
     124        this._name = "";
     125        const forceRemove = true;
     126        this._updateStyleText(forceRemove);
    125127    }
    126128
     
    326328    // Private
    327329
    328     _updateStyleText()
     330    _updateStyleText(forceRemove = false)
    329331    {
    330332        let text = "";
     
    335337        let oldText = this._text;
    336338        this._text = text;
    337         this._updateOwnerStyleText(oldText, this._text);
    338     }
    339 
    340     _updateOwnerStyleText(oldText, newText)
    341     {
    342         if (oldText === newText)
    343             return;
     339        this._updateOwnerStyleText(oldText, this._text, forceRemove);
     340    }
     341
     342    _updateOwnerStyleText(oldText, newText, forceRemove = false)
     343    {
     344        if (oldText === newText) {
     345            if (forceRemove) {
     346                const lineDelta = 0;
     347                const columnDelta = 0;
     348                this._ownerStyle.shiftPropertiesAfter(this, lineDelta, columnDelta, forceRemove);
     349            }
     350            return;
     351        }
    344352
    345353        let styleText = this._ownerStyle.text || "";
  • trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js

    r223970 r224174  
    358358    }
    359359
    360     newBlankProperty(insertAfterIndex)
     360    newBlankProperty(propertyIndex)
    361361    {
    362362        let text, name, value, priority, overridden, implicit, anonymous;
    363363        let enabled = true;
    364364        let valid = false;
    365         let styleSheetTextRange = this._rangeAfterPropertyAtIndex(insertAfterIndex);
    366 
    367         let propertyIndex = insertAfterIndex + 1;
     365        let styleSheetTextRange = this._rangeAfterPropertyAtIndex(propertyIndex - 1);
     366
    368367        let property = new WI.CSSProperty(propertyIndex, text, name, value, priority, enabled, overridden, implicit, anonymous, valid, styleSheetTextRange);
    369368
    370369        this._allProperties.insertAtIndex(property, propertyIndex);
     370        for (let index = propertyIndex + 1; index < this._allProperties.length; index++)
     371            this._allProperties[index].index = index;
     372
    371373        const suppressEvents = true;
    372374        this.update(this._text, this._allProperties, this._styleSheetTextRange, suppressEvents);
  • trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js

    r223970 r224174  
    3535        this.style = style;
    3636        this._propertyViews = [];
     37        this._propertyPendingStartEditing = null;
    3738    }
    3839
     
    4849        this.element.classList.toggle("no-properties", !properties.length);
    4950
     51        // FIXME: Only re-layout properties that have been modified and preserve focus whenever possible.
    5052        this._propertyViews = [];
     53
     54        let propertyViewPendingStartEditing = null;
    5155        for (let index = 0; index < properties.length; index++) {
    5256            let property = properties[index];
    53             let propertyView = new WI.SpreadsheetStyleProperty(this, property);
     57            let propertyView = new WI.SpreadsheetStyleProperty(this, property, index);
    5458            this.element.append(propertyView.element);
    5559            this._propertyViews.push(propertyView);
     60
     61            if (property === this._propertyPendingStartEditing)
     62                propertyViewPendingStartEditing = propertyView;
     63        }
     64
     65        if (propertyViewPendingStartEditing) {
     66            propertyViewPendingStartEditing.nameTextField.startEditing();
     67            this._propertyPendingStartEditing = null;
    5668        }
    5769    }
     
    90102        else {
    91103            let index = 0;
    92             this._addBlankProperty(index);
     104            this.addBlankProperty(index);
    93105        }
    94106    }
     
    101113        else {
    102114            let index = 0;
    103             this._addBlankProperty(index);
     115            this.addBlankProperty(index);
    104116        }
    105117    }
     
    144156
    145157        return false;
     158    }
     159
     160    isFocused()
     161    {
     162        let focusedElement = document.activeElement;
     163
     164        if (!focusedElement || focusedElement.tagName === "BODY")
     165            return false;
     166
     167        return focusedElement.isSelfOrDescendant(this.element);
     168    }
     169
     170    addBlankProperty(index)
     171    {
     172        if (index === -1) {
     173            // Append to the end.
     174            index = this._propertyViews.length;
     175        }
     176
     177        this._propertyPendingStartEditing = this._style.newBlankProperty(index);
     178        this.needsLayout();
    146179    }
    147180
     
    168201                    this._delegate.cssStyleDeclarationEditorStartEditingAdjacentRule(reverse);
    169202                } else
    170                     this._addBlankProperty(movedFromIndex);
     203                    this.addBlankProperty(index);
    171204            }
    172205        } else {
     
    200233    }
    201234
    202     _addBlankProperty(afterIndex)
    203     {
    204         let blankProperty = this._style.newBlankProperty(afterIndex);
    205         const newlyAdded = true;
    206         let propertyView = new WI.SpreadsheetStyleProperty(this, blankProperty, newlyAdded);
    207         this.element.append(propertyView.element);
    208         this._propertyViews.push(propertyView);
    209         propertyView.nameTextField.startEditing();
    210     }
    211 
    212     _isFocused()
    213     {
    214         let focusedElement = document.activeElement;
    215 
    216         if (!focusedElement || focusedElement.tagName === "BODY")
    217             return false;
    218 
    219         return focusedElement.isSelfOrDescendant(this.element);
    220     }
    221 
    222235    _propertiesChanged(event)
    223236    {
    224         if (this._isFocused()) {
     237        if (this.isFocused()) {
    225238            for (let propertyView of this._propertyViews)
    226239                propertyView.updateClassNames();
  • trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js

    r224064 r224174  
    3838        this._propertiesEditor = null;
    3939        this._selectorElements = [];
     40        this._wasFocused = false;
    4041    }
    4142
     
    5556        super.initialLayout();
    5657
    57         this._headerElement = document.createElement("span");
     58        this._headerElement = document.createElement("div");
    5859        this._headerElement.classList.add("header");
    5960
     
    6667        this._headerElement.append(this._selectorElement);
    6768
     69        let openBrace = document.createElement("span");
     70        openBrace.classList.add("open-brace");
     71        openBrace.textContent = " {";
     72        this._headerElement.append(openBrace);
     73
    6874        if (this._style.selectorEditable) {
    6975            this._selectorTextField = new WI.SpreadsheetSelectorField(this, this._selectorElement);
     
    7480        this._propertiesEditor.element.classList.add("properties");
    7581
    76         let openBrace = document.createElement("span");
    77         openBrace.classList.add("open-brace");
    78         openBrace.textContent = " {";
    79 
    8082        let closeBrace = document.createElement("span");
    8183        closeBrace.classList.add("close-brace");
    8284        closeBrace.textContent = "}";
    8385
    84         this._element.append(this._createMediaHeader(), this._headerElement, openBrace);
     86        this._element.append(this._createMediaHeader(), this._headerElement);
    8587        this.addSubview(this._propertiesEditor);
    8688        this._propertiesEditor.needsLayout();
     
    9193        else if (!this._style.ownerRule)
    9294            this._element.classList.add("selector-locked");
     95
     96        if (this._style.editable) {
     97            this.element.addEventListener("click", this._handleClick.bind(this));
     98            this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));
     99        }
    93100    }
    94101
     
    336343        return mediaElement;
    337344    }
     345
     346    _handleMouseDown(event)
     347    {
     348        this._wasFocused = this._propertiesEditor.isFocused();
     349    }
     350
     351    _handleClick(event)
     352    {
     353        if (this._wasFocused)
     354            return;
     355
     356        event.stop();
     357
     358        if (event.target.classList.contains(WI.SpreadsheetStyleProperty.StyleClassName)) {
     359            let propertyIndex = parseInt(event.target.dataset.propertyIndex);
     360            this._propertiesEditor.addBlankProperty(propertyIndex + 1);
     361            return;
     362        }
     363
     364        if (event.target.isSelfOrDescendant(this._headerElement)) {
     365            this._propertiesEditor.addBlankProperty(0);
     366            return;
     367        }
     368
     369        const appendAfterLast = -1;
     370        this._propertiesEditor.addBlankProperty(appendAfterLast);
     371    }
    338372};
    339373
  • trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js

    r223978 r224174  
    2626WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
    2727{
    28     constructor(delegate, property, newlyAdded = false)
     28    constructor(delegate, property, index)
    2929    {
    3030        super();
     
    3434        this._delegate = delegate || null;
    3535        this._property = property;
    36         this._newlyAdded = newlyAdded;
    3736        this._element = document.createElement("div");
     37        this._element.dataset.propertyIndex = index;
    3838
    3939        this._nameElement = null;
     
    8787        };
    8888
    89         let classNames = ["property"];
     89        let classNames = [WI.SpreadsheetStyleProperty.StyleClassName];
    9090
    9191        if (this._property.overridden)
     
    200200        let propertyValue = this._valueTextField.value.trim();
    201201        let willRemoveProperty = false;
     202        let newlyAdded = this._valueTextField.valueBeforeEditing === "";
    202203
    203204        // Remove a property with an empty name or value. However, a newly added property
    204205        // has an empty name and value at first. Don't remove it when moving focus from
    205206        // the name to the value for the first time.
    206         if (!propertyName || (!this._newlyAdded && !propertyValue))
     207        if (!propertyName || (!newlyAdded && !propertyValue))
    207208            willRemoveProperty = true;
    208209
     
    211212        if (!isEditingName && !willRemoveProperty)
    212213            this._renderValue(propertyValue);
    213 
    214         if (propertyName && isEditingName)
    215             this._newlyAdded = false;
    216214
    217215        if (direction === "forward") {
     
    489487};
    490488
     489WI.SpreadsheetStyleProperty.StyleClassName = "property";
     490
    491491WI.SpreadsheetStyleProperty.CommitCoalesceDelay = 250;
  • trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetTextField.js

    r223453 r224174  
    4747
    4848        this._editing = false;
    49         this._startEditingValue = "";
     49        this._valueBeforeEditing = "";
    5050    }
    5151
     
    5858    get value() { return this._element.textContent; }
    5959    set value(value) { this._element.textContent = value; }
     60
     61    get valueBeforeEditing() { return this._valueBeforeEditing; }
    6062
    6163    get suggestionHint()
     
    8486
    8587        this._editing = true;
    86         this._startEditingValue = this.value;
     88        this._valueBeforeEditing = this.value;
    8789
    8890        this._element.classList.add("editing");
     
    103105
    104106        this._editing = false;
    105         this._startEditingValue = "";
     107        this._valueBeforeEditing = "";
    106108        this._element.classList.remove("editing");
    107109        this._element.contentEditable = false;
     
    170172    _discardChange()
    171173    {
    172         if (this._startEditingValue !== this.value) {
    173             this.value = this._startEditingValue;
     174        if (this._valueBeforeEditing !== this.value) {
     175            this.value = this._valueBeforeEditing;
    174176            this._selectText();
    175177
Note: See TracChangeset for help on using the changeset viewer.