Web Inspector: Styles Redesign: Pasting multiple properties should create properties...
authorwebkit@devinrousso.com <webkit@devinrousso.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Feb 2018 22:52:56 +0000 (22:52 +0000)
committerwebkit@devinrousso.com <webkit@devinrousso.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Feb 2018 22:52:56 +0000 (22:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179622
<rdar://problem/35511170>

Reviewed by Matt Baker.

* UserInterface/Views/SpreadsheetStyleProperty.js:
(WI.SpreadsheetStyleProperty.prototype._remove):
(WI.SpreadsheetStyleProperty.prototype._update):
(WI.SpreadsheetStyleProperty.prototype.spreadsheetTextFieldDidCommit):
(WI.SpreadsheetStyleProperty.prototype._handleNamePaste):
When the user pastes into the name field, parse the text for a list of name-value pairs and
replace the property being edited with the text of those pairs.

* UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
(WI.SpreadsheetCSSStyleDeclarationEditor):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.addBlankProperty):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetStylePropertyFocusMoved):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetStylePropertyAddBlankPropertySoon):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetStylePropertyRemoved):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype._propertiesChanged):
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetCSSStyleDeclarationEditorFocusMoved): Deleted.
Calling `addBlankProperty` will trigger a layout on the next frame, but that might be before
the CSSAgent has had a chance to finish refreshing, so we need a way to defer the creation
of a new property until after we have finished the next layout (which is after the refresh).
Drive-by: fix naming of some delegate functions.
* UserInterface/Models/CSSProperty.js:
(WI.CSSProperty.prototype.replaceWithText):
Provide a way for replacing the property with new text.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228030 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Models/CSSProperty.js
Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js
Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js

index bb6c332..4a14dfa 100644 (file)
@@ -1,3 +1,37 @@
+2018-02-02  Devin Rousso  <webkit@devinrousso.com>
+
+        Web Inspector: Styles Redesign: Pasting multiple properties should create properties instead of a bad property
+        https://bugs.webkit.org/show_bug.cgi?id=179622
+        <rdar://problem/35511170>
+
+        Reviewed by Matt Baker.
+
+        * UserInterface/Views/SpreadsheetStyleProperty.js:
+        (WI.SpreadsheetStyleProperty.prototype._remove):
+        (WI.SpreadsheetStyleProperty.prototype._update):
+        (WI.SpreadsheetStyleProperty.prototype.spreadsheetTextFieldDidCommit):
+        (WI.SpreadsheetStyleProperty.prototype._handleNamePaste):
+        When the user pastes into the name field, parse the text for a list of name-value pairs and
+        replace the property being edited with the text of those pairs.
+
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
+        (WI.SpreadsheetCSSStyleDeclarationEditor):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.addBlankProperty):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetStylePropertyFocusMoved):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetStylePropertyAddBlankPropertySoon):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetStylePropertyRemoved):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype._propertiesChanged):
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.spreadsheetCSSStyleDeclarationEditorFocusMoved): Deleted.
+        Calling `addBlankProperty` will trigger a layout on the next frame, but that might be before
+        the CSSAgent has had a chance to finish refreshing, so we need a way to defer the creation
+        of a new property until after we have finished the next layout (which is after the refresh).
+        Drive-by: fix naming of some delegate functions.
+
+        * UserInterface/Models/CSSProperty.js:
+        (WI.CSSProperty.prototype.replaceWithText):
+        Provide a way for replacing the property with new text.
+
 2018-02-02  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: TabBar redesign: remove New Tab button and add experimental feature flag
 2018-02-02  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: TabBar redesign: remove New Tab button and add experimental feature flag
index ddc2cd4..2a6d64f 100644 (file)
@@ -131,6 +131,11 @@ WI.CSSProperty = class CSSProperty extends WI.Object
         this._updateStyleText(forceRemove);
     }
 
         this._updateStyleText(forceRemove);
     }
 
+    replaceWithText(text)
+    {
+        this._updateOwnerStyleText(this._text, text, true);
+    }
+
     commentOut(disabled)
     {
         console.assert(this._enabled === disabled, "CSS property is already " + (disabled ? "disabled" : "enabled"));
     commentOut(disabled)
     {
         console.assert(this._enabled === disabled, "CSS property is already " + (disabled ? "disabled" : "enabled"));
index 4c7e571..a3134b5 100644 (file)
@@ -39,6 +39,7 @@ WI.SpreadsheetCSSStyleDeclarationEditor = class SpreadsheetCSSStyleDeclarationEd
         this._focused = false;
 
         this._propertyPendingStartEditing = null;
         this._focused = false;
 
         this._propertyPendingStartEditing = null;
+        this._pendingAddBlankPropertyIndexOffset = NaN;
         this._filterText = null;
     }
 
         this._filterText = null;
     }
 
@@ -90,6 +91,9 @@ WI.SpreadsheetCSSStyleDeclarationEditor = class SpreadsheetCSSStyleDeclarationEd
 
         if (this._filterText)
             this.applyFilter(this._filterText);
 
         if (this._filterText)
             this.applyFilter(this._filterText);
+
+        if (!isNaN(this._pendingAddBlankPropertyIndexOffset))
+            this.addBlankProperty(this._propertyViews.length - 1 - this._pendingAddBlankPropertyIndexOffset);
     }
 
     detached()
     }
 
     detached()
@@ -204,6 +208,8 @@ WI.SpreadsheetCSSStyleDeclarationEditor = class SpreadsheetCSSStyleDeclarationEd
 
     addBlankProperty(index)
     {
 
     addBlankProperty(index)
     {
+        this._pendingAddBlankPropertyIndexOffset = NaN;
+
         if (index === -1) {
             // Append to the end.
             index = this._propertyViews.length;
         if (index === -1) {
             // Append to the end.
             index = this._propertyViews.length;
@@ -213,9 +219,9 @@ WI.SpreadsheetCSSStyleDeclarationEditor = class SpreadsheetCSSStyleDeclarationEd
         this.needsLayout();
     }
 
         this.needsLayout();
     }
 
-    spreadsheetCSSStyleDeclarationEditorFocusMoved({direction, movedFromProperty, willRemoveProperty})
+    spreadsheetStylePropertyFocusMoved(propertyView, {direction, willRemoveProperty})
     {
     {
-        let movedFromIndex = this._propertyViews.indexOf(movedFromProperty);
+        let movedFromIndex = this._propertyViews.indexOf(propertyView);
         console.assert(movedFromIndex !== -1, "Property doesn't exist, focusing on a selector as a fallback.");
         if (movedFromIndex === -1) {
             if (this._style.selectorEditable)
         console.assert(movedFromIndex !== -1, "Property doesn't exist, focusing on a selector as a fallback.");
         if (movedFromIndex === -1) {
             if (this._style.selectorEditable)
@@ -254,12 +260,21 @@ WI.SpreadsheetCSSStyleDeclarationEditor = class SpreadsheetCSSStyleDeclarationEd
 
     // SpreadsheetStyleProperty delegate
 
 
     // SpreadsheetStyleProperty delegate
 
+    spreadsheetStylePropertyAddBlankPropertySoon(propertyView, {index})
+    {
+        if (isNaN(index))
+            index = this._propertyViews.length;
+        this._pendingAddBlankPropertyIndexOffset = this._propertyViews.length - index;
+    }
+
     spreadsheetStylePropertyRemoved(propertyView)
     {
         this._propertyViews.remove(propertyView);
 
         for (let index = 0; index < this._propertyViews.length; index++)
             this._propertyViews[index].index = index;
     spreadsheetStylePropertyRemoved(propertyView)
     {
         this._propertyViews.remove(propertyView);
 
         for (let index = 0; index < this._propertyViews.length; index++)
             this._propertyViews[index].index = index;
+
+        this._focused = false;
     }
 
     stylePropertyInlineSwatchActivated()
     }
 
     stylePropertyInlineSwatchActivated()
@@ -322,7 +337,7 @@ WI.SpreadsheetCSSStyleDeclarationEditor = class SpreadsheetCSSStyleDeclarationEd
 
     _propertiesChanged(event)
     {
 
     _propertiesChanged(event)
     {
-        if (this.editing) {
+        if (this.editing && isNaN(this._pendingAddBlankPropertyIndexOffset)) {
             for (let propertyView of this._propertyViews)
                 propertyView.updateStatus();
         } else
             for (let propertyView of this._propertyViews)
                 propertyView.updateStatus();
         } else
index a3c5a83..295d486 100644 (file)
@@ -148,10 +148,15 @@ WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
 
     // Private
 
 
     // Private
 
-    _remove()
+    _remove(replacement = "")
     {
         this.element.remove();
     {
         this.element.remove();
-        this._property.remove();
+
+        if (replacement)
+            this._property.replaceWithText(replacement);
+        else
+            this._property.remove();
+
         this.detached();
 
         if (this._delegate && typeof this._delegate.spreadsheetStylePropertyRemoved === "function")
         this.detached();
 
         if (this._delegate && typeof this._delegate.spreadsheetStylePropertyRemoved === "function")
@@ -196,6 +201,7 @@ WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
         if (this._property.editable && this._property.enabled) {
             this._nameElement.tabIndex = 0;
             this._nameElement.addEventListener("beforeinput", this._handleNameBeforeInput.bind(this));
         if (this._property.editable && this._property.enabled) {
             this._nameElement.tabIndex = 0;
             this._nameElement.addEventListener("beforeinput", this._handleNameBeforeInput.bind(this));
+            this._nameElement.addEventListener("paste", this._handleNamePaste.bind(this));
 
             this._nameTextField = new WI.SpreadsheetTextField(this, this._nameElement, this._nameCompletionDataProvider.bind(this));
 
 
             this._nameTextField = new WI.SpreadsheetTextField(this, this._nameElement, this._nameCompletionDataProvider.bind(this));
 
@@ -265,9 +271,9 @@ WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
             }
         }
 
             }
         }
 
-        if (typeof this._delegate.spreadsheetCSSStyleDeclarationEditorFocusMoved === "function") {
+        if (typeof this._delegate.spreadsheetStylePropertyFocusMoved === "function") {
             // Move focus away from the current property, to the next or previous one, if exists, or to the next or previous rule, if exists.
             // Move focus away from the current property, to the next or previous one, if exists, or to the next or previous rule, if exists.
-            this._delegate.spreadsheetCSSStyleDeclarationEditorFocusMoved({direction, willRemoveProperty, movedFromProperty: this});
+            this._delegate.spreadsheetStylePropertyFocusMoved(this, {direction, willRemoveProperty});
         }
 
         if (willRemoveProperty)
         }
 
         if (willRemoveProperty)
@@ -562,6 +568,23 @@ WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
         this._valueTextField.startEditing();
     }
 
         this._valueTextField.startEditing();
     }
 
+    _handleNamePaste(event)
+    {
+        let text = event.clipboardData.getData("text/plain");
+        if (!text || !text.includes(":"))
+            return;
+
+        event.preventDefault();
+
+        this._remove(text);
+
+        if (this._delegate.spreadsheetStylePropertyAddBlankPropertySoon) {
+            this._delegate.spreadsheetStylePropertyAddBlankPropertySoon(this, {
+                index: parseInt(this._element.dataset.propertyIndex) + 1,
+            });
+        }
+    }
+
     _nameCompletionDataProvider(prefix)
     {
         return WI.CSSCompletions.cssNameCompletions.startsWith(prefix);
     _nameCompletionDataProvider(prefix)
     {
         return WI.CSSCompletions.cssNameCompletions.startsWith(prefix);