home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / xulrunner-1.9.0.14 / chrome / toolkit.jar / content / global / bindings / scrollbox.xml < prev    next >
Encoding:
Extensible Markup Language  |  2008-05-05  |  21.3 KB  |  619 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!DOCTYPE bindings [
  4.   <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
  5.   %globalDTD;
  6. ]>
  7.  
  8. <bindings id="arrowscrollboxBindings"
  9.    xmlns="http://www.mozilla.org/xbl"
  10.    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  11.    xmlns:xbl="http://www.mozilla.org/xbl">
  12.  
  13.   <binding id="scrollbox-base" extends="chrome://global/content/bindings/general.xml#basecontrol">
  14.     <resources>
  15.       <stylesheet src="chrome://global/skin/scrollbox.css"/>
  16.     </resources>
  17.   </binding>
  18.  
  19.   <binding id="scrollbox" extends="chrome://global/content/bindings/scrollbox.xml#scrollbox-base">
  20.     <content>
  21.       <xul:box class="box-inherit scrollbox-innerbox" xbl:inherits="orient,align,pack,dir" flex="1">
  22.         <children/>
  23.       </xul:box>
  24.     </content>
  25.   </binding>
  26.  
  27.   <binding id="arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#scrollbox-base">
  28.     <content>
  29.       <xul:autorepeatbutton class="autorepeatbutton-up"
  30.                             anonid="scrollbutton-up"
  31.                             collapsed="true"
  32.                             xbl:inherits="orient"
  33.                             oncommand="_autorepeatbuttonScroll(event);"/>
  34.       <xul:scrollbox xbl:inherits="orient,align,pack,dir" flex="1" anonid="scrollbox">
  35.         <children/>
  36.       </xul:scrollbox>
  37.       <xul:autorepeatbutton class="autorepeatbutton-down"
  38.                             anonid="scrollbutton-down"
  39.                             collapsed="true"
  40.                             xbl:inherits="orient"
  41.                             oncommand="_autorepeatbuttonScroll(event);"/>
  42.     </content>
  43.  
  44.     <implementation>
  45.       <field name="_scrollbox">
  46.         document.getAnonymousElementByAttribute(this, "anonid", "scrollbox");
  47.       </field>
  48.       <field name="_scrollButtonUp">
  49.         document.getAnonymousElementByAttribute(this, "anonid", "scrollbutton-up");
  50.       </field>
  51.       <field name="_scrollButtonDown">
  52.         document.getAnonymousElementByAttribute(this, "anonid", "scrollbutton-down");
  53.       </field>
  54.  
  55.       <field name="__prefBranch">null</field>
  56.       <property name="_prefBranch" readonly="true">
  57.         <getter><![CDATA[
  58.           if (this.__prefBranch === null) {
  59.             this.__prefBranch = Components.classes['@mozilla.org/preferences-service;1']
  60.                                           .getService(Components.interfaces.nsIPrefBranch2);
  61.           }
  62.           return this.__prefBranch;
  63.         ]]></getter>
  64.       </property>
  65.  
  66.       <field name="_scrollIncrement">null</field>
  67.       <property name="scrollIncrement" readonly="true">
  68.         <getter><![CDATA[
  69.           if (this._scrollIncrement === null) {
  70.             try {
  71.               this._scrollIncrement = this._prefBranch
  72.                                           .getIntPref("toolkit.scrollbox.scrollIncrement");
  73.             }
  74.             catch (ex) {
  75.               this._scrollIncrement = 20;
  76.             }
  77.           }
  78.           return this._scrollIncrement;
  79.         ]]></getter>
  80.       </property>
  81.  
  82.       <field name="_smoothScroll">null</field>
  83.       <property name="smoothScroll">
  84.         <getter><![CDATA[
  85.           if (this._smoothScroll === null) {
  86.             if (this.hasAttribute("smoothscroll")) {
  87.               this._smoothScroll = (this.getAttribute("smoothscroll") == "true");
  88.             } else {
  89.               try {
  90.                 this._smoothScroll = this._prefBranch
  91.                                          .getBoolPref("toolkit.scrollbox.smoothScroll");
  92.               }
  93.               catch (ex) {
  94.                 this._smoothScroll = true;
  95.               }
  96.             }
  97.           }
  98.           return this._smoothScroll;
  99.         ]]></getter>
  100.         <setter><![CDATA[
  101.           this._smoothScroll = val;
  102.           return val;
  103.         ]]></setter>
  104.       </property>
  105.  
  106.       <field name="_scrollBoxObject">null</field>
  107.       <property name="scrollBoxObject" readonly="true">
  108.         <getter><![CDATA[
  109.           if (!this._scrollBoxObject) {
  110.             this._scrollBoxObject =
  111.               this._scrollbox.boxObject
  112.                              .QueryInterface(Components.interfaces.nsIScrollBoxObject);
  113.           }
  114.           return this._scrollBoxObject;
  115.         ]]></getter>
  116.       </property>
  117.  
  118.       <field name="_isLTRScrollbox">
  119.         document.defaultView.getComputedStyle(this._scrollbox, "").direction == "ltr";
  120.       </field>
  121.  
  122.       <method name="ensureElementIsVisible">
  123.         <parameter name="element"/>
  124.         <body><![CDATA[
  125.           if (!this.smoothScroll || this.getAttribute("orient") == "vertical") {
  126.             this.scrollBoxObject.ensureElementIsVisible(element);
  127.             return;
  128.           }
  129.  
  130.           var rect = this._scrollbox.getBoundingClientRect();
  131.           var containerStart = rect.left;
  132.           var containerEnd = rect.right;
  133.           rect = element.getBoundingClientRect();
  134.           var elementStart = rect.left;
  135.           var elementEnd = rect.right;
  136.           var amountToScroll;
  137.  
  138.           if (elementStart < containerStart) {
  139.             amountToScroll = elementStart - containerStart;
  140.           } else if (containerEnd < elementEnd) {
  141.             amountToScroll = elementEnd - containerEnd;
  142.           } else if (this._isScrolling) {
  143.             // decelerate if a currently-visible element is selected during the scroll
  144.             const STOP_DISTANCE = 15;
  145.             if (this._isScrolling == -1 && elementStart - STOP_DISTANCE < containerStart)
  146.               amountToScroll = elementStart - containerStart;
  147.             else if (this._isScrolling == 1 && containerEnd - STOP_DISTANCE < elementEnd)
  148.               amountToScroll = elementEnd - containerEnd;
  149.             else
  150.               amountToScroll = this._isScrolling * STOP_DISTANCE;
  151.           } else {
  152.             return;
  153.           }
  154.  
  155.           this._smoothScrollByPixels(amountToScroll);
  156.         ]]></body>
  157.       </method>
  158.  
  159.       <method name="_smoothScrollByPixels">
  160.         <parameter name="amountToScroll"/>
  161.         <body><![CDATA[
  162.           this._stopSmoothScroll();
  163.  
  164.           // Positive amountToScroll makes us scroll right (elements fly left), negative scrolls left.
  165.           var round;
  166.           if (amountToScroll < 0) {
  167.             this._isScrolling = -1;
  168.             round = Math.floor;
  169.           } else {
  170.             this._isScrolling = 1;
  171.             round = Math.ceil;
  172.           }
  173.  
  174.           const FRAME_LENGTH = 60;
  175.  
  176.           function processFrame(self, scrollAmounts, off) {
  177.             var distance = scrollAmounts.shift();
  178.  
  179.             // Skip frames if we aren't getting the desired frame rate.
  180.             if (off > 0) {
  181.               for (var i = Math.round(off / FRAME_LENGTH); i > 0; i--)
  182.                 distance += scrollAmounts.shift() || 0;
  183.             }
  184.  
  185.             self.scrollBoxObject.scrollBy(distance, 0);
  186.             if (!scrollAmounts.length)
  187.               self._stopSmoothScroll();
  188.           }
  189.  
  190.           // amountToScroll: total distance to scroll
  191.           // scrollAmount: distance to move during the particular effect frame (60ms)
  192.           var scrollAmount, scrollAmounts = [];
  193.           if (amountToScroll > 2 || amountToScroll < -2) {
  194.             scrollAmount = round(amountToScroll * 0.2);
  195.             scrollAmounts.push(scrollAmount, scrollAmount, scrollAmount);
  196.             amountToScroll -= 3 * scrollAmount;
  197.           }
  198.           while (this._isScrolling < 0 && amountToScroll < 0 ||
  199.                  this._isScrolling > 0 && amountToScroll > 0) {
  200.             amountToScroll -= (scrollAmount = round(amountToScroll * 0.5));
  201.             scrollAmounts.push(scrollAmount);
  202.           }
  203.           this._smoothScrollTimer = setInterval(processFrame, FRAME_LENGTH, this, scrollAmounts);
  204.           processFrame(this, scrollAmounts, 0);
  205.         ]]></body>
  206.       </method>
  207.  
  208.       <method name="scrollByIndex">
  209.         <parameter name="index"/>
  210.         <body><![CDATA[
  211.           if (index == 0)
  212.             return;
  213.           if (this.getAttribute("orient") == "vertical") {
  214.             this.scrollBoxObject.scrollByIndex(index);
  215.             return;
  216.           }
  217.  
  218.           var x;
  219.           if (index > 0)
  220.             x = this._scrollbox.getBoundingClientRect().right + 1;
  221.           else
  222.             x = this._scrollbox.getBoundingClientRect().left - 1;
  223.           var nextElement = this._elementFromPoint(x);
  224.           if (!nextElement)
  225.             return;
  226.  
  227.           var targetElement;
  228.           if (!this._isLTRScrollbox)
  229.             index *= -1;
  230.  
  231.           while (index < 0 && nextElement) {
  232.             targetElement = nextElement;
  233.             nextElement = nextElement.previousSibling;
  234.             index++;
  235.           }
  236.           while (index > 0 && nextElement) {
  237.             targetElement = nextElement;
  238.             nextElement = nextElement.nextSibling;
  239.             index--;
  240.           }
  241.  
  242.           this.ensureElementIsVisible(targetElement);
  243.         ]]></body>
  244.       </method>
  245.  
  246.       <method name="_elementFromPoint">
  247.         <parameter name="aX"/>
  248.         <body><![CDATA[
  249.           var elements = this.hasChildNodes() ?
  250.                          this.childNodes :
  251.                          document.getBindingParent(this).childNodes;
  252.           if (!this._isLTRScrollbox) {
  253.             elements = Array.slice(elements);
  254.             elements.reverse();
  255.           }
  256.           var low = 0;
  257.           var high = elements.length - 1;
  258.  
  259.           while (low <= high) {
  260.             var mid = Math.floor((low + high) / 2);
  261.             var element = elements[mid];
  262.             var rect = element.getBoundingClientRect();
  263.             if (rect.left > aX)
  264.               high = mid - 1; 
  265.             else if (rect.right < aX)
  266.               low = mid + 1;
  267.             else
  268.               return element;
  269.           }
  270.  
  271.           return null;
  272.         ]]></body>
  273.       </method>
  274.  
  275.       <method name="_autorepeatbuttonScroll">
  276.         <parameter name="event"/>
  277.         <body><![CDATA[
  278.           var dir = event.originalTarget == this._scrollButtonUp ? -1 : 1;
  279.           if (this.getAttribute("orient") == "horizontal" && !this._isLTRScrollbox)
  280.             dir *= -1;
  281.  
  282.           this.scrollByPixels(this.scrollIncrement * dir);
  283.  
  284.           event.stopPropagation();
  285.         ]]></body>
  286.       </method>
  287.  
  288.       <method name="scrollByPixels">
  289.         <parameter name="px"/>
  290.         <body><![CDATA[
  291.           if (this.getAttribute("orient") == "horizontal")
  292.             this.scrollBoxObject.scrollBy(px, 0);
  293.           else
  294.             this.scrollBoxObject.scrollBy(0, px);
  295.         ]]></body>
  296.       </method>
  297.  
  298.       <!-- 0: idle
  299.            1: scrolling right
  300.           -1: scrolling left -->
  301.       <field name="_isScrolling">0</field>
  302.       <field name="_smoothScrollTimer">0</field>
  303.  
  304.       <method name="_stopSmoothScroll">
  305.         <body><![CDATA[
  306.           clearInterval(this._smoothScrollTimer);
  307.           this._isScrolling = 0;
  308.         ]]></body>
  309.       </method>
  310.  
  311.       <method name="_updateScrollButtonsDisabledState">
  312.         <body><![CDATA[
  313.           var disableUpButton = false;
  314.           var disableDownButton = false;
  315.  
  316.           if (this.getAttribute("orient") == "horizontal") {
  317.             var width = {};
  318.             this.scrollBoxObject.getScrolledSize(width, {});
  319.             var xPos = {};
  320.             this.scrollBoxObject.getPosition(xPos, {});
  321.             if (xPos.value == 0) {
  322.               // In the RTL case, this means the _last_ element in the
  323.               // scrollbox is visible
  324.               if (this._isLTRScrollbox) 
  325.                 disableUpButton = true;
  326.               else
  327.                 disableDownButton = true;
  328.             }
  329.             else if (this._scrollbox.boxObject.width + xPos.value == width.value) {
  330.               // In the RTL case, this means the _first_ element in the
  331.               // scrollbox is visible
  332.               if (this._isLTRScrollbox)
  333.                 disableDownButton = true;
  334.               else
  335.                 disableUpButton = true;
  336.             }
  337.           }
  338.           else {  // vertical scrollbox
  339.             var height = {};
  340.             this.scrollBoxObject.getScrolledSize({}, height);
  341.             var yPos = {};
  342.             this.scrollBoxObject.getPosition({}, yPos);
  343.             if (yPos.value == 0)
  344.               disableUpButton = true;
  345.             else if (this._scrollbox.boxObject.height + yPos.value == height.value)
  346.               disableDownButton = true;
  347.           }
  348.  
  349.           if (this._scrollButtonUp.disabled != disableUpButton ||
  350.               this._scrollButtonDown.disabled != disableDownButton) {
  351.             this._scrollButtonUp.disabled = disableUpButton;
  352.             this._scrollButtonDown.disabled = disableDownButton;
  353.  
  354.             var event = document.createEvent("Events");
  355.             event.initEvent("UpdatedScrollButtonsDisabledState", true, false);
  356.             this.dispatchEvent(event);
  357.           }
  358.         ]]></body>
  359.       </method>
  360.     </implementation>
  361.  
  362.     <handlers>
  363.       <handler event="DOMMouseScroll" action="this.scrollByIndex(event.detail); event.stopPropagation();"/>
  364.  
  365.       <handler event="underflow"><![CDATA[
  366.         // filter underflow events which were dispatched on nested scrollboxes
  367.         if (event.target != this)
  368.           return;
  369.  
  370.         // Ignore events that doesn't match our orientation.
  371.         // Scrollport event orientation:
  372.         //   0: vertical
  373.         //   1: horizontal
  374.         //   2: both
  375.         if (this.getAttribute("orient") == "horizontal") {
  376.           if (event.detail == 0) {
  377.             return;
  378.           }
  379.         }
  380.         else {    // vertical scrollbox
  381.           if (event.detail == 1) {
  382.             return;
  383.           }
  384.         }
  385.  
  386.         this._scrollButtonUp.collapsed = true;
  387.         this._scrollButtonDown.collapsed = true;
  388.         try {
  389.           // See bug 341047 and comments in overflow handler as to why 
  390.           // try..catch is needed here
  391.           var childNodes = document.getAnonymousNodes(this._scrollbox);
  392.           if (childNodes && childNodes.length)
  393.             this.scrollBoxObject.ensureElementIsVisible(childNodes[0]);
  394.         }
  395.         catch(e) {
  396.           this._scrollButtonUp.collapsed = false;
  397.           this._scrollButtonDown.collapsed = false;
  398.         }
  399.       ]]></handler>
  400.  
  401.       <handler event="overflow"><![CDATA[
  402.         // filter underflow events which were dispatched on nested scrollboxes
  403.         if (event.target != this)
  404.           return;
  405.  
  406.         // Ignore events that doesn't match our orientation.
  407.         // Scrollport event orientation:
  408.         //   0: vertical
  409.         //   1: horizontal
  410.         //   2: both
  411.         if (this.getAttribute("orient") == "horizontal") {
  412.           if (event.detail == 0) {
  413.             return;
  414.           }
  415.         }
  416.         else {    // vertical scrollbox
  417.           if (event.detail == 1) {
  418.             return;
  419.           }
  420.         }
  421.  
  422.         this._scrollButtonUp.collapsed = false;
  423.         this._scrollButtonDown.collapsed = false;
  424.         try {
  425.           // See bug 341047, the overflow event is dispatched when the 
  426.           // scrollbox already is mostly destroyed. This causes some code in
  427.           // _updateScrollButtonsDisabledState() to throw an error. It also
  428.           // means that the scrollbarbuttons were uncollapsed when that should
  429.           // not be happening, because the whole overflow event should not be
  430.           // happening in that case.
  431.           this._updateScrollButtonsDisabledState();
  432.         } 
  433.         catch(e) {
  434.           this._scrollButtonUp.collapsed = true;
  435.           this._scrollButtonDown.collapsed = true;
  436.         }
  437.       ]]></handler>
  438.  
  439.       <handler event="scroll" action="this._updateScrollButtonsDisabledState()"/>
  440.     </handlers>
  441.   </binding>
  442.  
  443.   <binding id="autorepeatbutton" extends="chrome://global/content/bindings/scrollbox.xml#scrollbox-base">
  444.     <content repeat="hover" chromedir="&locale.dir;">
  445.       <xul:image class="autorepeatbutton-icon"/>
  446.     </content>
  447.   </binding>
  448.  
  449.   <binding id="arrowscrollbox-clicktoscroll" extends="chrome://global/content/bindings/scrollbox.xml#arrowscrollbox">
  450.     <content>
  451.       <xul:toolbarbutton class="scrollbutton-up" collapsed="true"
  452.                          xbl:inherits="orient"
  453.                          anonid="scrollbutton-up"
  454.                          onclick="_distanceScroll(event);"
  455.                          onmousedown="_startScroll(-1);"
  456.                          onmouseover="_continueScroll(-1);"
  457.                          onmouseup="_stopScroll();"
  458.                          onmouseout="_pauseScroll();"
  459.                          chromedir="&locale.dir;"/>
  460.       <xul:scrollbox xbl:inherits="orient,align,pack,dir" flex="1" anonid="scrollbox">
  461.         <children/>
  462.       </xul:scrollbox>
  463.       <xul:toolbarbutton class="scrollbutton-down" collapsed="true"
  464.                          xbl:inherits="orient"
  465.                          anonid="scrollbutton-down"
  466.                          onclick="_distanceScroll(event);"
  467.                          onmousedown="_startScroll(1);"
  468.                          onmouseover="_continueScroll(1);"
  469.                          onmouseup="_stopScroll();"
  470.                          onmouseout="_pauseScroll();"
  471.                          chromedir="&locale.dir;"/>
  472.     </content>
  473.     <implementation implements="nsITimerCallback, nsIDOMEventListener">
  474.       <constructor><![CDATA[
  475.         try {
  476.           this._scrollDelay = this._prefBranch
  477.                                   .getIntPref("toolkit.scrollbox.clickToScroll.scrollDelay");
  478.         }
  479.         catch (ex) {
  480.         }
  481.       ]]></constructor>
  482.  
  483.       <destructor><![CDATA[
  484.         // Release timer to avoid reference cycles.
  485.         if (this._scrollTimer) {
  486.           this._scrollTimer.cancel();
  487.           this._scrollTimer = null;
  488.         }
  489.       ]]></destructor>
  490.  
  491.       <field name="_scrollIndex">0</field>
  492.       <field name="_scrollDelay">150</field>
  493.  
  494.       <method name="notify">
  495.         <parameter name="aTimer"/>
  496.         <body>
  497.         <![CDATA[
  498.           if (!document)
  499.             aTimer.cancel();
  500.  
  501.           if (this.smoothScroll)
  502.             this.scrollByPixels(25 * this._scrollIndex);
  503.           else
  504.             this.scrollBoxObject.scrollByIndex(this._scrollIndex);
  505.         ]]>
  506.         </body>
  507.       </method>
  508.  
  509.       <method name="_startScroll">
  510.         <parameter name="index"/>
  511.         <body><![CDATA[
  512.           if (this.getAttribute("orient") == "horizontal" && !this._isLTRScrollbox)
  513.             index *= -1;
  514.           this._scrollIndex = index;
  515.           var scrollDelay = this.smoothScroll ? 60 : this._scrollDelay;
  516.           if (!this._scrollTimer)
  517.             this._scrollTimer =
  518.               Components.classes["@mozilla.org/timer;1"]
  519.                         .createInstance(Components.interfaces.nsITimer);
  520.           else
  521.             this._scrollTimer.cancel();
  522.  
  523.           this._scrollTimer.initWithCallback(this, scrollDelay,
  524.                                              this._scrollTimer.TYPE_REPEATING_SLACK);
  525.           this.notify(this._scrollTimer);
  526.           this._mousedown = true;
  527.         ]]>
  528.         </body>
  529.       </method>
  530.  
  531.       <method name="_stopScroll">
  532.         <body><![CDATA[
  533.           if (this._scrollTimer)
  534.             this._scrollTimer.cancel();
  535.           this._mousedown = false;
  536.           if (!this._scrollIndex || !this.smoothScroll)
  537.             return;
  538.  
  539.           this.scrollByIndex(this._scrollIndex);
  540.           this._scrollIndex = 0;
  541.         ]]></body>
  542.       </method>
  543.  
  544.       <method name="_pauseScroll">
  545.         <body><![CDATA[
  546.           if (this._mousedown) {
  547.             this._stopScroll();
  548.             this._mousedown = true;
  549.             document.addEventListener("mouseup", this, false);
  550.             document.addEventListener("blur", this, true);
  551.           }
  552.         ]]></body>
  553.       </method>
  554.  
  555.       <method name="_continueScroll">
  556.         <parameter name="index"/>
  557.         <body><![CDATA[
  558.           if (this._mousedown)
  559.             this._startScroll(index);
  560.         ]]></body>
  561.       </method>
  562.  
  563.       <method name="handleEvent">
  564.         <parameter name="aEvent"/>
  565.         <body><![CDATA[
  566.           if (aEvent.type == "mouseup" ||
  567.               aEvent.type == "blur" && aEvent.target == document) {
  568.             this._mousedown = false;
  569.             document.removeEventListener("mouseup", this, false);
  570.             document.removeEventListener("blur", this, true);
  571.           }
  572.         ]]></body>
  573.       </method>
  574.  
  575.       <method name="_distanceScroll">
  576.         <parameter name="aEvent"/>
  577.         <body><![CDATA[
  578.           if (this.getAttribute("orient") == "vertical" ||
  579.               aEvent.detail < 2 || aEvent.detail > 3)
  580.             return;
  581.  
  582.           var scrollLeft = (aEvent.originalTarget == this._scrollButtonUp);
  583.           if (!this._isLTRScrollbox)
  584.             scrollLeft = !scrollLeft;
  585.           var targetElement;
  586.  
  587.           if (aEvent.detail == 2) {
  588.             // scroll by the width of the scrollbox; make sure that the next
  589.             // partly-hidden element will become fully visible.
  590.             var rect = this._scrollbox.getBoundingClientRect();
  591.             var x;
  592.             if (scrollLeft)
  593.               x = rect.left - (rect.right - rect.left);
  594.             else
  595.               x = rect.right + (rect.right - rect.left);
  596.             targetElement = this._elementFromPoint(x);
  597.  
  598.             if (targetElement)
  599.               targetElement = scrollLeft ?
  600.                               targetElement.nextSibling :
  601.                               targetElement.previousSibling;
  602.           }
  603.  
  604.           if (!targetElement) {
  605.             // scroll to the first resp. last element
  606.             var container = this.hasChildNodes() ? this : document.getBindingParent(this);
  607.             targetElement = (this._isLTRScrollbox ? scrollLeft : !scrollLeft) ?
  608.                             container.firstChild :
  609.                             container.lastChild;
  610.           }
  611.  
  612.           this.ensureElementIsVisible(targetElement);
  613.         ]]></body>
  614.       </method>
  615.  
  616.     </implementation>
  617.   </binding>
  618. </bindings>
  619.