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 / datetimepicker.xml < prev    next >
Encoding:
Extensible Markup Language  |  2008-02-01  |  45.9 KB  |  1,259 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!-- ***** BEGIN LICENSE BLOCK *****
  4.    - Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5.    -
  6.    - The contents of this file are subject to the Mozilla Public License Version
  7.    - 1.1 (the "License"); you may not use this file except in compliance with
  8.    - the License. You may obtain a copy of the License at
  9.    - http://www.mozilla.org/MPL/
  10.    -
  11.    - Software distributed under the License is distributed on an "AS IS" basis,
  12.    - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.    - for the specific language governing rights and limitations under the
  14.    - License.
  15.    -
  16.    - The Original Code is Mozilla.org code.
  17.    -
  18.    - The Initial Developer of the Original Code is Mozilla Corporation.
  19.    - Portions created by the Initial Developer are Copyright (C) 2006
  20.    - the Initial Developer. All Rights Reserved.
  21.    -
  22.    - Contributor(s):
  23.    -   Neil Deakin <enndeakin@sympatico.ca> (Original Author)
  24.    -
  25.    - Alternatively, the contents of this file may be used under the terms of
  26.    - either of the GNU General Public License Version 2 or later (the "GPL"),
  27.    - or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.    - in which case the provisions of the GPL or the LGPL are applicable instead
  29.    - of those above. If you wish to allow use of your version of this file only
  30.    - under the terms of either the GPL or the LGPL, and not to allow others to
  31.    - use your version of this file under the terms of the MPL, indicate your
  32.    - decision by deleting the provisions above and replace them with the notice
  33.    - and other provisions required by the GPL or the LGPL. If you do not delete
  34.    - the provisions above, a recipient may use your version of this file under
  35.    - the terms of any one of the MPL, the GPL or the LGPL.
  36.    -
  37.    - ***** END LICENSE BLOCK ***** -->
  38.  
  39. <!DOCTYPE bindings [
  40.   <!ENTITY % datetimepickerDTD SYSTEM "chrome://global/locale/datetimepicker.dtd">
  41.   %datetimepickerDTD;
  42.   <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
  43.   %globalDTD;
  44. ]>
  45.  
  46. <bindings id="timepickerBindings"
  47.    xmlns="http://www.mozilla.org/xbl"
  48.    xmlns:html="http://www.w3.org/1999/xhtml"
  49.    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  50.    xmlns:xbl="http://www.mozilla.org/xbl">
  51.  
  52.   <binding id="datetimepicker-base"
  53.            extends="chrome://global/content/bindings/general.xml#basecontrol">
  54.  
  55.     <resources>
  56.       <stylesheet src="chrome://global/skin/textbox.css"/>
  57.       <stylesheet src="chrome://global/skin/dropmarker.css"/>
  58.       <stylesheet src="chrome://global/skin/datetimepicker.css"/>
  59.     </resources>
  60.  
  61.     <content align="center">
  62.       <xul:hbox class="datetimepicker-input-box" align="center"
  63.                 xbl:inherits="context">
  64.         <xul:hbox class="textbox-input-box datetimepicker-input-subbox" align="center">
  65.           <html:input class="datetimepicker-input textbox-input" anonid="input-one"
  66.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  67.                       xbl:inherits="disabled,readonly"/>
  68.         </xul:hbox>
  69.         <xul:label anonid="sep-first" class="datetimepicker-separator" value=":"/>
  70.         <xul:hbox class="textbox-input-box datetimepicker-input-subbox" align="center">
  71.           <html:input class="datetimepicker-input textbox-input" anonid="input-two"
  72.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  73.                       xbl:inherits="disabled,readonly"/>
  74.         </xul:hbox>
  75.         <xul:label anonid="sep-second" class="datetimepicker-separator" value=":"/>
  76.         <xul:hbox class="textbox-input-box datetimepicker-input-subbox" align="center">
  77.           <html:input class="datetimepicker-input textbox-input" anonid="input-three"
  78.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  79.                       xbl:inherits="disabled,readonly"/>
  80.         </xul:hbox>
  81.         <xul:hbox class="textbox-input-box datetimepicker-input-subbox" align="center">
  82.           <html:input class="datetimepicker-input textbox-input" anonid="input-ampm"
  83.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  84.                       xbl:inherits="disabled,readonly"/>
  85.         </xul:hbox>
  86.       </xul:hbox>
  87.       <xul:spinbuttons anonid="buttons" xbl:inherits="disabled"
  88.                        onup="this.parentNode._increaseOrDecrease(1);"
  89.                        ondown="this.parentNode._increaseOrDecrease(-1);"/>
  90.     </content>
  91.  
  92.     <implementation>
  93.       <field name="_dateValue">null</field>
  94.       <field name="_fieldOne">
  95.         document.getAnonymousElementByAttribute(this, "anonid", "input-one");
  96.       </field>
  97.       <field name="_fieldTwo">
  98.         document.getAnonymousElementByAttribute(this, "anonid", "input-two");
  99.       </field>
  100.       <field name="_fieldThree">
  101.         document.getAnonymousElementByAttribute(this, "anonid", "input-three");
  102.       </field>
  103.       <field name="_fieldAMPM">
  104.         document.getAnonymousElementByAttribute(this, "anonid", "input-ampm");
  105.       </field>
  106.       <field name="_separatorFirst">
  107.         document.getAnonymousElementByAttribute(this, "anonid", "sep-first");
  108.       </field>
  109.       <field name="_separatorSecond">
  110.         document.getAnonymousElementByAttribute(this, "anonid", "sep-second");
  111.       </field>
  112.       <field name="_lastFocusedField">null</field>
  113.       <field name="_hasEntry">true</field>
  114.       <field name="_valueEntered">false</field>
  115.       <field name="attachedControl">null</field>
  116.  
  117.       <property name="_currentField" readonly="true">
  118.         <getter>
  119.           var focusedInput = document.activeElement;
  120.           if (focusedInput == this._fieldOne ||
  121.               focusedInput == this._fieldTwo ||
  122.               focusedInput == this._fieldThree ||
  123.               focusedInput == this._fieldAMPM)
  124.             return focusedInput;
  125.           return this._lastFocusedField || this._fieldOne;
  126.         </getter>
  127.       </property>
  128.  
  129.       <property name="dateValue" onget="return new Date(this._dateValue);">
  130.         <setter>
  131.           <![CDATA[
  132.             if (!(val instanceof Date))
  133.               throw "Invalid Date";
  134.  
  135.             this._setValueNoSync(val);
  136.             if (this.attachedControl)
  137.               this.attachedControl._setValueNoSync(val);
  138.             return val;
  139.           ]]>
  140.         </setter>
  141.       </property>
  142.  
  143.       <property name="readOnly" onset="if (val) this.setAttribute('readonly', 'true');
  144.                                        else this.removeAttribute('readonly'); return val;"
  145.                                 onget="return this.getAttribute('readonly') == 'true';"/>
  146.  
  147.       <method name="_fireEvent">
  148.         <parameter name="aEventName"/>
  149.         <parameter name="aTarget"/>
  150.         <body>
  151.           var event = document.createEvent("Events");
  152.           event.initEvent(aEventName, true, true);
  153.           return !aTarget.dispatchEvent(event);
  154.         </body>
  155.       </method>
  156.  
  157.       <method name="_setValueOnChange">
  158.         <parameter name="aField"/>
  159.         <body>
  160.           <![CDATA[
  161.             if (!this._hasEntry)
  162.               return;
  163.  
  164.             if (aField == this._fieldOne ||
  165.                 aField == this._fieldTwo ||
  166.                 aField == this._fieldThree) {
  167.               var value = Number(aField.value);
  168.               if (isNaN(value))
  169.                 value = 0;
  170.  
  171.               value = this._constrainValue(aField, value, true);
  172.               this._setFieldValue(aField, value);
  173.             }
  174.           ]]>
  175.         </body>
  176.       </method>
  177.  
  178.       <method name="_init">
  179.         <body/>
  180.       </method>
  181.  
  182.       <constructor>
  183.         this._init();
  184.  
  185.         var cval = this.getAttribute("value");
  186.         if (cval) {
  187.           try {
  188.             this.value = cval;
  189.             return;
  190.           } catch (ex) { }
  191.         }
  192.         this.dateValue = new Date();
  193.       </constructor>
  194.  
  195.       <destructor>
  196.         if (this.attachedControl) {
  197.           this.attachedControl.attachedControl = null;
  198.           this.attachedControl = null;
  199.         }
  200.       </destructor>
  201.  
  202.     </implementation>
  203.  
  204.     <handlers>
  205.       <handler event="focus" phase="capturing">
  206.         <![CDATA[
  207.           var target = event.originalTarget;
  208.           if (target == this._fieldOne ||
  209.               target == this._fieldTwo ||
  210.               target == this._fieldThree ||
  211.               target == this._fieldAMPM)
  212.             this._lastFocusedField = target;
  213.         ]]>
  214.       </handler>
  215.  
  216.       <handler event="keypress">
  217.         <![CDATA[
  218.           if (this._hasEntry && event.charCode &&
  219.               this._currentField != this._fieldAMPM &&
  220.           ! (event.altKey || event.ctrlKey || event.metaKey) &&
  221.               (event.charCode < 48 || event.charCode > 57))
  222.             event.preventDefault();
  223.         ]]>
  224.       </handler>
  225.  
  226.       <handler event="keypress" keycode="VK_UP">
  227.         if (this._hasEntry)
  228.           this._increaseOrDecrease(1);
  229.       </handler>
  230.       <handler event="keypress" keycode="VK_DOWN">
  231.         if (this._hasEntry)
  232.           this._increaseOrDecrease(-1);
  233.       </handler>
  234.  
  235.       <handler event="input">
  236.         this._valueEntered = true;
  237.       </handler>
  238.  
  239.       <handler event="change">
  240.         this._setValueOnChange(event.originalTarget);
  241.       </handler>
  242.     </handlers>
  243.  
  244.   </binding>
  245.  
  246.   <binding id="timepicker"
  247.            extends="chrome://global/content/bindings/datetimepicker.xml#datetimepicker-base">
  248.  
  249.     <implementation>
  250.       <field name="is24HourClock" readonly="true">false</field>
  251.       <field name="hourLeadingZero" readonly="true">false</field>
  252.       <field name="minuteLeadingZero" readonly="true">true</field>
  253.       <field name="secondLeadingZero" readonly="true">true</field>
  254.       <field name="amIndicator" readonly="true">"AM"</field>
  255.       <field name="pmIndicator" readonly="true">"PM"</field>
  256.  
  257.       <field name="hourField">null</field>
  258.       <field name="minuteField">null</field>
  259.       <field name="secondField">null</field>
  260.  
  261.       <property name="value">
  262.         <getter>
  263.           <![CDATA[
  264.             var minute = this._dateValue.getMinutes();
  265.             if (minute < 10)
  266.               minute = "0" + minute;
  267.  
  268.             var second = this._dateValue.getSeconds();
  269.             if (second < 10)
  270.               second = "0" + second;
  271.             return this._dateValue.getHours() + ":" + minute + ":" + second;
  272.           ]]>
  273.         </getter>
  274.         <setter>
  275.           <![CDATA[
  276.             var items = val.match(/^([0-9]{1,2})\:([0-9]{1,2})\:?([0-9]{1,2})?$/);
  277.             if (!items)
  278.               throw "Invalid Time";
  279.  
  280.             var dt = this.dateValue;
  281.             dt.setHours(items[1]);
  282.             dt.setMinutes(items[2]);
  283.             dt.setSeconds(items[3] ? items[3] : 0);
  284.             this.dateValue = dt;
  285.             return val;
  286.           ]]>
  287.         </setter>
  288.       </property>
  289.       <property name="hour" onget="return this._dateValue.getHours();">
  290.         <setter>
  291.           <![CDATA[
  292.             var valnum = Number(val);
  293.             if (isNaN(valnum) || valnum < 0 || valnum > 23)
  294.               throw "Invalid Hour";
  295.             this._setFieldValue(this.hourField, valnum);
  296.             return val;
  297.           ]]>
  298.         </setter>
  299.       </property>
  300.       <property name="minute" onget="return this._dateValue.getMinutes();">
  301.         <setter>
  302.           <![CDATA[
  303.             var valnum = Number(val);
  304.             if (isNaN(valnum) || valnum < 0 || valnum > 59)
  305.               throw "Invalid Minute";
  306.             this._setFieldValue(this.minuteField, valnum);
  307.             return val;
  308.           ]]>
  309.         </setter>
  310.       </property>
  311.       <property name="second" onget="return this._dateValue.getSeconds();">
  312.         <setter>
  313.           <![CDATA[
  314.             var valnum = Number(val);
  315.             if (isNaN(valnum) || valnum < 0 || valnum > 59)
  316.               throw "Invalid Second";
  317.             this._setFieldValue(this.secondField, valnum);
  318.             return val;
  319.           ]]>
  320.         </setter>
  321.       </property>
  322.       <property name="isPM">
  323.         <getter>
  324.           <![CDATA[
  325.             return (this.hour >= 12);
  326.           ]]>
  327.         </getter>
  328.         <setter>
  329.           <![CDATA[
  330.             if (val) {
  331.               if (this.hour < 12)
  332.                 this.hour += 12;
  333.             }
  334.             else if (this.hour >= 12)
  335.               this.hour -= 12;
  336.             return val;
  337.           ]]>
  338.         </setter>
  339.       </property>
  340.       <property name="hideSeconds">
  341.         <getter>
  342.           return (this.getAttribute("hideseconds") == "true");
  343.         </getter>
  344.         <setter>
  345.           if (val)
  346.             this.setAttribute("hideseconds", "true");
  347.           else
  348.             this.removeAttribute("hideseconds");
  349.           if (this.secondField)
  350.             this.secondField.parentNode.collapsed = val;
  351.           this._separatorSecond.collapsed = val;
  352.           return val;
  353.         </setter>
  354.       </property>
  355.       <property name="increment">
  356.         <getter>
  357.           <![CDATA[
  358.             var increment = this.getAttribute("increment");
  359.             increment = Number(increment);
  360.             if (isNaN(increment) || increment <= 0 || increment >= 60)
  361.               return 1;
  362.             return increment;
  363.           ]]>
  364.         </getter>
  365.         <setter>
  366.           <![CDATA[
  367.             if (typeof val == "number")
  368.               this.setAttribute("increment", val);
  369.             return val;
  370.           ]]>
  371.         </setter>
  372.       </property>
  373.  
  374.       <method name="_setValueNoSync">
  375.         <parameter name="aValue"/>
  376.         <body>
  377.           <![CDATA[
  378.             var dt = new Date(aValue);
  379.             if (!isNaN(dt)) {
  380.               this._dateValue = dt;
  381.               this.setAttribute("value", this.value);
  382.               this._updateUI(this.hourField, this.hour);
  383.               this._updateUI(this.minuteField, this.minute);
  384.               this._updateUI(this.secondField, this.second);
  385.             }
  386.           ]]>
  387.         </body>
  388.       </method>
  389.       <method name="_increaseOrDecrease">
  390.         <parameter name="aDir"/>
  391.         <body>
  392.           <![CDATA[
  393.             if (this.disabled || this.readOnly)
  394.               return;
  395.  
  396.             var field = this._currentField;
  397.             if (this._valueEntered)
  398.               this._setValueOnChange(field);
  399.  
  400.             if (field == this._fieldAMPM) {
  401.               this.isPM = !this.isPM;
  402.               this._fireEvent("change", this);
  403.             }
  404.             else {
  405.               var oldval;
  406.               var change = aDir;
  407.               if (field == this.hourField) {
  408.                 oldval = this.hour;
  409.               }
  410.               else if (field == this.minuteField) {
  411.                 oldval = this.minute;
  412.                 change *= this.increment;
  413.               }
  414.               else if (field == this.secondField) {
  415.                 oldval = this.second;
  416.               }
  417.  
  418.               var newval = this._constrainValue(field, oldval + change, false);
  419.  
  420.               if (field == this.hourField)
  421.                 this.hour = newval;
  422.               else if (field == this.minuteField)
  423.                 this.minute = newval;
  424.               else if (field == this.secondField)
  425.                 this.second = newval;
  426.  
  427.               if (oldval != newval)
  428.                 this._fireEvent("change", this);
  429.             }
  430.             field.select();
  431.           ]]>
  432.         </body>
  433.       </method>
  434.       <method name="_setFieldValue">
  435.         <parameter name="aField"/>
  436.         <parameter name="aValue"/>
  437.         <body>
  438.           <![CDATA[
  439.             if (aField == this.hourField)
  440.               this._dateValue.setHours(aValue);
  441.             else if (aField == this.minuteField)
  442.               this._dateValue.setMinutes(aValue);
  443.             else if (aField == this.secondField)
  444.               this._dateValue.setSeconds(aValue);
  445.  
  446.             this.setAttribute("value", this.value);
  447.             this._updateUI(aField, aValue);
  448.  
  449.             if (this.attachedControl)
  450.               this.attachedControl._setValueNoSync(this._dateValue);
  451.           ]]>
  452.         </body>
  453.       </method>
  454.       <method name="_updateUI">
  455.         <parameter name="aField"/>
  456.         <parameter name="aValue"/>
  457.         <body>
  458.           <![CDATA[
  459.             this._valueEntered = false;
  460.  
  461.             var prependZero = false;
  462.             if (aField == this.hourField) {
  463.               prependZero = this.hourLeadingZero;
  464.               if (!this.is24HourClock) {
  465.                 if (aValue >= 12) {
  466.                   if (aValue > 12)
  467.                     aValue -= 12;
  468.                   this._fieldAMPM.value = this.pmIndicator;
  469.                 }
  470.                 else {
  471.                   if (aValue == 0)
  472.                     aValue = 12;
  473.                   this._fieldAMPM.value = this.amIndicator;
  474.                 }
  475.               }
  476.             }
  477.             else if (aField == this.minuteField) {
  478.               prependZero = this.minuteLeadingZero;
  479.             }
  480.             else if (aField == this.secondField) {
  481.               prependZero = this.secondLeadingZero;
  482.             }
  483.  
  484.             if (prependZero && aValue < 10)
  485.               aField.value = "0" + aValue;
  486.             else
  487.               aField.value = aValue;
  488.           ]]>
  489.         </body>
  490.       </method>
  491.       <method name="_constrainValue">
  492.         <parameter name="aField"/>
  493.         <parameter name="aValue"/>
  494.         <parameter name="aNoWrap"/>
  495.         <body>
  496.           <![CDATA[
  497.             // aNoWrap is true when the user entered a value, so just
  498.             // constrain within limits. If false, the value is being
  499.             // incremented or decremented, so wrap around values 
  500.             var max = (aField == this.hourField) ? 24 : 60;
  501.             if (aValue < 0)
  502.               return aNoWrap ? 0 : max + aValue;
  503.             if (aValue >= max)
  504.               return aNoWrap ? max - 1 : aValue - max;
  505.             return aValue;
  506.           ]]>
  507.         </body>
  508.       </method>
  509.       <method name="_init">
  510.         <body>
  511.           <![CDATA[
  512.             this.hourField = this._fieldOne;
  513.             this.minuteField = this._fieldTwo;
  514.             this.secondField = this._fieldThree;
  515.  
  516.             var numberOrder = /^(\D*)\s*(\d+)(\D*)(\d+)(\D*)(\d+)\s*(\D*)$/;
  517.  
  518.             var pmTime = new Date(2000,0,1,16,7,9).toLocaleFormat("%X");
  519.             var numberFields = pmTime.match(numberOrder);
  520.             if (numberFields) {
  521.               this._separatorFirst.value = numberFields[3];
  522.               this._separatorSecond.value = numberFields[5];
  523.               if (Number(numberFields[2]) > 12)
  524.                 this.is24HourClock = true;
  525.               else
  526.                 this.pmIndicator = numberFields[1] || numberFields[7];
  527.             }
  528.  
  529.             var amTime = new Date(2000,0,1,1,7,9).toLocaleFormat("%X");
  530.             numberFields = amTime.match(numberOrder);
  531.             if (numberFields) {
  532.               this.hourLeadingZero = (numberFields[2].length > 1);
  533.               this.minuteLeadingZero = (numberFields[4].length > 1);
  534.               this.secondLeadingZero = (numberFields[6].length > 1);
  535.  
  536.               if (!this.is24HourClock) {
  537.                 this.amIndicator = numberFields[1] || numberFields[7];
  538.                 if (numberFields[1]) {
  539.                   var mfield = this._fieldAMPM.parentNode;
  540.                   var mcontainer = mfield.parentNode;
  541.                   mcontainer.insertBefore(mfield, mcontainer.firstChild);
  542.                 }
  543.                 var size = (numberFields[1] || numberFields[7]).length;
  544.                 if (this.pmIndicator.length > size)
  545.                   size = this.pmIndicator.length;
  546.                 this._fieldAMPM.size = size;
  547.                 this._fieldAMPM.maxLength = size;
  548.               }
  549.               else {
  550.                 this._fieldAMPM.parentNode.collapsed = true;
  551.               }
  552.             }
  553.  
  554.             this.hideSeconds = this.hideSeconds;
  555.           ]]>
  556.         </body>
  557.       </method>
  558.     </implementation>
  559.  
  560.     <handlers>
  561.       <handler event="keypress">
  562.         <![CDATA[
  563.           // just allow any printable character to switch the AM/PM state
  564.           if (event.charCode && !this.disabled && !this.readOnly &&
  565.               this._currentField == this._fieldAMPM) {
  566.             this.isPM = !this.isPM;
  567.             this._fieldAMPM.select();
  568.             this._fireEvent("change", this);
  569.             event.preventDefault();
  570.           }
  571.         ]]>
  572.       </handler>
  573.     </handlers>
  574.  
  575.   </binding>
  576.  
  577.   <binding id="datepicker"
  578.            extends="chrome://global/content/bindings/datetimepicker.xml#datetimepicker-base">
  579.  
  580.     <implementation>
  581.       <field name="yearLeadingZero">false</field>
  582.       <field name="monthLeadingZero">true</field>
  583.       <field name="dateLeadingZero">true</field>
  584.  
  585.       <field name="yearField"/>
  586.       <field name="monthField"/>
  587.       <field name="dateField"/>
  588.  
  589.       <property name="value">
  590.         <getter>
  591.           <![CDATA[
  592.             var month = this._dateValue.getMonth();
  593.             month = (month < 9) ? month = "0" + ++month : month + 1;
  594.  
  595.             var date = this._dateValue.getDate();
  596.             if (date < 10)
  597.               date = "0" + date;
  598.             return this._dateValue.getFullYear() + "-" + month + "-" + date;
  599.           ]]>
  600.  
  601.         </getter>
  602.         <setter>
  603.           <![CDATA[
  604.             var results = val.match(/^([0-9]{1,4})\-([0-9]{1,2})\-([0-9]{1,2})$/);
  605.             if (!results)
  606.               throw "Invalid Date";
  607.  
  608.             this.dateValue = new Date(results[1] + "/" + results[2] + "/" + results[3]);
  609.             this.setAttribute("value", this.value);
  610.             return val;
  611.           ]]>
  612.         </setter>
  613.       </property>
  614.       <property name="year" onget="return this._dateValue.getFullYear();">
  615.         <setter>
  616.           <![CDATA[
  617.             var valnum = Number(val);
  618.             if (isNaN(valnum) || valnum < 1 || valnum > 9999)
  619.               throw "Invalid Year";
  620.             this._setFieldValue(this.yearField, valnum);
  621.             return val;
  622.           ]]>
  623.         </setter>
  624.       </property>
  625.       <property name="month" onget="return this._dateValue.getMonth();">
  626.         <setter>
  627.           <![CDATA[
  628.             var valnum = Number(val);
  629.             if (isNaN(valnum) || valnum < 0 || valnum > 11)
  630.               throw "Invalid Month";
  631.             this._setFieldValue(this.monthField, valnum);
  632.             return val;
  633.           ]]>
  634.         </setter>
  635.       </property>
  636.       <property name="date" onget="return this._dateValue.getDate();">
  637.         <setter>
  638.           <![CDATA[
  639.             var valnum = Number(val);
  640.             if (isNaN(valnum) || valnum < 1 || valnum > 31)
  641.               throw "Invalid Date";
  642.             this._setFieldValue(this.dateField, valnum);
  643.             return val;
  644.           ]]>
  645.         </setter>
  646.       </property>
  647.       <property name="open" onget="return false;" onset="return val;"/>
  648.  
  649.       <method name="_setValueNoSync">
  650.         <parameter name="aValue"/>
  651.         <body>
  652.           <![CDATA[
  653.             var dt = new Date(aValue);
  654.             if (!isNaN(dt)) {
  655.               this._dateValue = dt;
  656.               this.setAttribute("value", this.value);
  657.               this._updateUI(this.yearField, this.year);
  658.               this._updateUI(this.monthField, this.month);
  659.               this._updateUI(this.dateField, this.date);
  660.             }
  661.           ]]>
  662.         </body>
  663.       </method>
  664.       <method name="_increaseOrDecrease">
  665.         <parameter name="aDir"/>
  666.         <body>
  667.           <![CDATA[
  668.             if (this.disabled || this.readOnly)
  669.               return;
  670.  
  671.             var field = this._currentField;
  672.             if (this._valueEntered)
  673.               this._setValueOnChange(field);
  674.  
  675.             var oldval;
  676.             if (field == this.yearField)
  677.               oldval = this.year;
  678.             else if (field == this.monthField)
  679.               oldval = this.month;
  680.             else if (field == this.dateField)
  681.               oldval = this.date;
  682.  
  683.             var newval = this._constrainValue(field, oldval + aDir, false);
  684.  
  685.             if (field == this.yearField)
  686.               this.year = newval;
  687.             else if (field == this.monthField)
  688.               this.month = newval;
  689.             else if (field == this.dateField)
  690.               this.date = newval;
  691.  
  692.             if (oldval != newval)
  693.               this._fireEvent("change", this);
  694.             field.select();
  695.           ]]>
  696.         </body>
  697.       </method>
  698.       <method name="_setFieldValue">
  699.         <parameter name="aField"/>
  700.         <parameter name="aValue"/>
  701.         <body>
  702.           <![CDATA[
  703.             if (aField == this.yearField) {
  704.               var oldDate = this.date;
  705.               this._dateValue.setFullYear(aValue);
  706.               if (oldDate != this.date) {
  707.                 this._dateValue.setDate(0);
  708.                 this._updateUI(this.dateField, this.date);
  709.               }
  710.             }
  711.             else if (aField == this.monthField) {
  712.               var oldDate = this.date;
  713.               this._dateValue.setMonth(aValue);
  714.               if (oldDate != this.date) {
  715.                 this._dateValue.setDate(0);
  716.                 this._updateUI(this.dateField, this.date);
  717.               }
  718.             }
  719.             else if (aField == this.dateField) {
  720.               this._dateValue.setDate(aValue);
  721.             }
  722.  
  723.             this.setAttribute("value", this.value);
  724.             this._updateUI(aField, aValue);
  725.  
  726.             if (this.attachedControl)
  727.               this.attachedControl._setValueNoSync(this._dateValue);
  728.           ]]>
  729.         </body>
  730.       </method>
  731.       <method name="_updateUI">
  732.         <parameter name="aField"/>
  733.         <parameter name="aValue"/>
  734.         <body>
  735.           <![CDATA[
  736.             this._valueEntered = false;
  737.  
  738.             var prependZero = false;
  739.             if (aField == this.yearField) {
  740.               if (this.yearLeadingZero) {
  741.                 aField.value = ("000" + aValue).slice(-4);
  742.                 return;
  743.               }
  744.             }
  745.             else if (aField == this.monthField) {
  746.               aValue++;
  747.               prependZero = this.monthLeadingZero;
  748.             }
  749.             else if (aField == this.dateField) {
  750.               prependZero = this.dateLeadingZero;
  751.             }
  752.             if (prependZero && aValue < 10)
  753.               aField.value = "0" + aValue;
  754.             else
  755.               aField.value = aValue;
  756.           ]]>
  757.         </body>
  758.       </method>
  759.       <method name="_constrainValue">
  760.         <parameter name="aField"/>
  761.         <parameter name="aValue"/>
  762.         <parameter name="aNoWrap"/>
  763.         <body>
  764.           <![CDATA[
  765.             // the month will be 1 to 12 if entered by the user, so subtract 1
  766.             if (aNoWrap && aField == this.monthField)
  767.               aValue--;
  768.  
  769.             if (aField == this.dateField) {
  770.               if (aValue < 1)
  771.                 return new Date(this.year, this.month + 1, 0).getDate();
  772.  
  773.               var currentMonth = this.month;
  774.               var dt = new Date(this.year, currentMonth, aValue);
  775.               return (dt.getMonth() != currentMonth ? 1 : aValue);
  776.             }
  777.             var min = (aField == this.monthField) ? 0 : 1;
  778.             var max = (aField == this.monthField) ? 11 : 9999;
  779.             if (aValue < min)
  780.               return aNoWrap ? min : max;
  781.             if (aValue > max)
  782.               return aNoWrap ? max : min;
  783.             return aValue;
  784.           ]]>
  785.         </body>
  786.       </method>
  787.       <method name="_init">
  788.         <body>
  789.           <![CDATA[
  790.             var numberOrder = /^(\D*)\s*(\d+)(\D*)(\d+)(\D*)(\d+)\s*(\D*)$/;
  791.  
  792.             var dt = new Date(2002,9,4).toLocaleFormat("%x");
  793.             var numberFields = dt.match(numberOrder);
  794.             if (numberFields) {
  795.               this._separatorFirst.value = numberFields[3];
  796.               this._separatorSecond.value = numberFields[5];
  797.  
  798.               var twoDigitYear = false;
  799.               var yfield = "input-one";
  800.               var mfield = "input-two";
  801.               var dfield = "input-three";
  802.               var yi = 2, mi = 4, di = 6;
  803.               for (var i = 1; i < numberFields.length; i++) {
  804.                 switch (Number(numberFields[i])) {
  805.                   case 2:
  806.                     twoDigitYear = true; // fall through
  807.                   case 2002:
  808.                     yi = i;
  809.                     yfield = (i == 2 ? "input-one" :
  810.                              (i == 4 ? "input-two" : "input-three"));
  811.                     break;
  812.                   case 9, 10:
  813.                     mi = i;
  814.                     mfield = (i == 2 ? "input-one" :
  815.                              (i == 4 ? "input-two" : "input-three"));
  816.                     break;
  817.                   case 4:
  818.                     di = i;
  819.                     dfield = (i == 2 ? "input-one" :
  820.                              (i == 4 ? "input-two" : "input-three"));
  821.                     break;
  822.                 }
  823.               }
  824.             }
  825.  
  826.             this.yearField = document.getAnonymousElementByAttribute(this, "anonid", yfield);
  827.             if (!twoDigitYear)
  828.               this.yearField.parentNode.className =
  829.                 "datetimepicker-input-subbox datetimepicker-year";
  830.             this.monthField = document.getAnonymousElementByAttribute(this, "anonid", mfield);
  831.             this.dateField = document.getAnonymousElementByAttribute(this, "anonid", dfield);
  832.  
  833.             this.yearLeadingZero = (numberFields[yi].length > 1);
  834.             this.monthLeadingZero = (numberFields[mi].length > 1);
  835.             this.dateLeadingZero = (numberFields[di].length > 1);
  836.  
  837.             this._fieldAMPM.parentNode.collapsed = true;
  838.             this.yearField.size = twoDigitYear ? 2 : 4;
  839.             this.yearField.maxLength = twoDigitYear ? 2 : 4;
  840.           ]]>
  841.         </body>
  842.       </method>
  843.     </implementation>
  844.  
  845.   </binding>
  846.  
  847.   <binding id="datepicker-grid"
  848.            extends="chrome://global/content/bindings/datetimepicker.xml#datepicker">
  849.  
  850.     <content>
  851.       <vbox class="datepicker-mainbox"
  852.             xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  853.         <hbox class="datepicker-monthbox" align="center">
  854.           <button class="datepicker-previous datepicker-button" type="repeat"
  855.                   chromedir="&locale.dir;" xbl:inherits="disabled"
  856.                   oncommand="document.getBindingParent(this)._increaseOrDecreaseMonth(-1);"/>
  857.           <spacer flex="1"/>
  858.           <deck anonid="monthlabeldeck">
  859.             <label class="datepicker-gridlabel"/>
  860.             <label class="datepicker-gridlabel"/>
  861.             <label class="datepicker-gridlabel"/>
  862.             <label class="datepicker-gridlabel"/>
  863.             <label class="datepicker-gridlabel"/>
  864.             <label class="datepicker-gridlabel"/>
  865.             <label class="datepicker-gridlabel"/>
  866.             <label class="datepicker-gridlabel"/>
  867.             <label class="datepicker-gridlabel"/>
  868.             <label class="datepicker-gridlabel"/>
  869.             <label class="datepicker-gridlabel"/>
  870.             <label class="datepicker-gridlabel"/>
  871.           </deck>
  872.           <label anonid="yearlabel" class="datepicker-gridlabel"/>
  873.           <spacer flex="1"/>
  874.           <button class="datepicker-next datepicker-button" type="repeat"
  875.                   chromedir="&locale.dir;" xbl:inherits="disabled"
  876.                   oncommand="document.getBindingParent(this)._increaseOrDecreaseMonth(1);"/>
  877.         </hbox>
  878.         <grid class="datepicker-grid" role="grid">
  879.           <columns>
  880.             <column class="datepicker-gridrow" flex="1"/>
  881.             <column class="datepicker-gridrow" flex="1"/>
  882.             <column class="datepicker-gridrow" flex="1"/>
  883.             <column class="datepicker-gridrow" flex="1"/>
  884.             <column class="datepicker-gridrow" flex="1"/>
  885.             <column class="datepicker-gridrow" flex="1"/>
  886.             <column class="datepicker-gridrow" flex="1"/>
  887.           </columns>
  888.           <rows anonid="datebox">
  889.             <row anonid="dayofweekbox">
  890.               <label class="datepicker-weeklabel" role="columnheader"/>
  891.               <label class="datepicker-weeklabel" role="columnheader"/>
  892.               <label class="datepicker-weeklabel" role="columnheader"/>
  893.               <label class="datepicker-weeklabel" role="columnheader"/>
  894.               <label class="datepicker-weeklabel" role="columnheader"/>
  895.               <label class="datepicker-weeklabel" role="columnheader"/>
  896.               <label class="datepicker-weeklabel" role="columnheader"/>
  897.             </row>
  898.             <row>
  899.               <label class="datepicker-gridlabel" role="gridcell"/>
  900.               <label class="datepicker-gridlabel" role="gridcell"/>
  901.               <label class="datepicker-gridlabel" role="gridcell"/>
  902.               <label class="datepicker-gridlabel" role="gridcell"/>
  903.               <label class="datepicker-gridlabel" role="gridcell"/>
  904.               <label class="datepicker-gridlabel" role="gridcell"/>
  905.               <label class="datepicker-gridlabel" role="gridcell"/>
  906.             </row>
  907.             <row>
  908.               <label class="datepicker-gridlabel" role="gridcell"/>
  909.               <label class="datepicker-gridlabel" role="gridcell"/>
  910.               <label class="datepicker-gridlabel" role="gridcell"/>
  911.               <label class="datepicker-gridlabel" role="gridcell"/>
  912.               <label class="datepicker-gridlabel" role="gridcell"/>
  913.               <label class="datepicker-gridlabel" role="gridcell"/>
  914.               <label class="datepicker-gridlabel" role="gridcell"/>
  915.             </row>
  916.             <row>
  917.               <label class="datepicker-gridlabel" role="gridcell"/>
  918.               <label class="datepicker-gridlabel" role="gridcell"/>
  919.               <label class="datepicker-gridlabel" role="gridcell"/>
  920.               <label class="datepicker-gridlabel" role="gridcell"/>
  921.               <label class="datepicker-gridlabel" role="gridcell"/>
  922.               <label class="datepicker-gridlabel" role="gridcell"/>
  923.               <label class="datepicker-gridlabel" role="gridcell"/>
  924.             </row>
  925.             <row>
  926.               <label class="datepicker-gridlabel" role="gridcell"/>
  927.               <label class="datepicker-gridlabel" role="gridcell"/>
  928.               <label class="datepicker-gridlabel" role="gridcell"/>
  929.               <label class="datepicker-gridlabel" role="gridcell"/>
  930.               <label class="datepicker-gridlabel" role="gridcell"/>
  931.               <label class="datepicker-gridlabel" role="gridcell"/>
  932.               <label class="datepicker-gridlabel" role="gridcell"/>
  933.             </row>
  934.             <row>
  935.               <label class="datepicker-gridlabel" role="gridcell"/>
  936.               <label class="datepicker-gridlabel" role="gridcell"/>
  937.               <label class="datepicker-gridlabel" role="gridcell"/>
  938.               <label class="datepicker-gridlabel" role="gridcell"/>
  939.               <label class="datepicker-gridlabel" role="gridcell"/>
  940.               <label class="datepicker-gridlabel" role="gridcell"/>
  941.               <label class="datepicker-gridlabel" role="gridcell"/>
  942.             </row>
  943.             <row>
  944.               <label class="datepicker-gridlabel" role="gridcell"/>
  945.               <label class="datepicker-gridlabel" role="gridcell"/>
  946.               <label class="datepicker-gridlabel" role="gridcell"/>
  947.               <label class="datepicker-gridlabel" role="gridcell"/>
  948.               <label class="datepicker-gridlabel" role="gridcell"/>
  949.               <label class="datepicker-gridlabel" role="gridcell"/>
  950.               <label class="datepicker-gridlabel" role="gridcell"/>
  951.             </row>
  952.           </rows>
  953.         </grid>
  954.       </vbox>
  955.     </content>
  956.  
  957.     <implementation>
  958.       <field name="_hasEntry">false</field>
  959.       <field name="_weekStart">&firstdayofweek.default;</field>
  960.       <field name="_displayedDate">null</field>
  961.       <field name="_todayItem">null</field>
  962.  
  963.       <field name="yearField">
  964.         document.getAnonymousElementByAttribute(this, "anonid", "yearlabel");
  965.       </field>
  966.       <field name="monthField">
  967.         document.getAnonymousElementByAttribute(this, "anonid", "monthlabeldeck");
  968.       </field>
  969.       <field name="dateField">
  970.         document.getAnonymousElementByAttribute(this, "anonid", "datebox");
  971.       </field>
  972.  
  973.       <field name="_selectedItem">null</field>
  974.  
  975.       <property name="selectedItem" onget="return this._selectedItem">
  976.         <setter>
  977.           <![CDATA[
  978.             if (!val.value)
  979.               return val;
  980.             if (val.parentNode.parentNode != this.dateField)
  981.               return val;
  982.  
  983.             if (this._selectedItem)
  984.               this._selectedItem.removeAttribute("selected");
  985.             this._selectedItem = val;
  986.             val.setAttribute("selected", "true");
  987.             this._displayedDate.setDate(val.value);
  988.             return val;
  989.           ]]>
  990.         </setter>
  991.       </property>
  992.  
  993.       <method name="_init">
  994.         <body>
  995.           <![CDATA[
  996.             var monthLabel = this.monthField.firstChild;
  997.             var tempDate = new Date(2005, 0, 1);
  998.             for (var month = 0; month < 12; month++) {
  999.               tempDate.setMonth(month);
  1000.               monthLabel.setAttribute("value", tempDate.toLocaleFormat("%B"));
  1001.               monthLabel = monthLabel.nextSibling;
  1002.             }
  1003.  
  1004.             var fdow = Number(this.getAttribute("firstdayofweek"));
  1005.             if (!isNaN(fdow) && fdow >= 0 && fdow <= 6)
  1006.               this._weekStart = fdow;
  1007.  
  1008.             var weekbox = document.getAnonymousElementByAttribute(this, "anonid", "dayofweekbox").childNodes;
  1009.             var date = new Date();
  1010.             date.setDate(date.getDate() - (date.getDay() - this._weekStart));
  1011.             for (var i = 0; i < weekbox.length; i++) {
  1012.               weekbox[i].value = date.toLocaleFormat("%a").charAt(0);
  1013.               date.setDate(date.getDate() + 1);
  1014.             }
  1015.           ]]>
  1016.         </body>
  1017.       </method>
  1018.       <method name="_setValueNoSync">
  1019.         <parameter name="aValue"/>
  1020.         <body>
  1021.           <![CDATA[
  1022.             var dt = new Date(aValue);
  1023.             if (!isNaN(dt)) {
  1024.               this._dateValue = dt;
  1025.               this.setAttribute("value", this.value);
  1026.               this._updateUI();
  1027.             }
  1028.           ]]>
  1029.         </body>
  1030.       </method>
  1031.       <method name="_updateUI">
  1032.         <parameter name="aField"/>
  1033.         <parameter name="aValue"/>
  1034.         <parameter name="aIncDecMonth"/>
  1035.         <body>
  1036.           <![CDATA[
  1037.             var date;
  1038.             var currentMonth;
  1039.             if (aIncDecMonth) {
  1040.               if (!this._displayedDate)
  1041.                 this._displayedDate = this.dateValue;
  1042.               this._displayedDate.setMonth(aValue);
  1043.  
  1044.               date = new Date(this._displayedDate);
  1045.               currentMonth = this._displayedDate.getMonth();
  1046.             }
  1047.             else {
  1048.               var samemonth = (this._displayedDate &&
  1049.                                this._displayedDate.getMonth() == this.month &&
  1050.                                this._displayedDate.getFullYear() == this.year);
  1051.               if (samemonth) {
  1052.                 var items = this.dateField.getElementsByAttribute("value", this.date);
  1053.                 if (items.length)
  1054.                   this.selectedItem = items[0];
  1055.                 return;
  1056.               }
  1057.  
  1058.               date = this.dateValue;
  1059.               this._displayedDate = new Date(date);
  1060.               currentMonth = this.month;
  1061.             }
  1062.  
  1063.             if (this._todayItem) {
  1064.               this._todayItem.removeAttribute("today");
  1065.               this._todayItem = null;
  1066.             }
  1067.  
  1068.             if (this._selectedItem) {
  1069.               this._selectedItem.removeAttribute("selected");
  1070.               this._selectedItem = null;
  1071.             }
  1072.  
  1073.             // Update the month and year title
  1074.             this.monthField.selectedIndex = currentMonth;
  1075.             this.yearField.setAttribute("value", date.getFullYear());
  1076.  
  1077.             date.setDate(1);
  1078.             var firstWeekday = (7 + date.getDay() - this._weekStart) % 7;
  1079.             date.setDate(date.getDate() - firstWeekday);
  1080.  
  1081.             var today = new Date();
  1082.             var datebox = this.dateField;
  1083.             for (var k = 1; k < datebox.childNodes.length; k++) {
  1084.               var row = datebox.childNodes[k];
  1085.               for (var i = 0; i < 7; i++) {
  1086.                 var item = row.childNodes[i];
  1087.  
  1088.                 if (currentMonth == date.getMonth()) {
  1089.                   item.value = date.getDate();
  1090.  
  1091.                   // highlight today
  1092.                   if (this._isSameDay(today, date)) {
  1093.                     this._todayItem = item;
  1094.                     item.setAttribute("today", "true");
  1095.                   }
  1096.  
  1097.                   // highlight the selected date
  1098.                   if (this._isSameDay(this._dateValue, date)) {
  1099.                     this._selectedItem = item;
  1100.                     item.setAttribute("selected", "true");
  1101.                   }
  1102.                 }
  1103.                 else {
  1104.                   item.value = "";
  1105.                 }
  1106.  
  1107.                 date.setDate(date.getDate() + 1);
  1108.               }
  1109.             }
  1110.  
  1111.             this._fireEvent("monthchange", this);
  1112.             if (this.hasAttribute("monthchange")) {
  1113.               var fn = new Function("event", aTarget.getAttribute("onmonthchange"));
  1114.               fn.call(aTarget, event);
  1115.             }
  1116.           ]]>
  1117.         </body>
  1118.       </method>
  1119.       <method name="_increaseOrDecreaseDateFromEvent">
  1120.         <parameter name="aEvent"/>
  1121.         <parameter name="aDiff"/>
  1122.         <body>
  1123.           <![CDATA[
  1124.             if (aEvent.originalTarget == this && !this.disabled && !this.readOnly) {
  1125.               var newdate = this.dateValue;
  1126.               newdate.setDate(newdate.getDate() + aDiff);
  1127.               this.dateValue = newdate;
  1128.               this._fireEvent("change", this);
  1129.             }
  1130.             aEvent.stopPropagation();
  1131.             aEvent.preventDefault();
  1132.           ]]>
  1133.         </body>
  1134.       </method>
  1135.       <method name="_increaseOrDecreaseMonth">
  1136.         <parameter name="aDir"/>
  1137.         <body>
  1138.           <![CDATA[
  1139.             if (!this.disabled) {
  1140.               var month = this._displayedDate ? this._displayedDate.getMonth() :
  1141.                                                 this.month;
  1142.               this._updateUI(this.monthField, month + aDir, true);
  1143.             }
  1144.           ]]>
  1145.         </body>
  1146.       </method>
  1147.       <method name="_isSameDay">
  1148.         <parameter name="aDate1"/>
  1149.         <parameter name="aDate2"/>
  1150.         <body>
  1151.           <![CDATA[
  1152.             return (aDate1 && aDate2 &&
  1153.                     aDate1.getDate() == aDate2.getDate() &&
  1154.                     aDate1.getMonth() == aDate2.getMonth() &&
  1155.                     aDate1.getFullYear() == aDate2.getFullYear());
  1156.           ]]>
  1157.         </body>
  1158.       </method>
  1159.  
  1160.     </implementation>
  1161.  
  1162.     <handlers>
  1163.       <handler event="click">
  1164.         <![CDATA[
  1165.           if (event.button != 0 || this.disabled || this.readOnly)
  1166.             return;
  1167.  
  1168.           var target = event.originalTarget;
  1169.           if (target.className == "datepicker-gridlabel" &&
  1170.               target != this.selectedItem) {
  1171.             this.selectedItem = target;
  1172.             this._dateValue = new Date(this._displayedDate);
  1173.             if (this.attachedControl)
  1174.               this.attachedControl._setValueNoSync(this._dateValue);
  1175.             this._fireEvent("change", this);
  1176.  
  1177.             if (this.attachedControl && "open" in this.attachedControl)
  1178.               this.attachedControl.open = false; // close the popup
  1179.           }
  1180.         ]]>
  1181.       </handler>
  1182.       <handler event="DOMMouseScroll">
  1183.         <![CDATA[
  1184.           this._increaseOrDecreaseMonth(event.detail < 0 ? -1 : 1);
  1185.         ]]>
  1186.       </handler>
  1187.       <handler event="keypress" keycode="VK_LEFT"
  1188.                action="this._increaseOrDecreaseDateFromEvent(event, -1);"/>
  1189.       <handler event="keypress" keycode="VK_RIGHT"
  1190.                action="this._increaseOrDecreaseDateFromEvent(event, 1);"/>
  1191.       <handler event="keypress" keycode="VK_UP"
  1192.                action="this._increaseOrDecreaseDateFromEvent(event, -7);"/>
  1193.       <handler event="keypress" keycode="VK_DOWN"
  1194.                action="this._increaseOrDecreaseDateFromEvent(event, 7);"/>
  1195.       <handler event="keypress" keycode="VK_PAGE_UP"
  1196.                action="this._increaseOrDecreaseMonth(-1);"/>
  1197.       <handler event="keypress" keycode="VK_PAGE_DOWN"
  1198.                action="this._increaseOrDecreaseMonth(1);"/>
  1199.     </handlers>
  1200.   </binding>
  1201.  
  1202.   <binding id="datepicker-popup" display="xul:menu"
  1203.            extends="chrome://global/content/bindings/datetimepicker.xml#datepicker">
  1204.     <content align="center">
  1205.       <xul:hbox class="textbox-input-box datetimepicker-input-box" align="center"
  1206.                 allowevents="true" xbl:inherits="context">
  1207.         <xul:hbox class="datetimepicker-input-subbox" align="baseline">
  1208.           <html:input class="datetimepicker-input textbox-input" anonid="input-one"
  1209.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  1210.                       xbl:inherits="disabled,readonly"/>
  1211.         </xul:hbox>
  1212.         <xul:label anonid="sep-first" class="datetimepicker-separator" value=":"/>
  1213.         <xul:hbox class="datetimepicker-input-subbox" align="baseline">
  1214.           <html:input class="datetimepicker-input textbox-input" anonid="input-two"
  1215.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  1216.                       xbl:inherits="disabled,readonly"/>
  1217.         </xul:hbox>
  1218.         <xul:label anonid="sep-second" class="datetimepicker-separator" value=":"/>
  1219.         <xul:hbox class="datetimepicker-input-subbox" align="center">
  1220.           <html:input class="datetimepicker-input textbox-input" anonid="input-three"
  1221.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;"
  1222.                       xbl:inherits="disabled,readonly"/>
  1223.         </xul:hbox>
  1224.         <xul:hbox class="datetimepicker-input-subbox" align="center">
  1225.           <html:input class="datetimepicker-input textbox-input" anonid="input-ampm"
  1226.                       size="2" maxlength="2" flex="1" chromedir="&locale.dir;" 
  1227.                       xbl:inherits="disabled,readonly"/>
  1228.         </xul:hbox>
  1229.       </xul:hbox>
  1230.       <xul:spinbuttons anonid="buttons" xbl:inherits="disabled" allowevents="true"
  1231.                        onup="this.parentNode._increaseOrDecrease(1);"
  1232.                        ondown="this.parentNode._increaseOrDecrease(-1);"/>
  1233.       <xul:dropmarker class="datepicker-dropmarker" xbl:inherits="disabled"/>
  1234.       <xul:panel onpopupshown="this.firstChild.focus();">
  1235.         <xul:datepicker anonid="grid" type="grid" class="datepicker-popupgrid"
  1236.                         xbl:inherits="disabled,readonly,firstdayofweek"/>
  1237.       </xul:panel>
  1238.     </content>
  1239.     <implementation>
  1240.       <constructor>
  1241.         var grid = document.getAnonymousElementByAttribute(this, "anonid", "grid");
  1242.         this.attachedControl = grid;
  1243.         grid.attachedControl = this;
  1244.         grid._setValueNoSync(this._dateValue);
  1245.       </constructor>
  1246.       <property name="open" onget="return this.hasAttribute('open');">
  1247.         <setter>
  1248.           <![CDATA[
  1249.             if (this.boxObject instanceof Components.interfaces.nsIMenuBoxObject)
  1250.               this.boxObject.openMenu(val);
  1251.             return val;
  1252.           ]]>
  1253.         </setter>
  1254.       </property>
  1255.     </implementation>
  1256.   </binding>
  1257.  
  1258. </bindings>
  1259.