Bug 242621 Move Autoscroll Icon Out of the DOM (SeaMonkey-style autoscroll)Patch by me and Michael Ventnor <ventnor.bugzilla@yahoo.com.au>Icons by Dão Gottwald <dao@design-noir.de>ui-review=beltzner, r=mano
authorcst@yecc.com
Thu, 14 Jun 2007 19:36:38 -0700
changeset 2428 b82e108370c575b761f78e7ce1f5d0fef964fd64
parent 2427 dbf298da2f861cfac5d790c9dee8e8a3d9389c7b
child 2429 7fa84e21c4292636312e1b679b655f52d448b49e
push idunknown
push userunknown
push dateunknown
reviewersmano
bugs242621
milestone1.9a6pre
Bug 242621 Move Autoscroll Icon Out of the DOM (SeaMonkey-style autoscroll)Patch by me and Michael Ventnor <ventnor.bugzilla@yahoo.com.au>Icons by Dão Gottwald <dao@design-noir.de>ui-review=beltzner, r=mano
toolkit/content/jar.mn
toolkit/content/widgets/browser.xml
toolkit/themes/gnomestripe/global/global.css
toolkit/themes/gnomestripe/global/popup.css
toolkit/themes/pinstripe/global/global.css
toolkit/themes/pinstripe/global/icons/autoscroll.png
toolkit/themes/pinstripe/global/jar.mn
toolkit/themes/winstripe/global/global.css
toolkit/themes/winstripe/global/icons/autoscroll.png
toolkit/themes/winstripe/global/jar.mn
--- a/toolkit/content/jar.mn
+++ b/toolkit/content/jar.mn
@@ -67,17 +67,14 @@ toolkit.jar:
 *+ content/global/bindings/tabbrowser.xml      (widgets/tabbrowser.xml)
 *+ content/global/bindings/text.xml            (widgets/text.xml)
 *+ content/global/bindings/textbox.xml         (widgets/textbox.xml)
 *+ content/global/bindings/toolbar.xml         (widgets/toolbar.xml)
 *+ content/global/bindings/toolbarbutton.xml   (widgets/toolbarbutton.xml)
 *+ content/global/bindings/tree.xml            (widgets/tree.xml)
 *+ content/global/bindings/wizard.xml          (widgets/wizard.xml)
 *+ content/global/bindings/findbar.xml         (widgets/findbar.xml)
-   content/global/bindings/autoscroll_all.png  (widgets/autoscroll_all.png)
-   content/global/bindings/autoscroll_h.png    (widgets/autoscroll_h.png)
-   content/global/bindings/autoscroll_v.png    (widgets/autoscroll_v.png)
 #ifdef XP_MACOSX
 *  content/global/macWindowMenu.js             (macWindowMenu.js)
 #endif
 #ifdef MOZ_SVG
    content/global/svg/svgBindings.xml          (/layout/svg/base/src/resources/content/svgBindings.xml)
 #endif
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -18,16 +18,18 @@
    - The Initial Developer of the Original Code is
    - Peter Annema.
    - Portions created by the Initial Developer are Copyright (C) 2001
    - the Initial Developer. All Rights Reserved.
    -
    - Contributor(s):
    -   Peter Annema <disttsc@bart.nl> (Original Author of <browser>)
    -   Peter Parente <parente@cs.unc.edu>
+   -   Christopher Thomas <cst@yecc.com>
+   -   Michael Ventnor <m.ventnor@gmail.com>
    -
    - Alternatively, the contents of this file may be used under the terms of
    - either the GNU General Public License Version 2 or later (the "GPL"), or
    - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    - in which case the provisions of the GPL or the LGPL are applicable instead
    - of those above. If you wish to allow use of your version of this file only
    - under the terms of either the GPL or the LGPL, and not to allow others to
    - use your version of this file under the terms of the MPL, indicate your
@@ -454,18 +456,18 @@
               this.updatePageReport();
             }
             if (!this.docShell || !this.fastFind)
               return;
             var tabBrowser = this.getTabBrowser();
             if (!tabBrowser || tabBrowser.mCurrentBrowser == this)
               this.fastFind.setDocShell(this.docShell);
 
-            if (this._isScrolling)
-              this.stopScroll();
+            if (this._scrollingView)
+              this._autoScrollPopup.hidePopup();
          ]]>
         </body>
       </method>
 
       <method name="updatePageReport">
         <body>
           <![CDATA[
             var tabBrowser = this.getTabBrowser();
@@ -665,50 +667,92 @@
             if (purge > 0)
               this.sessionHistory.PurgeHistory(purge);
           ]]>
         </body>
       </method>
           
       <field name="_AUTOSCROLL_SPEED">3</field>
       <field name="_AUTOSCROLL_SNAP">10</field>
-      <field name="_clientFrameDoc">null</field>
-      <field name="_isScrolling">false</field>
-      <field name="_autoScrollMarkerImage">null</field>
-      <field name="_snapOn">false</field>
+      <field name="_scrollingView">null</field>
+      <field name="_autoScrollTimer">null</field>
       <field name="_startX">null</field>
       <field name="_startY">null</field>
       <field name="_screenX">null</field>
       <field name="_screenY">null</field>
+      <field name="_autoScrollPopup">null</field>
 
       <method name="stopScroll">
         <body>
           <![CDATA[
-            this._isScrolling = false;
-            this.removeEventListener("mousemove", this, false);
-            this.contentDocument.removeEventListener("blur", this, true);
-            if (this._autoScrollMarkerImage) {
-              this._autoScrollMarkerImage.style.display = 'none';  // seems to avoid blocking when autoscroll is initited during pageload
-              this._autoScrollMarkerImage.parentNode.removeChild(this._autoScrollMarkerImage);
+            if (this._scrollingView) {
+              this._scrollingView = null;
+              window.removeEventListener("mousemove", this, true);
+              window.removeEventListener("mousedown", this, true);
+              window.removeEventListener("mouseup", this, true);
+              window.removeEventListener("contextmenu", this, true);
+              clearInterval(this._autoScrollTimer);
             }
-            this._autoScrollMarkerImage = null;
          ]]>
        </body>
      </method>
      
+      <method name="startScroll">
+        <parameter name="event"/>
+        <body>
+          <![CDATA[
+            // if the tabbrowser didn't point us to a cached popup, we're not in a tabbrowser, so use global scope
+           if (!this._autoScrollPopup) {
+              const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+              this._autoScrollPopup = document.createElementNS(XUL_NS, "popup");
+              this._autoScrollPopup.id = "autoscroller";
+              this._autoScrollPopup.addEventListener("popuphidden", this, true);
+              document.documentElement.appendChild(this._autoScrollPopup);
+            }
+            this._scrollingView = event.originalTarget.ownerDocument.defaultView;
+            if (this._scrollingView.scrollMaxX > 0) {
+              this._autoScrollPopup.setAttribute("scrolldir", this._scrollingView.scrollMaxY > 0 ? "NSEW" : "EW");
+            }
+            else if (this._scrollingView.scrollMaxY > 0) {
+              this._autoScrollPopup.setAttribute("scrolldir", "NS");
+            }
+            else {
+              this._scrollingView = null; // abort scrolling
+              return;
+            }
+
+            document.popupNode = null;
+            this._autoScrollPopup.showPopup(document.documentElement,
+                                            event.screenX,
+                                            event.screenY,
+                                            "popup", null, null);
+            this._ignoreMouseEvents = true;
+            this._startX = event.screenX;
+            this._startY = event.screenY;
+            this._screenX = event.screenX;
+            this._screenY = event.screenY;
+
+            window.addEventListener("mousemove", this, true);
+            window.addEventListener("mousedown", this, true);
+            window.addEventListener("mouseup", this, true);
+            window.addEventListener("contextmenu", this, true);
+
+            this._autoScrollTimer = setInterval(function(self) { self.autoScrollLoop(); },
+                                                20, this);
+         ]]>
+       </body>
+     </method>
+
      <method name="autoScrollLoop">
        <body>
          <![CDATA[
-           if (this._isScrolling) {
-             var x = (this._screenX - this._startX) / this._AUTOSCROLL_SPEED;
-             var y = (this._screenY - this._startY) / this._AUTOSCROLL_SPEED;
+           var x = (this._screenX - this._startX) / this._AUTOSCROLL_SPEED;
+           var y = (this._screenY - this._startY) / this._AUTOSCROLL_SPEED;
 
-             this._clientFrameDoc.defaultView.scrollBy(x, y);
-             setTimeout(function foo(a) { a.autoScrollLoop() }, 20, this);
-           }
+           this._scrollingView.scrollBy(x, y);
          ]]>
        </body>
      </method>
      <method name="isAutoscrollBlocker">
        <parameter name="node"/>
        <body>
          <![CDATA[
            var mmPaste = false;
@@ -738,85 +782,48 @@
                return true;
 
              node = node.parentNode;
            }
            return false;
          ]]>
        </body>
      </method>
-     <method name="showAutoscrollMarker">
-       <parameter name="evt"/>
-       <body>
-         <![CDATA[
-           var scrollCursor  = new Array("n-resize", "move",  "e-resize");
-           var scrollImages  = new Array("chrome://global/content/bindings/autoscroll_v.png",
-                                         "chrome://global/content/bindings/autoscroll_all.png",
-                                         "chrome://global/content/bindings/autoscroll_h.png");
-           var left = evt.clientX;
-           var top = evt.clientY;
-
-           var scrollType = 1;
-           if (this._clientFrameDoc.defaultView.scrollMaxY > 0) scrollType--;
-           if (this._clientFrameDoc.defaultView.scrollMaxX > 0) scrollType++;           
-           
-           var imageWidth = 28;
-           var imageHeight = 28;
-           
-           // marker
-           var el = this._clientFrameDoc.createElementNS("http://www.w3.org/1999/xhtml", "img");
-           
-           el.src = scrollImages[scrollType];         
-           el.style.position = "fixed";
-           el.style.left = left - imageWidth / 2 + "px";
-           el.style.top = top - imageHeight / 2 + "px";
-           el.style.width = imageWidth + "px";
-           el.style.height = imageHeight + "px";
-           el.style.cursor = scrollCursor[scrollType];
-           el.style.zIndex = 2147483647; //Max Int
-           el.style.borderStyle = "none";
-           el.style.padding = "0";
-           el.style.margin = "0";
-
-           this._clientFrameDoc.documentElement.appendChild(el);
-           
-           this._autoScrollMarkerImage = el;
-         ]]>
-       </body>
-     </method>
-     <method name="_handleMouseMove">
-        <parameter name="aEvent"/>
-        <body>
-        <![CDATA[
-          this._screenX = aEvent.screenX;
-          this._screenY = aEvent.screenY;
-        
-          if (this._isScrolling) {
-            var x = this._screenX - this._startX;
-            var y = this._screenY - this._startY;
-        
-            if ((x > this._AUTOSCROLL_SNAP || x < -this._AUTOSCROLL_SNAP) ||
-                (y > this._AUTOSCROLL_SNAP || y < -this._AUTOSCROLL_SNAP))
-              this._snapOn = false;
-          }
-        ]]>
-        </body>
-      </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body>
         <![CDATA[
-          switch (aEvent.type) {
-            case "mousemove":
-              this._handleMouseMove(aEvent);
-              break;
-            case "blur":
-              if (aEvent.target == this.contentDocument)
+          if (this._scrollingView) {
+            switch(aEvent.type) {
+              case "mousemove": {
+                this._screenX = aEvent.screenX;
+                this._screenY = aEvent.screenY;
+
+                var x = this._screenX - this._startX;
+                var y = this._screenY - this._startY;
+        
+                if ((x > this._AUTOSCROLL_SNAP || x < -this._AUTOSCROLL_SNAP) ||
+                    (y > this._AUTOSCROLL_SNAP || y < -this._AUTOSCROLL_SNAP))
+                  this._ignoreMouseEvents = false;
+                break;
+              }
+              case "mouseup":
+              case "mousedown":
+              case "contextmenu": {
+                if (!this._ignoreMouseEvents)
+                  this._autoScrollPopup.hidePopup();
+                this._ignoreMouseEvents = false;
+                break;
+              }
+              case "popuphidden": {
                 this.stopScroll();
+                break;
+              }
+            }
           }
         ]]>
         </body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="keypress" keycode="VK_F7" group="system">
@@ -860,44 +867,25 @@
 
           // Toggle the pref
           try {
             this.mPrefs.setBoolPref("accessibility.browsewithcaret",!browseWithCaretOn);
           } catch (ex) {
           }
         ]]>
       </handler>
-      <handler event="mouseup">
+      <handler event="mousedown" phase="capturing">
         <![CDATA[
-          if (!this.autoscrollEnabled)
-            return;
-          if (!this._snapOn)
-            this.stopScroll();
-        ]]>        
-      </handler>
-      <handler event="mousedown">
-        <![CDATA[
-          if (this._isScrolling) {
-            stopScroll();
-          } else if (event.button == 1) {
+          if (!this._scrollingView && event.button == 1) {
             if (!this.autoscrollEnabled  ||
                 this.currentURI.spec == "about:blank"|| 
                 this.isAutoscrollBlocker(event.originalTarget))
               return;
-            this.addEventListener("mousemove", this, false);
-            this.contentDocument.addEventListener("blur", this, true);
-            this._screenX = event.screenX;
-            this._screenY = event.screenY;
-            this._startX = event.screenX;
-            this._startY = event.screenY;
-            this._clientFrameDoc = event.originalTarget.ownerDocument;
-            this._isScrolling = true;
-            this._snapOn = true; 
-            this.showAutoscrollMarker(event);
-            window.setTimeout(function foo(a) { a.autoScrollLoop() }, 20, this);
+
+            this.startScroll(event);
           }
         ]]>
       </handler>
     </handlers>
 
   </binding>
 
 </bindings>
--- a/toolkit/themes/gnomestripe/global/global.css
+++ b/toolkit/themes/gnomestripe/global/global.css
@@ -180,8 +180,30 @@ sidebarheader > label {
   -moz-padding-start: 4px;
 }
 
 /* ::::: miscellaneous ::::: */
 
 .toolbar-focustarget {
   -moz-user-focus: ignore !important;
 }
+
+/* :::::: autoscroll popup ::::: */
+
+#autoscroller {
+  height: 28px;
+  width: 28px;
+  border: none;
+  margin: -14px;
+  padding: 0;
+  background-position: center top;
+  background-image: url("chrome://global/skin/icons/autoscroll.png");
+  background-color: transparent;
+  -moz-appearance: none;
+}
+
+#autoscroller[scrolldir="NS"] {
+  background-position: center center;
+}
+
+#autoscroller[scrolldir="EW"] {
+  background-position: center bottom;
+}
--- a/toolkit/themes/gnomestripe/global/popup.css
+++ b/toolkit/themes/gnomestripe/global/popup.css
@@ -40,17 +40,17 @@
   == Styles used by the XUL popup element.
   ======================================================================= */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 /* ::::: menupopup ::::: */
 
 menupopup, popup {
-  -moz-appearance: menupopup !important;
+  -moz-appearance: menupopup;
   min-width: 1px;
 }
 
 /* ::::: tooltip ::::: */
 
 tooltip {
   -moz-appearance: tooltip;
   margin-top: 21px;
--- a/toolkit/themes/pinstripe/global/global.css
+++ b/toolkit/themes/pinstripe/global/global.css
@@ -229,8 +229,28 @@ browser {
 #OCSPDialog {
   font: message-box;
 }
 
 #historyTree, #bookmarks-view {
 	border-top: 1px solid #bebebe;
 }
 
+/* :::::: autoscroll popup ::::: */
+
+#autoscroller {
+  height: 28px;
+  width: 28px;
+  border: none;
+  margin: -14px;
+  padding: 0;
+  background-image: url("chrome://global/skin/icons/autoscroll.png");
+  background-color: transparent;
+  -moz-appearance: none;
+}
+
+#autoscroller[scrolldir="NS"] {
+  background-position: left center;
+}
+
+#autoscroller[scrolldir="EW"] {
+  background-position: left bottom;
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e460930a9e714469eb39c8918643ffa81baef2e5
GIT binary patch
literal 3369
zc$@(#4c79BP)<h;3K|Lk000e1NJLTq002|~002}71^@s69BUB400007bV*G`2iF7*
z4IDb`rtg*j000SaNLh0L01FZT01FZU(%pXi00004XF*Lt006O%3;baP000cQNkl<Z
zc-rk;2}~4A8m<{Y@jyHt&m(vvio}f<D1xB!6mMg^@IW-KqA|Xhjk+FLMU4{OWPRBf
zUtABo<FzUt>_Y_)5U<r;F@pE8DhlF(0?Il2{k=4=>FMd|>FEaEGGEeRy1J_VuD}1P
z|F5c#GBCzWtZHGfF~7;q^48$$?d=`dty{Ojo}Qjw9v&VI+}zw;=s{jyUP*R#cERh{
zub<q#dpGgHg9n$9TwtwnCO}sWRtPf~lqjUq%bYuRj=8$Ja=*WQ`^E+j9xT-cHE`+B
zp~JM`;NbDNn6Izz`!;Rbyld2`(YHEv>XaIdMib;YfByX0_0_9a-(_TEG`n!&f^%|m
za@^y`k7Ma|ehUgU?cBMOb?VfKwQALhHEr6I)vsTlIXO9TWlKs*SV2Jn`}pxA%goGV
zj~+c@GiT0Jqg3CJkdQy3tXo)E*wYp*T6_^c95-&<Kq#^vK4!cyJtrrpK|(@8$Jp4|
zqQu0+KO^auWFu@vbaXU#*$QTPc;TL*0VXKQR9swaRUVXUdh_Ou2@T`xRcaN(Crp@d
z93NvdRV}`zPMvz5uW!VN5vfvno<D#7SLBOBp7CZz!)&zB)vH%mx?i<wmEy7%EY!4V
z(<T!v#^B@QQ_;PZ$}21^WEk5Rx}#~~!i5GVZ>>Y2%!qB<w!L(BcQ@;@)22-e+P{B)
zs4xvmy?Xle>9gXz`T6;E=FOYecJJQ3f5+`HRSFe1&Q_&LDAcrJ!v@o^VZ#hvyLRQe
zwi<b*rKOxw<KyE^ix)4pq}1+kJWEniQl4O(EEPWt4-XGMbm-7PDR~$cuAe-4G67?2
zB}HNQaq8c{zt`>Cw>RVV3Z)qpX+oxP)}C2I-@bh-DU<)WO5~N5m2rQmY?m%wSYTkF
zCF`sUL~Y-`{h?TyR7X@)RG(wVjs>~6xD-QaMWU-1!%A;-@sOgTqDu8+d@qHCX5cRk
z<c%mzk%cN%m^DikS*QsOWRoUMVhtNM)I{FbuV2~W!-v_788d`(2(!kIAK&H3kt6xy
zI!K{6Z{BprM=`;(OUj`<P^Qt}-#^#c+1X54vu4e5g)_~<&rQ|k<xR_$Eo1oV6s~A0
zgFOGPUAx%&_3L?A4WO*e4<9~ELzv{QN4v7JvT|FuZruaUbfIjQSJRc1mO%i`g-2S;
zYuBzFLl`7X3cyEu4Q09s6X(yL?+4}Aw^bg(DW{DaH+l=ZfAi+e8^L;?;b(|Nh1xSN
zDk)229>yol<zXCTa6ZDvJ*G^V@`efg1v#LtTepT$H@8(5hNn`L4IDaj=x{-@Vfysx
znfUuVNrl?eIHh$6ySmo$=wk`ca@43%U-=sfjmVornPvE(Wx|Z`+C~cMn>1;%uyNzY
ze;7G(<Pc0EoP~L4oW(~gL73K?p7ZIL!Ij`oBct4l$-TVNd=j7lp6l{@$)gz-$zcBr
z(2bZ<y7J28<4h=~Ok5sT76NY{{OQvt_uSlEw=-wX1Yn#G73bqEo1XJZ#mtVnTd7g%
zg_J5utx_p?M;N1<JnHs>34#e>O&tXE1H?hQ7-!F(?I}(}+}cg93@H_H>M*p&T%rHZ
zD335?f$+#oADA>)Er`0wV!3>kDo`@x5$3TqKMz_pqA8<Z@({joGRk4Z*jR-4^dh=^
zqFmVl0|wj?r}gR6Cta=#x_s&{0NPW8TNkr0qV%QJDibi!65P9Y?{t&*;ll@hnU9Nk
zU%q@<NH>_(r0`0WvPL{l!Zi3A=J}s7qxv#%;J{mZ_Ut(?&c|CVoZXdEr%rK$b!KKJ
zDb&d*_hR<IS{?W9-P29p{rmTYk1|i3IMG0$w3Nw{Cto0i((Ff=5#GHdK0ZDHPH7XI
z(qEF2l1_VidKL=v(5$JXq{KNiH1sCs_Z7;96Re9rpDm7|_B2vSSz63MgEW^%Yo@}F
z1^gRRPKxv^y!wFy2QJT@JNFkQ<D(dPd3jDKn*zoELzupA-@fMflUA)$Pjo*<3nN;B
zrk=ZZ?`G@Pt>a}iM3}P$>37<<Z|`Pj^^(ZW&i;a_XHOW&kIqU8Xtg*ZfFUL(#?-N6
zM}`<t)5VdiSFZ|{NyvjGrr-m1J$UfoC#ibiz>Em9%H(9xR8zcs$798c6)o}nU-<c6
zv4vV|q!MLHt%oKjC$oTn0L5#emgLdccH_nkt}bT29$FU)`}y+a%dh<W{LB=G2%y!5
z4I2Ul@A&HrLN~aK=;qhw%$f6CTsA#D-GF(#SAKr}JSI1W+M+Of#y?n;2`|Mh604O*
zWyuj;xpKu)kwRGEmf5ps`@-3{h#w9gK0K>!+qUm--@e`T)~#EWE=t49D-ToB*Wz*r
z$DC)*oY@V^{2M8g(rgOsr5b6chc+x(vcy39LTPDf!q`!<JSsy@==}NfY|)}cT%8tV
z{qxS9JG)?M-cV|#eHL2qz?3sdDo&-)2z8%n)~s2vFrBtQ=Fgws1-;@3ZZ8R+)tF5>
zym(b?(v6rjX;K0#`e&&PI4HGZlMX@q6{$Q=o;=wc5fMTAOcTv4gw?QZ<k;9)=H=yO
zwv9}nu1(v>6u3i~3=LzEk&)KwltTAGg9iO+`t<2_F%N$r-bM}&4-cXJc#27d>E+wV
zT@dV>Fz=5+($$)-P)@1B8y$%bb-lg4e;*VSG!9p(kB<+HquH1xeI=p;Wq{{)BE`OV
z@#1^L&ELa;x~8V4p2C>Fg;`*b7?^{KQ{UIuHx$=k^on*K9v-e3Q#s#)AifM%S%_ii
zKN%SrNf_tJV)NuGt2L`lGAP5CU4Y@F06nz`moVHwG*(tj&k73*X@jrKT4lAl%R9JD
zRmE)@GiJ;Wuv#OWQYFTSgWDtx#oQ+3yJ&K7o3!ONO`beC>A-;l$>O{YZj%*m6JpXp
zDCY+$d1R@W?_Uz9JGe~}+$O?;1q*r~I&>&RirYkKCr+FQf;IY!%l#&}P4q5n)~rz^
zZ{^CBl~#w;aGMCkZ7TmTl8T@Yhxao0`T6BaJ$G=MG=^eslb(>`HfaH++$Jrdh})z$
z#M~yWpoH6`1LV0)RROKLx)5^QCOIhKHd%s2Zj%xy<r-N)C2o@*@+@(itU)QaNeYtO
zCZ&y&`fUq%Zj)Z}q_|B=%BkTt@u+p&CM8hIZ7PR3w@C?X<r+zW=QimjPm0^5q?{UV
z6Azx-RBdtSix)4rJ$XIw_U&8NvSmwN)=%l_>34m6d|F#8M-GU_%+%D>t`x}k>ecJv
zo;`cciRm~}c=qhsD}-jgiaeMepq)y+6e`7SqJ<Z0;JHosnP4@u2v)gGdPB@@(h5qr
zO?rUmHdUKKv$M0=<HwIRuNPg9+YuEYH7za86Y2SC>r~K|FW0YM?}(ol9o#17;5JFh
zvxnOh7Z=xj?b@}$qz5T(6V<nL>C)s06DGV7mvwNPB)CnXp`kfmUS8RjxJ~FqIbmU8
z+2V2zZj%hR3B$pqh=>R?`Zw{NjvqgsBwm<yaGQRGVr~=iT`)PgO^P7PZJIc7;sAUw
zBQf%X=?-p_JRIC6I~8aN4sMgiaB!O>+MoswZc|lpn=C;Ix2dKmlzRcPM%rtl?Ga~Z
z`B^b}eERoBniL=~7q-V5h}$%K{rdH<5l!T%X$PECQ%pD8?%%(EFK&<4G=<7?o2)@g
zZj&w0gxjQpLS?y4N}&a}Ne%4cHt7XR+$JT^irb_XQrxEMR4B)7>e;iWYReR^4AEI2
z-Me?^XgJI~cAYkA)Tlgve}5ZlR|Xh^F+4n+#^PDrdsL0?%)oJ*V4Y@bp-N6(u#~r6
zy?U%)zkY1_^5vY2@?_#R1z~8()T=RYa9J)cE<NzGX{|lCDJm+;ALFjg=Qic$<~qm3
z#B_F?+ax--3Gwa_<h9uwyScfQ?AWoRpX1!7a`5Li(J@16&uv1C>^QfHZZI<n(E8k_
zv17+_&uiVeP3ZRh5djR5E31avM09aj>fl<(ZGscAy2GoM+f-a!Om)|;bDNGHJ$iw*
zG~~*v;Wp9fx9Iw{^W3I`2M=E6l?rP#vpieRZGxx2Mu%Y0A+5Fc+$K`$=+UE7=<Fr6
z=Qg1SxL^Wt2bNjEfvVN#HpRuoCBma8LNTh&ZHkPHyq1uVa7uW@u;bh&4Iw<Ysk*#8
zaho_E627=*m0IC8S>=bSg(_~77O;ieWGn39HrWH!+$OzXiQ8lg?BzD8h27jH9U#kX
zQUWcwO=@6?+f?0Mo(J~=q!e;eI&abux9LYrQJ;41+&N24JDxs$`dxH%v^V0`?YKQ$
zsf{&6p%sd)3EU=2aB!RC;ovsesX$B6l-u-Q_Hny@nnw1n00000NkvXXu0mjf$cB`U
--- a/toolkit/themes/pinstripe/global/jar.mn
+++ b/toolkit/themes/pinstripe/global/jar.mn
@@ -107,16 +107,17 @@ classic.jar:
 +  skin/classic/global/console/console-error-caret.gif                (console/console-error-caret.gif)
 +  skin/classic/global/console/console-error-dash.gif                 (console/console-error-dash.gif)
 +  skin/classic/global/console/console.css                            (console/console.css)
 +  skin/classic/global/icons/alltabs.png                              (icons/alltabs.png)
 +  skin/classic/global/icons/alert-error.gif                          (icons/alert-error.gif)
 +  skin/classic/global/icons/alert-message.gif                        (icons/alert-message.gif)
 +  skin/classic/global/icons/alert-question.gif                       (icons/alert-question.gif)
 +  skin/classic/global/icons/autocomplete-dropmarker.png              (icons/autocomplete-dropmarker.png)
++  skin/classic/global/icons/autoscroll.png                           (icons/autoscroll.png)
 +  skin/classic/global/icons/chevron.png                              (icons/chevron.png)
 +  skin/classic/global/icons/close.gif                                (icons/close.gif)
 +  skin/classic/global/icons/closetab-active.png                      (icons/closetab-active.png)
 +  skin/classic/global/icons/closetab-hover.png                       (icons/closetab-hover.png)
 +  skin/classic/global/icons/closetab.png                             (icons/closetab.png)
 +  skin/classic/global/icons/find.png                                 (icons/find.png)
 +  skin/classic/global/icons/find-bar-background.png                  (icons/find-bar-background.png)
 +  skin/classic/global/icons/find-bar-flash.png                       (icons/find-bar-flash.png)
--- a/toolkit/themes/winstripe/global/global.css
+++ b/toolkit/themes/winstripe/global/global.css
@@ -179,8 +179,40 @@ sidebarheader > label {
   -moz-padding-start: 4px;
 }
 
 /* ::::: miscellaneous ::::: */
 
 .toolbar-focustarget {
   -moz-user-focus: ignore !important;
 }
+
+/* :::::: autoscroll popup ::::: */
+
+#autoscroller {
+  height: 28px;
+  width: 28px;
+  border: none;
+  margin: -14px;
+  padding: 0;
+  background-image: url("chrome://global/skin/icons/autoscroll.png");
+  background-color: transparent;
+%ifdef XP_WIN
+  background-position: right top;
+%endif
+  -moz-appearance: none;
+}
+
+#autoscroller[scrolldir="NS"] {
+%ifdef XP_WIN
+  background-position: right center;
+%else
+  background-position: left center;
+%endif
+}
+
+#autoscroller[scrolldir="EW"] {
+%ifdef XP_WIN
+  background-position: right bottom;
+%else
+  background-position: left bottom;
+%endif
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e460930a9e714469eb39c8918643ffa81baef2e5
GIT binary patch
literal 3369
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
--- a/toolkit/themes/winstripe/global/jar.mn
+++ b/toolkit/themes/winstripe/global/jar.mn
@@ -69,16 +69,17 @@ classic.jar:
 	skin/classic/global/icons/alltabs-box-overflow-end-bkgnd.png   (icons/alltabs-box-overflow-end-bkgnd.png)
     skin/classic/global/icons/alltabs-box-overflow-start-bkgnd-animate.png   (icons/alltabs-box-overflow-start-bkgnd-animate.png)
 	skin/classic/global/icons/alltabs-box-overflow-end-bkgnd-animate.png   (icons/alltabs-box-overflow-end-bkgnd-animate.png)
 	skin/classic/global/icons/alltabs-box-overflow-start-bkgnd.png (icons/alltabs-box-overflow-start-bkgnd.png)
         skin/classic/global/icons/autocomplete-dropmark-arrow.png   (icons/autocomplete-dropmark-arrow.png)
         skin/classic/global/icons/autocomplete-dropmark-bkgnd.png   (icons/autocomplete-dropmark-bkgnd.png)
         skin/classic/global/icons/autocomplete-dropmark-bkgnd-mid-top.png    (icons/autocomplete-dropmark-bkgnd-mid-top.png)
         skin/classic/global/icons/autocomplete-dropmark-bkgnd-mid-bottom.png (icons/autocomplete-dropmark-bkgnd-mid-bottom.png)
+        skin/classic/global/icons/autoscroll.png                    (icons/autoscroll.png)
         skin/classic/global/icons/Close.gif                         (icons/Close.gif)
         skin/classic/global/icons/close.png                         (icons/close.png)
         skin/classic/global/icons/alltabs.png                       (icons/alltabs.png)
         skin/classic/global/icons/Error.png                         (icons/Error.png)
         skin/classic/global/icons/find.png                          (icons/find.png)
         skin/classic/global/icons/folder-item.png                   (icons/folder-item.png)
         skin/classic/global/icons/Minimize.gif                      (icons/Minimize.gif)
         skin/classic/global/icons/notfound.png                      (icons/notfound.png)