Title: [161441] trunk/Tools
Revision
161441
Author
a...@apple.com
Date
2014-01-07 11:36:11 -0800 (Tue, 07 Jan 2014)

Log Message

There should be a delay when quickly switching to a different popover at build.webkit.org/dashboard
https://bugs.webkit.org/show_bug.cgi?id=126472

Reviewed by Timothy Hatcher.

Added a delay when quickly switching to a different popover, making it easier to
move mouse pointer from active element to its popover without accidentally opening
a different popover.

Used this code to add a delay before creating a popover. This doesn't change UI
behavior, as there was alerady a delay before it became visible, but it avoids
flooding buildbot server with http requests when quickly moving the mouse over
dashboard page.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Popover.js:
Fixed a case where popover could get stuck. If content was updated while fade-out
transition was already in place, the transition was removed for no good reason.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/PopoverTracker.js:
(PopoverTracker._onblur): While at it, also taught popovers to disappear on window blur.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/Popover.css:
(.popover.step-in): Now that PopoverTracker has a 200ms delay of its own, reduced
popover delay from 1s to 800ms.

Modified Paths

Diff

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Popover.js (161440 => 161441)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Popover.js	2014-01-07 19:35:29 UTC (rev 161440)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Popover.js	2014-01-07 19:36:11 UTC (rev 161441)
@@ -208,12 +208,9 @@
         var targetFrame = this._targetFrame;
         var preferredEdges = this._preferredEdges;
 
-        // Ensure our element is on display so that its metrics can be resolved
-        // or interrupt any pending transition to remove it from display.
+        // Ensure our element is on display so that its metrics can be resolved.
         if (this._element.parentNode !== document.body)
             document.body.appendChild(this._element);
-        else
-            this._element.classList.remove(Dashboard.Popover.FadeOutClassName);
 
         if (this._contentNeedsUpdate) {
             // Reset CSS properties on element so that the element may be sized to fit its content.

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/PopoverTracker.js (161440 => 161441)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/PopoverTracker.js	2014-01-07 19:35:29 UTC (rev 161440)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/PopoverTracker.js	2014-01-07 19:36:11 UTC (rev 161441)
@@ -28,7 +28,7 @@
     BaseObject.call(this);
 
     console.assert(element);
-    console.assert(presentPopoverCallback && typeof presentPopoverCallback == "function");
+    console.assert(presentPopoverCallback && typeof presentPopoverCallback === "function");
 
     this._element = element;
     this._presentPopover = presentPopoverCallback;
@@ -40,46 +40,116 @@
     element.addEventListener("mouseleave", this._mouseExitedPopoverOrElement.bind(this), true);
 };
 
-PopoverTracker._popover = null; // Only one popover may be active at any time.
+// Only one popover may be active at any time. An active popover is not necessarily visible already.
+PopoverTracker._popover = null;
 
+// A candidate timer may be active whether we have an active popover or not.
+PopoverTracker._candidateTracker = null;
+PopoverTracker._candidateTimer = null;
+PopoverTracker.CandidateSwitchDelay = 200;
+
 BaseObject.addConstructorFunctions(PopoverTracker);
 
+PopoverTracker._setCandidatePopoverTracker = function(popoverTracker)
+{
+    console.assert(!popoverTracker || !popoverTracker._active);
+
+    if (PopoverTracker._candidateTracker) {
+        clearTimeout(PopoverTracker._candidateTimer);
+        PopoverTracker._candidateTimer = null;
+    }
+
+    console.assert(!PopoverTracker._candidateTimer);
+    
+    PopoverTracker._candidateTracker = popoverTracker;
+
+    if (popoverTracker)
+        PopoverTracker._candidateTimer = setTimeout(PopoverTracker._candidatePopoverTrackerTimerFired, PopoverTracker.CandidateSwitchDelay);
+}
+
+PopoverTracker._candidatePopoverTrackerTimerFired = function()
+{
+    var hadPopover = !!PopoverTracker._popover;
+    if (hadPopover) {
+        console.assert(PopoverTracker._popover.visible);
+        PopoverTracker._popover.dismissImmediately();
+    }
+    console.assert(!PopoverTracker._popover);
+
+    var tracker = PopoverTracker._candidateTracker;
+
+    PopoverTracker._setCandidatePopoverTracker(null);
+    tracker._showPopover();
+
+    if (PopoverTracker._popover && hadPopover)
+        PopoverTracker._popover.makeVisibleImmediately();
+}
+
+PopoverTracker._onblur = function()
+{
+    if (PopoverTracker._popover)
+        PopoverTracker._popover.dismissImmediately();
+
+    PopoverTracker._setCandidatePopoverTracker(null);
+}
+
+window.addEventListener("blur", PopoverTracker._onblur, true);
+
 PopoverTracker.prototype = {
     constructor: PopoverTracker,
     __proto__: BaseObject.prototype,
 
+    _showPopover: function()
+    {
+        var popover = new Dashboard.Popover(this);
+        if (!this._presentPopover(this._element, popover, this._context))
+            return;
+
+        this._active = true;
+        PopoverTracker._popover = popover;
+        popover.element.addEventListener("mouseenter", this._mouseEnteredPopoverOrElement.bind(this), true);
+        popover.element.addEventListener("mouseleave", this._mouseExitedPopoverOrElement.bind(this), true);
+    },
+
     _mouseEnteredPopoverOrElement: function(event)
     {
         var popover = PopoverTracker._popover;
-        var popoverWasVisible = popover && popover.visible;
+
         if (popover) {
             // Abort fade-out when re-entering the same element or an existing popover.
             if ((this._active && this._element.isSelfOrAncestor(event.toElement))
                 || popover.element.isSelfOrAncestor(event.toElement)) {
                 popover.makeVisibleImmediately();
+                PopoverTracker._setCandidatePopoverTracker(null);
                 return;
             }
 
-            // We entered a different element, dismiss the old popover.
+            // We entered a different element.
+            if (popover.visible) {
+                PopoverTracker._setCandidatePopoverTracker(this);
+                return;
+            }
+
+            // The popover wasn't visible yet, so it was effectively non-existent.
             popover.dismissImmediately();
         }
+
         console.assert(!PopoverTracker._popover);
+        console.assert(!PopoverTracker._candidateTracker);
+        console.assert(!PopoverTracker._candidateTimer);
 
-        var popover = new Dashboard.Popover(this);
-        if (!this._presentPopover(event.target, popover, this._context))
-            return;
-
-        if (popoverWasVisible)
-            popover.makeVisibleImmediately();
-
-        this._active = true;
-        PopoverTracker._popover = popover;
-        popover.element.addEventListener("mouseenter", this._mouseEnteredPopoverOrElement.bind(this), true);
-        popover.element.addEventListener("mouseleave", this._mouseExitedPopoverOrElement.bind(this), true);
+        PopoverTracker._setCandidatePopoverTracker(this);
     },
 
     _mouseExitedPopoverOrElement: function(event)
     {
+        if (this === PopoverTracker._candidateTracker) {
+            if (this._element.isSelfOrAncestor(event.toElement))
+                return;
+            PopoverTracker._setCandidatePopoverTracker(null);
+            return;
+        }
+
         var popover = PopoverTracker._popover;
 
         if (!popover)

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/Popover.css (161440 => 161441)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/Popover.css	2014-01-07 19:35:29 UTC (rev 161440)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/Popover.css	2014-01-07 19:36:11 UTC (rev 161441)
@@ -55,7 +55,9 @@
 
 .popover.step-in {
     transition: opacity 0ms;
-    transition-delay: 1s;
+    /* This is a delay after popover creation. Popover tracking code may add a delay of its own before it decides to create the popover. */
+    /* It is useful to separate the delays because popover creation can be costly, e.g. it can lazily load data from network during the transition. */
+    transition-delay: 800ms;
     opacity: 1;
 }
 

Modified: trunk/Tools/ChangeLog (161440 => 161441)


--- trunk/Tools/ChangeLog	2014-01-07 19:35:29 UTC (rev 161440)
+++ trunk/Tools/ChangeLog	2014-01-07 19:36:11 UTC (rev 161441)
@@ -1,5 +1,32 @@
 2014-01-07  Alexey Proskuryakov  <a...@apple.com>
 
+        There should be a delay when quickly switching to a different popover at build.webkit.org/dashboard
+        https://bugs.webkit.org/show_bug.cgi?id=126472
+
+        Reviewed by Timothy Hatcher.
+
+        Added a delay when quickly switching to a different popover, making it easier to
+        move mouse pointer from active element to its popover without accidentally opening
+        a different popover.
+
+        Used this code to add a delay before creating a popover. This doesn't change UI
+        behavior, as there was alerady a delay before it became visible, but it avoids
+        flooding buildbot server with http requests when quickly moving the mouse over
+        dashboard page.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Popover.js:
+        Fixed a case where popover could get stuck. If content was updated while fade-out
+        transition was already in place, the transition was removed for no good reason.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/PopoverTracker.js:
+        (PopoverTracker._onblur): While at it, also taught popovers to disappear on window blur.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/Popover.css:
+        (.popover.step-in): Now that PopoverTracker has a 200ms delay of its own, reduced
+        popover delay from 1s to 800ms.
+
+2014-01-07  Alexey Proskuryakov  <a...@apple.com>
+
         Improve display of failed builds at build.webkit.org/dashboard
         https://bugs.webkit.org/show_bug.cgi?id=126542
         <rdar://problem/15753550>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to