Bug 1293211 - part2: fire ready event in SwatchBasedEditorTooltips after widget initialization;r=bgrins
authorJulian Descottes <jdescottes@mozilla.com>
Tue, 09 Aug 2016 09:22:16 +0200
changeset 308584 a98ce7344c9a7192a0127c7e7354500f2ddc288b
parent 308583 b850bd6aa5a38f428359a8d6324650efe8adb5ea
child 308585 05ec8a8570372d94067ef178f0f1737ca107b86d
push id20265
push userjdescottes@mozilla.com
push dateTue, 09 Aug 2016 12:02:41 +0000
treeherderfx-team@a3fb4eb11fcf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1293211
milestone51.0a1
Bug 1293211 - part2: fire ready event in SwatchBasedEditorTooltips after widget initialization;r=bgrins Now that showing a XUL panel is asynchronous, tests need to be able to wait for the complete initialization of the editor tooltips. Waiting for the tooltip 'shown' event is not enough here because tooltips are also waiting for this event to start initializing their widgets. MozReview-Commit-ID: DGTyeVrHNb
devtools/client/shared/widgets/Tooltip.js
--- a/devtools/client/shared/widgets/Tooltip.js
+++ b/devtools/client/shared/widgets/Tooltip.js
@@ -12,16 +12,17 @@ const {CubicBezierWidget} =
 const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
 const {TooltipToggle} = require("devtools/client/shared/widgets/tooltip/TooltipToggle");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {colorUtils} = require("devtools/shared/css-color");
 const Heritage = require("sdk/core/heritage");
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip");
 const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
+const {Task} = require("devtools/shared/task");
 
 loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify");
 loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
 loader.lazyRequireGetter(this, "clearNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
 loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true);
 
 XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
   "resource://devtools/client/shared/widgets/VariablesView.jsm");
@@ -553,16 +554,17 @@ Tooltip.prototype = {
 /**
  * Base class for all (color, gradient, ...)-swatch based value editors inside
  * tooltips
  *
  * @param {Toolbox} toolbox
  *        The devtools toolbox, needed to get the devtools main window.
  */
 function SwatchBasedEditorTooltip(toolbox, stylesheet) {
+  EventEmitter.decorate(this);
   // Creating a tooltip instance
   // This one will consume outside clicks as it makes more sense to let the user
   // close the tooltip by clicking out
   // It will also close on <escape> and <enter>
   this.tooltip = new HTMLTooltip(toolbox, {
     type: "arrow",
     consumeOutsideClicks: true,
     useXulWrapper: true,
@@ -600,34 +602,45 @@ function SwatchBasedEditorTooltip(toolbo
   // activeSwatch property will hold the reference to the swatch DOM element
   // that was clicked
   this.activeSwatch = null;
 
   this._onSwatchClick = this._onSwatchClick.bind(this);
 }
 
 SwatchBasedEditorTooltip.prototype = {
+  /**
+   * Show the editor tooltip for the currently active swatch.
+   *
+   * @return {Promise} a promise that resolves once the editor tooltip is displayed, or
+   *         immediately if there is no currently active swatch.
+   */
   show: function () {
     if (this.activeSwatch) {
+      let onShown = this.tooltip.once("shown");
       this.tooltip.show(this.activeSwatch, "topcenter bottomleft");
 
       // When the tooltip is closed by clicking outside the panel we want to
       // commit any changes.
       this.tooltip.once("hidden", () => {
         if (!this._reverted && !this.eyedropperOpen) {
           this.commit();
         }
         this._reverted = false;
 
         // Once the tooltip is hidden we need to clean up any remaining objects.
         if (!this.eyedropperOpen) {
           this.activeSwatch = null;
         }
       });
+
+      return onShown;
     }
+
+    return Promise.resolve();
   },
 
   hide: function () {
     this.tooltip.hide();
   },
 
   /**
    * Add a new swatch DOM element to the list of swatch elements this editor
@@ -792,19 +805,19 @@ Heritage.extend(SwatchBasedEditorTooltip
 
     return spectrum;
   },
 
   /**
    * Overriding the SwatchBasedEditorTooltip.show function to set spectrum's
    * color.
    */
-  show: function () {
+  show: Task.async(function* () {
     // Call then parent class' show function
-    SwatchBasedEditorTooltip.prototype.show.call(this);
+    yield SwatchBasedEditorTooltip.prototype.show.call(this);
     // Then set spectrum's color and listen to color changes to preview them
     if (this.activeSwatch) {
       this.currentSwatchColor = this.activeSwatch.nextSibling;
       this._originalColor = this.currentSwatchColor.textContent;
       let color = this.activeSwatch.style.backgroundColor;
       this.spectrum.off("changed", this._onSpectrumColorChange);
       this.spectrum.rgb = this._colorToRgba(color);
       this.spectrum.on("changed", this._onSpectrumColorChange);
@@ -815,18 +828,19 @@ Heritage.extend(SwatchBasedEditorTooltip
     target.actorHasMethod("inspector", "pickColorFromPage").then(value => {
       let tooltipDoc = this.tooltip.doc;
       let eyeButton = tooltipDoc.querySelector("#eyedropper-button");
       if (value) {
         eyeButton.addEventListener("click", this._openEyeDropper);
       } else {
         eyeButton.style.display = "none";
       }
+      this.emit("ready");
     }, e => console.error(e));
-  },
+  }),
 
   _onSpectrumColorChange: function (event, rgba, cssColor) {
     this._selectColor(cssColor);
   },
 
   _selectColor: function (color) {
     if (this.activeSwatch) {
       this.activeSwatch.style.backgroundColor = color;
@@ -939,29 +953,30 @@ Heritage.extend(SwatchBasedEditorTooltip
 
     return def.promise;
   },
 
   /**
    * Overriding the SwatchBasedEditorTooltip.show function to set the cubic
    * bezier curve in the widget
    */
-  show: function () {
+  show: Task.async(function* () {
     // Call the parent class' show function
-    SwatchBasedEditorTooltip.prototype.show.call(this);
+    yield SwatchBasedEditorTooltip.prototype.show.call(this);
     // Then set the curve and listen to changes to preview them
     if (this.activeSwatch) {
       this.currentBezierValue = this.activeSwatch.nextSibling;
       this.widget.then(widget => {
         widget.off("updated", this._onUpdate);
         widget.cssCubicBezierValue = this.currentBezierValue.textContent;
         widget.on("updated", this._onUpdate);
+        this.emit("ready");
       });
     }
-  },
+  }),
 
   _onUpdate: function (event, bezier) {
     if (!this.activeSwatch) {
       return;
     }
 
     this.currentBezierValue.textContent = bezier + "";
     this.preview(bezier + "");
@@ -1011,28 +1026,29 @@ Heritage.extend(SwatchBasedEditorTooltip
     let container = doc.createElementNS(XHTML_NS, "div");
     container.id = "filter-container";
 
     this.tooltip.setContent(container, { width: 510, height: 200 });
 
     return new CSSFilterEditorWidget(container, filter);
   },
 
-  show: function () {
+  show: Task.async(function* () {
     // Call the parent class' show function
-    SwatchBasedEditorTooltip.prototype.show.call(this);
+    yield SwatchBasedEditorTooltip.prototype.show.call(this);
     // Then set the filter value and listen to changes to preview them
     if (this.activeSwatch) {
       this.currentFilterValue = this.activeSwatch.nextSibling;
       this.widget.off("updated", this._onUpdate);
       this.widget.on("updated", this._onUpdate);
       this.widget.setCssValue(this.currentFilterValue.textContent);
       this.widget.render();
+      this.emit("ready");
     }
-  },
+  }),
 
   _onUpdate: function (event, filters) {
     if (!this.activeSwatch) {
       return;
     }
 
     // Remove the old children and reparse the property value to
     // recompute them.