Web Inspector: Styles Redesign: Typing semicolon at the end of value should move...
authorwebkit@devinrousso.com <webkit@devinrousso.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Dec 2017 23:13:05 +0000 (23:13 +0000)
committerwebkit@devinrousso.com <webkit@devinrousso.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Dec 2017 23:13:05 +0000 (23:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178498
<rdar://problem/35065995>

Reviewed by Joseph Pecoraro.

* UserInterface/Views/SpreadsheetStypeProperty.js:
(WI.SpreadsheetStypeProperty.prototype._update):
(WI.SpreadsheetStypeProperty.prototype._handleValueBeforeInput):
Only move to the next property if there are no unbalanced quotes. For example, adding a
semicolon after `url("foo` or `url('bar` would not move to the next property.

* UserInterface/Views/SpreadsheetTextField.js:
(WI.SpreadsheetTextField.prototype.valueWithoutSuggestion):
(WI.SpreadsheetTextField.prototype.completionSuggestionsSelectedCompletion):
(WI.SpreadsheetTextField.prototype.completionSuggestionsClickedCompletion):
(WI.SpreadsheetTextField.prototype._handleKeyDownForSuggestionView):
(WI.SpreadsheetTextField.prototype._updateCompletions):
(WI.SpreadsheetTextField.prototype._getPrefix): Deleted.

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

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js
Source/WebInspectorUI/UserInterface/Views/SpreadsheetTextField.js

index 6aae450..be7de3e 100644 (file)
@@ -1,3 +1,25 @@
+2017-12-19  Devin Rousso  <webkit@devinrousso.com>
+
+        Web Inspector: Styles Redesign: Typing semicolon at the end of value should move to the next property
+        https://bugs.webkit.org/show_bug.cgi?id=178498
+        <rdar://problem/35065995>
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/Views/SpreadsheetStypeProperty.js:
+        (WI.SpreadsheetStypeProperty.prototype._update):
+        (WI.SpreadsheetStypeProperty.prototype._handleValueBeforeInput):
+        Only move to the next property if there are no unbalanced quotes. For example, adding a
+        semicolon after `url("foo` or `url('bar` would not move to the next property.
+
+        * UserInterface/Views/SpreadsheetTextField.js:
+        (WI.SpreadsheetTextField.prototype.valueWithoutSuggestion):
+        (WI.SpreadsheetTextField.prototype.completionSuggestionsSelectedCompletion):
+        (WI.SpreadsheetTextField.prototype.completionSuggestionsClickedCompletion):
+        (WI.SpreadsheetTextField.prototype._handleKeyDownForSuggestionView):
+        (WI.SpreadsheetTextField.prototype._updateCompletions):
+        (WI.SpreadsheetTextField.prototype._getPrefix): Deleted.
+
 2017-12-18  Nikita Vasilyev  <nvasilyev@apple.com>
 
         Web Inspector: Styles Redesign: Command-S should save changes in matching CSS resource
index 4ec41ad..c518b23 100644 (file)
@@ -193,6 +193,8 @@ WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
             this._nameTextField = new WI.SpreadsheetTextField(this, this._nameElement, this._nameCompletionDataProvider.bind(this));
 
             this._valueElement.tabIndex = 0;
+            this._valueElement.addEventListener("beforeinput", this._handleValueBeforeInput.bind(this));
+
             this._valueTextField = new WI.SpreadsheetTextField(this, this._valueElement, this._valueCompletionDataProvider.bind(this));
         }
 
@@ -545,6 +547,37 @@ WI.SpreadsheetStyleProperty = class SpreadsheetStyleProperty extends WI.Object
         return WI.CSSCompletions.cssNameCompletions.startsWith(prefix);
     }
 
+    _handleValueBeforeInput(event)
+    {
+        if (event.data !== ";" || event.inputType !== "insertText")
+            return;
+
+        let text = this._valueTextField.valueWithoutSuggestion();
+        let selection = window.getSelection();
+        if (!selection.rangeCount || selection.getRangeAt(0).endOffset !== text.length)
+            return;
+
+        // Find the first and last index (if any) of a quote character to ensure that the string
+        // doesn't contain unbalanced quotes. If so, then there's no way that the semicolon could be
+        // part of a string within the value, so we can assume that it's the property "terminator".
+        const quoteRegex = /["']/g;
+        let start = -1;
+        let end = text.length;
+        let match = null;
+        while (match = quoteRegex.exec(text)) {
+            if (start < 0)
+                start = match.index;
+            end = match.index + 1;
+        }
+
+        if (start !== -1 && !text.substring(start, end).hasMatchingEscapedQuotes())
+            return;
+
+        event.preventDefault();
+        this._valueTextField.stopEditing();
+        this.spreadsheetTextFieldDidCommit(this._valueTextField, {direction: "forward"});
+    }
+
     _valueCompletionDataProvider(prefix)
     {
         let propertyName = this._nameElement.textContent.trim();
index 35ca411..b904ddf 100644 (file)
@@ -58,6 +58,12 @@ WI.SpreadsheetTextField = class SpreadsheetTextField
     get value() { return this._element.textContent; }
     set value(value) { this._element.textContent = value; }
 
+    valueWithoutSuggestion()
+    {
+        let value = this._element.textContent;
+        return value.slice(0, value.length - this.suggestionHint.length);
+    }
+
     get suggestionHint()
     {
         return this._suggestionHintElement.textContent;
@@ -132,7 +138,7 @@ WI.SpreadsheetTextField = class SpreadsheetTextField
 
     completionSuggestionsSelectedCompletion(suggestionsView, selectedText = "")
     {
-        let prefix = this._getPrefix();
+        let prefix = this.valueWithoutSuggestion();
         let completionPrefix = this._getCompletionPrefix(prefix);
 
         this.suggestionHint = selectedText.slice(completionPrefix.length);
@@ -158,7 +164,7 @@ WI.SpreadsheetTextField = class SpreadsheetTextField
         // completionPrefix:            ro
         //        newPrefix:  1px solid
         //     selectedText:            rosybrown
-        let prefix = this._getPrefix();
+        let prefix = this.valueWithoutSuggestion();
         let completionPrefix = this._getCompletionPrefix(prefix);
         let newPrefix = prefix.slice(0, -completionPrefix.length);
 
@@ -191,12 +197,6 @@ WI.SpreadsheetTextField = class SpreadsheetTextField
         }
     }
 
-    _getPrefix()
-    {
-        let value = this._element.textContent;
-        return value.slice(0, value.length - this.suggestionHint.length);
-    }
-
     _handleFocus(event)
     {
         this.startEditing();
@@ -297,7 +297,7 @@ WI.SpreadsheetTextField = class SpreadsheetTextField
         if (event.key === "ArrowRight" && this.suggestionHint) {
             let selection = window.getSelection();
 
-            if (selection.isCollapsed && (selection.focusOffset === this._getPrefix().length || selection.focusNode === this._suggestionHintElement)) {
+            if (selection.isCollapsed && (selection.focusOffset === this.valueWithoutSuggestion().length || selection.focusNode === this._suggestionHintElement)) {
                 event.stop();
                 document.execCommand("insertText", false, this.suggestionHint);
 
@@ -350,7 +350,7 @@ WI.SpreadsheetTextField = class SpreadsheetTextField
         if (!this._completionProvider)
             return;
 
-        let prefix = this._getPrefix();
+        let prefix = this.valueWithoutSuggestion();
         let completionPrefix = this._getCompletionPrefix(prefix);
         let completions = this._completionProvider(completionPrefix);