Bug 1543782: Show the suggestions in case that the css value becomes empty. r=pbro
authorDaisuke Akatsuka <daisuke@birchill.co.jp>
Mon, 02 Sep 2019 03:27:26 +0000
changeset 491070 158098f49ec29039e97d369a75912b133b3a418c
parent 491069 dc0a13baf8c30e816302c8604915510bbaff6f46
child 491071 541172579196ab3639afc21b5f5ebe056bb0bdf6
push id36521
push userbtara@mozilla.com
push dateMon, 02 Sep 2019 09:48:57 +0000
treeherdermozilla-central@db860d4b1007 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1543782
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1543782: Show the suggestions in case that the css value becomes empty. r=pbro Differential Revision: https://phabricator.services.mozilla.com/D43719
devtools/client/inspector/rules/test/browser_rules_gridline-names-autocomplete.js
devtools/client/inspector/rules/test/head.js
devtools/client/inspector/rules/views/text-property-editor.js
devtools/client/shared/inplace-editor.js
--- a/devtools/client/inspector/rules/test/browser_rules_gridline-names-autocomplete.js
+++ b/devtools/client/inspector/rules/test/browser_rules_gridline-names-autocomplete.js
@@ -32,17 +32,17 @@ const changeTestData = [
 const newAreaTestData = [
   ["g", {}, "gap", OPEN, SELECTED, !CHANGE],
   ["VK_DOWN", {}, "grid", OPEN, SELECTED, !CHANGE],
   ["VK_DOWN", {}, "grid-area", OPEN, SELECTED, !CHANGE],
   ["VK_TAB", {}, "", !OPEN, !SELECTED, !CHANGE],
   "grid-line-names-updated",
   ["c", {}, "col1-start", OPEN, SELECTED, CHANGE],
   ["VK_BACK_SPACE", {}, "c", !OPEN, !SELECTED, CHANGE],
-  ["VK_BACK_SPACE", {}, "", !OPEN, !SELECTED, CHANGE],
+  ["VK_BACK_SPACE", {}, "", OPEN, !SELECTED, CHANGE],
   ["r", {}, "revert", OPEN, SELECTED, CHANGE],
   ["VK_DOWN", {}, "row1-start", OPEN, SELECTED, CHANGE],
   ["r", {}, "rr", !OPEN, !SELECTED, CHANGE],
   ["VK_BACK_SPACE", {}, "r", !OPEN, !SELECTED, CHANGE],
   ["o", {}, "row1-start", OPEN, SELECTED, CHANGE],
   ["VK_RETURN", {}, "", !OPEN, !SELECTED, CHANGE],
 ];
 
@@ -53,17 +53,17 @@ const newRowTestData = [
   ["r", {}, "grid", OPEN, SELECTED, !CHANGE],
   ["i", {}, "grid", OPEN, SELECTED, !CHANGE],
   ["d", {}, "grid", OPEN, SELECTED, !CHANGE],
   ["-", {}, "grid-area", OPEN, SELECTED, !CHANGE],
   ["r", {}, "grid-row", OPEN, SELECTED, !CHANGE],
   ["VK_RETURN", {}, "", !OPEN, !SELECTED, !CHANGE],
   "grid-line-names-updated",
   ["c", {}, "c", !OPEN, !SELECTED, CHANGE],
-  ["VK_BACK_SPACE", {}, "", !OPEN, !SELECTED, CHANGE],
+  ["VK_BACK_SPACE", {}, "", OPEN, !SELECTED, CHANGE],
   ["r", {}, "revert", OPEN, SELECTED, CHANGE],
   ["VK_DOWN", {}, "row1-start", OPEN, SELECTED, CHANGE],
   ["VK_TAB", {}, "", !OPEN, !SELECTED, CHANGE],
 ];
 
 const TEST_URL = URL_ROOT + "doc_grid_names.html";
 
 add_task(async function() {
--- a/devtools/client/inspector/rules/test/head.js
+++ b/devtools/client/inspector/rules/test/head.js
@@ -381,17 +381,19 @@ var setProperty = async function(
   textProp,
   value,
   blurNewProperty = true
 ) {
   await focusEditableField(view, textProp.editor.valueSpan);
 
   const onPreview = view.once("ruleview-changed");
   if (value === null) {
+    const onPopupOpened = once(view.popup, "popup-opened");
     EventUtils.synthesizeKey("VK_DELETE", {}, view.styleWindow);
+    await onPopupOpened;
   } else {
     EventUtils.sendString(value, view.styleWindow);
   }
   view.debounce.flush();
   await onPreview;
 
   const onValueDone = view.once("ruleview-changed");
   EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
--- a/devtools/client/inspector/rules/views/text-property-editor.js
+++ b/devtools/client/inspector/rules/views/text-property-editor.js
@@ -339,16 +339,17 @@ TextPropertyEditor.prototype = {
         popup: this.popup,
         multiline: true,
         maxWidth: () => this.container.getBoundingClientRect().width,
         cssProperties: this.cssProperties,
         cssVariables:
           this.rule.elementStyle.variablesMap.get(this.rule.pseudoElement) ||
           [],
         getGridLineNames: this.getGridlineNames,
+        showSuggestCompletionOnEmpty: true,
       });
     }
   },
 
   /**
    * Get the grid line names of the grid that the currently selected element is
    * contained in.
    *
--- a/devtools/client/shared/inplace-editor.js
+++ b/devtools/client/shared/inplace-editor.js
@@ -154,16 +154,19 @@ function isKeyIn(key, ...keys) {
  *      defaults to false
  *    {Object} cssProperties: An instance of CSSProperties.
  *    {Object} cssVariables: A Map object containing all CSS variables.
  *    {Number} defaultIncrement: The value by which the input is incremented
  *      or decremented by default (0.1 for properties like opacity and 1 by default)
  *    {Function} getGridLineNames:
  *       Will be called before offering autocomplete sugestions, if the property is
  *       a member of GRID_PROPERTY_NAMES.
+ *    {Boolean} showSuggestCompletionOnEmpty:
+ *       If true, show the suggestions in case that the current text becomes empty.
+ *       Defaults to false.
  */
 function editableField(options) {
   return editableItem(options, function(element, event) {
     if (!options.element.inplaceEditor) {
       new InplaceEditor(options, event);
     }
   });
 }
@@ -287,16 +290,17 @@ function InplaceEditor(options, event) {
   this.stopOnReturn = !!options.stopOnReturn;
   this.contentType = options.contentType || CONTENT_TYPES.PLAIN_TEXT;
   this.property = options.property;
   this.popup = options.popup;
   this.preserveTextStyles =
     options.preserveTextStyles === undefined
       ? false
       : !!options.preserveTextStyles;
+  this.showSuggestCompletionOnEmpty = !!options.showSuggestCompletionOnEmpty;
 
   this._onBlur = this._onBlur.bind(this);
   this._onWindowBlur = this._onWindowBlur.bind(this);
   this._onKeyPress = this._onKeyPress.bind(this);
   this._onInput = this._onInput.bind(this);
   this._onKeyup = this._onKeyup.bind(this);
   this._onAutocompletePopupClick = this._onAutocompletePopupClick.bind(this);
   this._onContextMenu = this._onContextMenu.bind(this);
@@ -1191,17 +1195,17 @@ InplaceEditor.prototype = {
     if (isPopupOpen && isKeyIn(key, "UP", "DOWN", "PAGE_UP", "PAGE_DOWN")) {
       prevent = true;
       cycling = true;
       this._cycleCSSSuggestion(isKeyIn(key, "UP", "PAGE_UP"));
       this._doValidation();
     }
 
     if (isKeyIn(key, "BACK_SPACE", "DELETE", "LEFT", "RIGHT", "HOME", "END")) {
-      if (isPopupOpen) {
+      if (isPopupOpen && this.currentInputValue !== "") {
         this._hideAutocompletePopup();
       }
     } else if (
       !cycling &&
       !multilineNavigation &&
       !event.metaKey &&
       !event.altKey &&
       !event.ctrlKey
@@ -1390,16 +1394,21 @@ InplaceEditor.prototype = {
     if (this._measurement) {
       this._updateSize();
     }
 
     // Call the user's change handler if available.
     if (this.change) {
       this.change(this.currentInputValue);
     }
+
+    // In case that the current value becomes empty, show the suggestions if needed.
+    if (this.currentInputValue === "" && this.showSuggestCompletionOnEmpty) {
+      this._maybeSuggestCompletion(false);
+    }
   },
 
   /**
    * Stop propagation on the provided event
    */
   _stopEventPropagation: function(e) {
     e.stopPropagation();
   },