Bug 606343, part 2, centre arrow on anchor in notification panel, r=dao, a=blocking
authorNeil Deakin <neil@mozilla.com>
Sun, 05 Dec 2010 17:10:36 -0500
changeset 58648 5ce0b1299094b8b52e984edea1a0fe7497382664
parent 58647 d0b7c821c18ae9671a47992e0e40d7742545224b
child 58649 62d5d8bc0ac8b6307f1e2ede7b78763444df46fe
push id17394
push userneil@mozilla.com
push dateSun, 05 Dec 2010 22:12:05 +0000
treeherdermozilla-central@44641ad32c29 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, blocking
bugs606343
milestone2.0b8pre
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 606343, part 2, centre arrow on anchor in notification panel, r=dao, a=blocking
browser/themes/pinstripe/browser/browser.css
browser/themes/winstripe/browser/browser.css
toolkit/content/PopupNotifications.jsm
toolkit/content/tests/widgets/test_arrowpanel.xul
toolkit/content/widgets/popup.xml
toolkit/themes/pinstripe/global/popup.css
toolkit/themes/winstripe/global/popup.css
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -2026,21 +2026,16 @@ toolbarbutton.chevron > .toolbarbutton-m
   -moz-window-shadow: none;
   background-color: transparent;
   margin-top: -3px;
   margin-left: -23px;
   min-width: 280px;
   -moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat;
 }
 
-#notification-popup {
-  margin-left: -16px;
-  margin-right: -16px;
-}
-
 #notification-popup-box {
   margin: 0 3px;
 }
 
 .notification-anchor-icon {
   width: 16px;
   height: 16px;
   margin: 0 2px;
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1854,21 +1854,16 @@ toolbarbutton.bookmark-item[dragover="tr
 }
 
 /* Popup Bounding Box */
 #identity-popup {
   -moz-appearance: menupopup;
   color: MenuText;
 }
 
-/* Notification popup */
-#notification-popup {
-  padding: 10px;
-}
-
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/Geolocation-64.png);
--- a/toolkit/content/PopupNotifications.jsm
+++ b/toolkit/content/PopupNotifications.jsm
@@ -397,17 +397,18 @@ PopupNotifications.prototype = {
     this.panel.hidden = false;
 
     this._refreshPanel(notificationsToShow);
 
     if (this.isPanelOpen && this._currentAnchorElement == anchorElement)
       return;
 
     // Make sure the identity popup hangs in the correct direction.
-    var position = (this.window.getComputedStyle(this.panel, "").direction == "rtl") ? "after_end" : "after_start";
+    var position = (this.window.getComputedStyle(this.panel, "").direction == "rtl") ?
+      "bottomcenter topright" : "bottomcenter topleft";
 
     this._currentAnchorElement = anchorElement;
 
     this.panel.openPopup(anchorElement, position);
     notificationsToShow.forEach(function (n) {
       this._fireCallback(n, "shown");
     }, this);
   },
--- a/toolkit/content/tests/widgets/test_arrowpanel.xul
+++ b/toolkit/content/tests/widgets/test_arrowpanel.xul
@@ -43,16 +43,17 @@ function nextTest()
   var panel = $("panel");
 
   function openPopup(position, anchor, expected, anchorEdge)
   {
     expectedAnchor = $(anchor);
     expectedSide = expected;
     expectedAnchorEdge = anchorEdge;
 
+    panel.removeAttribute("side");
     panel.openPopup(expectedAnchor, position, 0, 0, false, false, null);
   }
 
   openPopup("after_start", "topleft", "top", "left");
   yield;
   openPopup("after_start", "bottomleft", "bottom", "left");
   yield;
   openPopup("before_start", "topleft", "top", "left");
@@ -90,16 +91,34 @@ function nextTest()
   yield;
   openPopup("start_before", "bottomright", "right", "bottom");
   yield;
   openPopup("end_before", "bottomleft", "left", "bottom");
   yield;
   openPopup("end_before", "bottomright", "right", "bottom");
   yield;
 
+  openPopup("topcenter bottomleft", "bottomleft", "bottom", "center left");
+  yield;
+  openPopup("bottomcenter topleft", "topleft", "top", "center left");
+  yield;
+  openPopup("topcenter bottomright", "bottomright", "bottom", "center right");
+  yield;
+  openPopup("bottomcenter topright", "topright", "top", "center right");
+  yield;
+  openPopup("topcenter bottomleft", "middle", "bottom", "center left");
+  yield;
+  openPopup("bottomcenter topleft", "middle", "top", "center left");
+  yield;
+
+  openPopup("leftcenter topright", "middle", "right", "center top");
+  yield;
+  openPopup("rightcenter bottomleft", "middle", "left", "center bottom");
+  yield;
+
   SimpleTest.finish();
   yield;
 }
 
 function checkPanelPosition(panel)
 {
   var anchor = panel.anchorNode;
   var panelRect = panel.getBoundingClientRect();
@@ -115,28 +134,47 @@ function checkPanelPosition(panel)
     case "left":
       ok(labelRect.left > anchorRect.right + 5, "panel label is right");
       break;
     case "right":
       ok(labelRect.right < anchorRect.left - 5, "panel label is left");
       break;
   }
 
+  let iscentered = false;
+  if (expectedAnchorEdge.indexOf("center ") == 0) {
+    expectedAnchorEdge = expectedAnchorEdge.substring(7);
+    iscentered = true;
+  }
+
+  let adj;
   switch (expectedAnchorEdge) {
     case "top":
-      is(panelRect.top, anchorRect.top, "anchored on top");
+      adj = parseInt(getComputedStyle(panel, "").marginTop);
+      if (iscentered)
+        adj += anchorRect.height / 2;
+      is(Math.round(panelRect.top), Math.round(anchorRect.top + adj), "anchored on top");
       break;
     case "bottom":
-      is(panelRect.bottom, anchorRect.bottom, "anchored on bottom");
+      adj = parseInt(getComputedStyle(panel, "").marginBottom);
+      if (iscentered)
+        adj += anchorRect.height / 2;
+      is(Math.round(panelRect.bottom), Math.round(anchorRect.bottom - adj), "anchored on bottom");
       break;
     case "left":
-      is(panelRect.left, anchorRect.left, "anchored on left");
+      adj = parseInt(getComputedStyle(panel, "").marginLeft);
+      if (iscentered)
+        adj += anchorRect.width / 2;
+      is(Math.round(panelRect.left), Math.round(anchorRect.left + adj), "anchored on left ");
       break;
     case "right":
-      is(panelRect.right, anchorRect.right, "anchored on right");
+      adj = parseInt(getComputedStyle(panel, "").marginRight);
+      if (iscentered)
+        adj += anchorRect.width / 2;
+      is(Math.round(panelRect.right), Math.round(anchorRect.right - adj), "anchored on right");
       break;
   }
 
   is(anchor, expectedAnchor, "anchor");
 
   var arrow = document.getAnonymousElementByAttribute(panel, "anonid", "arrow");
   is(arrow.getAttribute("side"), expectedSide, "panel arrow side");
   is(arrow.hidden, false, "panel hidden");
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -274,17 +274,17 @@
             currentFocus = currentFocus.parentNode;
           }
         }
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="arrowpanel" extends="chrome://global/content/bindings/popup.xml#panel">
-    <content flip="both">
+    <content flip="both" side="top" position="bottomcenter topleft">
       <xul:box anonid="container" class="panel-arrowcontainer">
         <xul:box anonid="arrowbox" class="panel-arrowbox">
           <xul:image anonid="arrow" class="panel-arrow"/>
         </xul:box>
         <xul:box class="panel-arrowcontent">
           <xul:box class="panel-inner-arrowcontent" xbl:inherits="align,dir,orient,pack">
             <children/>
           </xul:box>
@@ -321,17 +321,17 @@
           container.orient = "vertical";
           arrowbox.orient = "";
           if (vertPos == 0) {
             hideAnchor = true;
           }
           else {
             arrowbox.pack = popupRect.left + popupRect.width / 2 < anchorRect.left ? "end" : "start";
             if (vertPos == 1) {
-              container.dir = ""; 
+              container.dir = "";
               anchorClass = "top";
             }
             else if (vertPos == -1) {
               container.dir = "reverse"; 
               anchorClass = "bottom";
             }
           }
         }
@@ -339,46 +339,47 @@
           container.orient = "";
           arrowbox.orient = "vertical";
           if (horizPos == 0) {
             hideAnchor = true;
           }
           else {
             arrowbox.pack = popupRect.top + popupRect.height / 2 < anchorRect.top ? "end" : "start";
             if (horizPos == 1) {
-              container.dir = ""; 
+              container.dir = "";
               anchorClass = "left";
             }
             else if (horizPos == -1) {
               container.dir = "reverse";
               anchorClass = "right";
             }
           }
         }
         else {
           hideAnchor = true;
         }
         arrow.hidden = hideAnchor;
         arrow.setAttribute("side", anchorClass);
+        this.setAttribute("side", anchorClass);
 
         // set fading
         var fade = this.getAttribute("fade");
         var fadeDelay = (fade == "fast") ? 1 : fade == "slow" ? 4000 : 0;
         if (fadeDelay) {
           this._fadeTimer = setTimeout(function (self) {
             self.style.opacity = 0.2;
           }, fadeDelay, this);
         }
       ]]>
       </handler>
-      <handler event="popuphiding">
+      <handler event="popuphiding" phase="target">
         clearTimeout(this._fadeTimer);
         this.style.removeProperty("opacity");
       </handler>
-      <handler event="transitionend">
+      <handler event="transitionend" phase="target">
       <![CDATA[
         if (event.propertyName == "opacity") {
           this.hidePopup();
           this.style.removeProperty("opacity");
         }
       ]]>
       </handler>
     </handlers>
--- a/toolkit/themes/pinstripe/global/popup.css
+++ b/toolkit/themes/pinstripe/global/popup.css
@@ -58,16 +58,28 @@ panel[titlebar] {
 }
 
 panel[type="arrow"] {
   -moz-appearance: none;
   background: transparent;
   -moz-transition: opacity 300ms;
 }
 
+panel[type="arrow"][side="top"],
+panel[type="arrow"][side="bottom"] {
+  margin-left: -26px;
+  margin-right: -26px;
+}
+
+panel[type="arrow"][side="left"],
+panel[type="arrow"][side="right"] {
+  margin-top: -26px;
+  margin-bottom: -26px;
+}
+
 .panel-arrowcontent {
   -moz-appearance: none;
   color: white;
   background: -moz-linear-gradient(rgba(85,85,85,1), rgba(75,75,75,.97) 5px, rgba(58,58,58,.97) 17px, rgba(43,43,43,.97) 40px, rgba(40,40,40,.97) 80px, rgba(40,40,40,.97));
   border-radius: 6px;
   box-shadow: 0 0 0 1px rgba(255,255,255,.15) inset,
               0 1px 0 rgba(255,255,255,.05) inset,
               0 0 0 1px rgba(0,0,0,.25);
--- a/toolkit/themes/winstripe/global/popup.css
+++ b/toolkit/themes/winstripe/global/popup.css
@@ -65,16 +65,28 @@ menupopup > menu > menupopup {
 
 panel[type="arrow"] {
   -moz-appearance: none;
   background: transparent;
   border: none;
   -moz-transition: opacity 300ms;
 }
 
+panel[type="arrow"][side="top"],
+panel[type="arrow"][side="bottom"] {
+  margin-left: -25px;
+  margin-right: -25px;
+}
+
+panel[type="arrow"][side="left"],
+panel[type="arrow"][side="right"] {
+  margin-top: -25px;
+  margin-bottom: -25px;
+}
+
 .panel-arrowcontent {
   border-radius: 6px;
 %ifdef WINSTRIPE_AERO
   background-color: rgba(179,230,255,.35);
   background-image: -moz-linear-gradient(rgba(250,253,255,.9), rgba(250,253,255,.75) 20px, rgba(250,253,255,.70) 39px, rgba(250,253,255,0) 41px, rgba(250,253,255,0));
   margin: 5px;
   box-shadow: 0 0 0 1px rgba(255,255,255,.65) inset,
               0 1px 0 rgba(255,255,255,.3) inset,