bug 278877, patch by andrew@progressivex.com (andrew@progressivex.com), gekacheka@yahoo.com and me.
r=gekacheka@yahoo.com
also fixes bug 273914. Also see bug 199779
This commit is contained in:
mvl%exedo.nl 2005-03-13 22:04:50 +00:00
Родитель 57b984965f
Коммит 88130df4ed
2 изменённых файлов: 0 добавлений и 753 удалений

Просмотреть файл

@ -1,245 +0,0 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is OEone Calendar Code, released October 31st, 2001.
-
- The Initial Developer of the Original Code is
- OEone Corporation.
- Portions created by the Initial Developer are Copyright (C) 2001
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Garth Smedley <garths@oeone.com>
- Mike Potter <mikep@oeone.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
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!--
/* DatePicker: text box + grid button XBL component.
Editing text box sets date if parseable as date using current
numerical short date format (in operating system).
Clicking button shows datepicker-grid for picking date in month.
Used in datetimepicker.xbl, calendar eventDialog.xul
Requires:
<?xml-stylesheet type="text/css"
href="chrome://calendar/content/datetimepickers/datepicker.css" ?>
May require (probably until bug 58757 fixed):
<script type="application/x-javascript"
src="chrome://global/content/strres.js" />
<script type="application/x-javascript"
src="chrome://calendar/content/dateUtils.js"/>
At site, can provide id, and code to run when value changed by picker.
<datepicker id="my-date-picker" onchange="myDatePick( this );"/>
May get/set value in javascript with
document.getElementById("my-date-picker").value = new Date();
May disable/enable in javascript with
document.getElementById("my-date-picker").disabled = true;
*/
-->
<bindings id="xulDatePicker"
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- this doesn't work, maybe bug 58757 -->
<xul:script xul:type="application/x-javascript"
xul:src="chrome://calendar/content/dateUtils.js"/>
<binding id="datepicker" extends="xul:box" xbl:inherits="value,onchange">
<!-- ::::::::::::::::: CONTENT ::::::::::::::::::::::::: -->
<!-- Desired behavior: when user is done editing the date field
and either leaves the field (onblur) or closes the dialog
(13 is enter/return key), parse the date and redisplay it
in the date field using the current format to verify
whether the date was parsed correctly.
This cannot be done with textbox oninput, so use a workaround.
This was done with textbox onkeypress="parseTextBoxDate(true)"
and onblur="parseTextBoxDate(true)" which worked in Moz1.6, but
no longer works in Moz1.7.
Therefore constructor stores attribute kDatePicker on the textbox,
and the onblur and onkeypress commands navigate to this kDatePicker.
xul:Textbox contains an xul:hbox which contains html:input.
Onkeypress and onblur are not documented attributes of xul:textbox,
but become attributes of the html:input.
Not clear how to navigate from the textbox to the input, otherwise
could put kDatePicker property on the input element.
[document.getAnonymousNodes(textBox) fails as of Moz1.7b]).
So navigate parents to textbox in order to call parseTextBoxDate.
[this comment is outside the <content> so it won't become a
node that interferes with navigation to interior nodes.] -->
<content id="content">
<xul:hbox flex="1" id="hbox" class="datepicker-box-class">
<xul:menulist editable="true" sizetopopup="false"
id="datepicker-text"
class="datepicker-text-class"
onkeypress="if (event.keyCode == 13) this.kDatePicker.parseTextBoxDate(true);"
xbl:inherits="disabled">
<xul:menupopup popupanchor="bottomright" popupalign="topright"
onpopupshowing="onPopup()">
<xul:minimonth onchange="this.kDatePicker.clickDate(this); "/>
</xul:menupopup>
</xul:menulist>
</xul:hbox>
</content>
<!-- ::::::::::::::::: INTERFACE ::::::::::::::::::::::::: -->
<implementation>
<property name="value"
onset="this.update(val,false)"
onget="return this.mValue"/>
<!-- called from datetimepicker.datepickerdisabled and datetimepicker.setDisabled -->
<property name="disabled"
onget="return this.mDisabled;"
onset="this.setDisabled( val );" />
<constructor>
<![CDATA[
var hbox = document.getAnonymousNodes(this)[0];
this.kTextBox = hbox.childNodes[0];
this.kTextBox.kDatePicker = this; // enable call back to method in Moz1.7
this.kMinimonth = this.kTextBox.menupopup.childNodes[0];
this.kMinimonth.kDatePicker = this; // enable call back to method in Moz1.6
this.kFormatter = new DateFormater();
// whether currently disabled
this.mDisabled = this.getAttribute("disabled") ? true : false;
this.mValue = null;
var val = this.getAttribute("value");
if (val) {
this.value = new Date(val); // setting value property calls update
} else {
this.value = new Date();
}
this.kCallback = null;
val = this.getAttribute("onchange");
if (val)
this.kCallback = function() { eval(val); };
]]>
</constructor>
<method name="update">
<parameter name="aValue"/>
<parameter name="aRefresh"/>
<body><![CDATA[
if (aValue != null) {
// format fails if year <= 1600 on win2k, so try format first.
var formattedValue = null;
try {
formattedValue = this.formatDate(aValue);
} catch (ex) {} // fall thru
if (formattedValue) {
// format succeeded, safe to set value
this.mValue = aValue;
this.kTextBox.value = formattedValue;
// called before constructor, so check aRefresh before kCallBack
if ( aRefresh != false && "kCallback" in this)
this.kCallback();
return;
}
}
// invalid date, revert to previous date
// set textBox.value property, not attribute
if (this.mValue) {
this.kTextBox.value = this.formatDate(this.mValue);
}
]]></body>
</method>
<method name="formatDate">
<parameter name="aValue"/>
<body><![CDATA[
return this.kFormatter.getShortFormatedDate(aValue);
]]></body>
</method>
<method name="setDisabled">
<parameter name="aDisabled" />
<body><![CDATA[
this.mDisabled = aDisabled;
if (this.mDisabled) {
this.kTextBox.setAttribute( "disabled", "true" );
} else {
this.kTextBox.removeAttribute( "disabled" );
}
]]></body>
</method>
<method name="onPopup">
<body><![CDATA[
this.kMinimonth.update( this.mValue );
// select all to remove cursor since can't type while popped-up
this.select();
]]></body>
</method>
<method name="parseTextBoxDate">
<parameter name="aRefresh"/>
<body><![CDATA[
this.update(this.kFormatter.parseShortDate(this.kTextBox.value),
aRefresh);
]]></body>
</method>
<method name="clickDate">
<parameter name="aMiniMonthGrid" />
<body><![CDATA[
this.update(new Date(aMiniMonthGrid.value), true);
// select changed value so no cursor appears (can't type to it).
this.select();
aMiniMonthGrid.parentNode.hidePopup();
]]></body>
</method>
<method name="select">
<body><![CDATA[
// select all in text box
this.kTextBox.select();
]]></body>
</method>
</implementation>
<!-- ::::::::::::::::: HANDLERS ::::::::::::::::::::::::: -->
<handlers>
<handler event="bindingattached" action="this.initialize();"/>
<handler event="blur" phase="capturing"><![CDATA[
this.parseTextBoxDate(true);
]]></handler>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -1,508 +0,0 @@
<?xml version="1.0"?>
<!--
/* MiniMonth Calendar: day-of-month grid XBL component.
Displays month name above days of month in grid, by week rows.
Arrows beside month move forward or back a month.
Clicking on a day cell calls onchange attribute.
Clicking on month arrows calls onmonthchange attribute.
Used in datepicker.xbl and as mini-month in calendar.xul of Calendar.
At site, can provide id, and code to run when value changed by picker.
<calendar id="my-date-picker" onchange="myDatePick( this );"/>
May get/set value in javascript with
document.getElementById("my-date-picker").value = new Date();
*/
-->
<bindings id="xulMiniMonth"
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="minimonth" extends="xul:box" xbl:inherits="onchange,onmonthchange">
<!-- ::::::::::::::::: CONTENT ::::::::::::::::::::::::: -->
<content>
<xul:vbox class="minimonth-mainbox" flex="1">
<xul:hbox class="minimonth-month-box">
<xul:image class="minimonth-navbtn" dir="-1"/>
<xul:spacer flex="1"/>
<xul:text id="month-name" class="minimonth-month-name" value="Month" popup="month-list"/>
<xul:text id="year-name" class="minimonth-year-name" value="Year" popup="year-list"/>
<xul:spacer flex="1"/>
<xul:image class="minimonth-navbtn" dir="1"/>
</xul:hbox>
<xul:vbox class="minimonth-cal-box" flex="1">
<xul:hbox class="minimonth-row-head" equalsize="always">
<xul:text class="minimonth-header" flex="1"/>
<xul:text class="minimonth-header" flex="1"/>
<xul:text class="minimonth-header" flex="1"/>
<xul:text class="minimonth-header" flex="1"/>
<xul:text class="minimonth-header" flex="1"/>
<xul:text class="minimonth-header" flex="1"/>
<xul:text class="minimonth-header" flex="1"/>
</xul:hbox>
<xul:hbox class="minimonth-row-body" equalsize="always" flex="1">
<xul:text class="minimonth-day" flex="1" />
<xul:text class="minimonth-day" flex="1" />
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
</xul:hbox>
<xul:hbox class="minimonth-row-body" equalsize="always" flex="1">
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
</xul:hbox>
<xul:hbox class="minimonth-row-body" equalsize="always" flex="1">
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
</xul:hbox>
<xul:hbox class="minimonth-row-body" equalsize="always" flex="1">
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
</xul:hbox>
<xul:hbox class="minimonth-row-body" equalsize="always" flex="1">
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
</xul:hbox>
<xul:hbox class="minimonth-row-body" equalsize="always" flex="1">
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
<xul:text class="minimonth-day" flex="1"/>
</xul:hbox>
</xul:vbox>
<xul:menupopup id="month-list" position="after_start">
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
</xul:menupopup>
<xul:menupopup id="year-list" position="after_start">
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
<xul:menuitem class="minimonth-list"/>
</xul:menupopup>
</xul:vbox>
</content>
<!-- ::::::::::::::::: INTERFACE ::::::::::::::::::::::::: -->
<implementation>
<property name="value"
onget="return this.mValue"
onset="this.update(val)"/>
<property name="onchange"/>
<property name="onmonthchange"/>
<constructor>
<![CDATA[
this.mInitialized = false;
this.mSelected = false;
this.mValue = null;
this.mMonthNames = new Array(12);
var dateStringBundle = srGetStrBundle("chrome://calendar/locale/dateFormat.properties");
for (var month = 0; month < 12; month++) {
// this.mMonthNames[0] is from "month.1.name" (January)
this.mMonthNames[month] = dateStringBundle.GetStringFromName("month."+(month+1)+".name");
}
this.refreshDisplay( );
]]>
</constructor>
<method name="refreshDisplay">
<body>
<![CDATA[
if (!this.mInitialized) {
this.mInitialized = true;
// Find out which should be the first day of the week
var pref = Components.classes[
"@mozilla.org/preferences-service;1"
].getService(Components.interfaces.nsIPrefBranch);
// this.weekStart;
try {
this.weekStart = pref.getIntPref("calendar.week.start");
} catch (e) {
this.weekStart = 0;
}
// save references for convenience
var monthbox = document.getAnonymousNodes(this)[0].childNodes[0];
this.mLeftBtn = monthbox.childNodes[0];
this.mLeftBtn.mCalendar = this;
this.mRightBtn = monthbox.childNodes[5];
this.mRightBtn.mCalendar = this;
this.mMonthCell = monthbox.childNodes[2];
this.mYearCell = monthbox.childNodes[3];
//var val = this.parentNode.parentNode.parentNode.parentNode.value;
//if (val) this.mValue = new Date(val);
//else this.mValue = new Date();
if (!this.mValue) this.mValue = new Date();
// In moz 1.7, onchange event handler attributes must be read as:
// yes: "this.onchange = function(){ eval(onChangeAttr); };"
// The following alternatives break for some expressions:
// no: "this.onchange = new Function(eval(onChangeAttr));"
// no: "this.onchange = new Function(onChangeAttr);"
// The latter two can produce unbound identifier errors
// for free variables of the onchange expression
// (variables defined outside the expression, such as globals).
var onChangeAttr = this.getAttribute("onchange");
if (onChangeAttr) this.onchange = function(){ eval(onChangeAttr); };
else this.onchange = null;
var onMonthChangeAttr = this.getAttribute("onmonthchange");
if (onMonthChangeAttr)
this.onmonthchange = function(){ eval(onMonthChangeAttr) };
else this.onmonthchange = null;
this.setHeader();
this.showMonth(this.mValue);
}
]]></body>
</method>
<method name="setHeader">
<body><![CDATA[
// need to create string bundle manually instead of
// using <xul:stringbundle/> see bug 63370 for details
var localeService = Components.classes[
"@mozilla.org/intl/nslocaleservice;1"
].getService(Components.interfaces.nsILocaleService);
var stringBundleService = Components.classes[
"@mozilla.org/intl/stringbundle;1"
].getService(Components.interfaces.nsIStringBundleService);
var bundleURL = "chrome://calendar/locale/dateFormat.properties";
var dateBundle = stringBundleService.createBundle(
bundleURL, localeService.getApplicationLocale()
);
// Reset the headers
var header = document.getAnonymousNodes(this)[0].
childNodes[1].childNodes[0]
;
for (var column = 0; column < header.childNodes.length; column++) {
header.childNodes[column].setAttribute( "value",
dateBundle.GetStringFromName(
"day."+
((this.weekStart + column) % 7 + 1) +
".short"
)
);
}
]]></body>
</method>
<method name="showMonth">
<parameter name="aDate"/>
<body><![CDATA[
if (!aDate) {
aDate = new Date();
} else {
aDate = new Date(aDate.toString());
aDate.setDate(1);
}
this.mEditorDate = aDate;
if (this.mSelected) {
this.mSelected.setAttribute("selected", "");
this.mSelected = null;
}
//-------- Update the month and year title
var mon = this.getMonthName(aDate);
this.mMonthCell.setAttribute("value", mon);
this.mYearCell.setAttribute("value", aDate.getFullYear());
//-------- Update the month popup
var i;
var months = document.getAnonymousNodes(this)[0].childNodes[2].childNodes;
for (i = 0; i < months.length; i++) {
months[i].setAttribute("label", this.mMonthNames[i]);
months[i].setAttribute("value", i);
months[i].setAttribute("current", "false");
if (i == aDate.getMonth())
months[i].setAttribute("current", "true");
}
//-------- Update the year popup
var years = document.getAnonymousNodes(this)[0].childNodes[3].childNodes;
var year = new Date(aDate.toString());
year.setFullYear(aDate.getFullYear() - (years.length%2 + 1));
for (i = 0; i < years.length; i++) {
years[i].setAttribute("label", year.getFullYear());
years[i].setAttribute("value", year.getFullYear());
years[i].setAttribute("current", "false");
if (year.getFullYear() == aDate.getFullYear())
years[i].setAttribute("current", "true");
year.setFullYear(year.getFullYear() + 1);
}
//-------- Update the calendar
var calbox = document.getAnonymousNodes(this)[0].childNodes[1];
var firstWeekday = (7 + aDate.getDay() - this.weekStart) % 7;
var date = new Date(aDate.getTime());
date.setDate(date.getDate()-firstWeekday);
for (var k = 1; k < calbox.childNodes.length; k++) {
var row = calbox.childNodes[k];
for (i = 0; i < 7; i++) {
var day = row.childNodes[i];
if (aDate.getMonth() != date.getMonth()) {
day.setAttribute("othermonth", "true");
} else {
day.setAttribute("othermonth", "");
}
// highlight the current date
var val = this.value;
if (val) {
if ((val.getFullYear() == date.getFullYear()) &&
(val.getMonth() == date.getMonth()) &&
(val.getDate() == date.getDate()))
{
this.mSelected = day;
day.setAttribute("selected", "true");
}
}
day.date = date;
day.calendar = this;
day.setAttribute("value", date.getDate());
date = new Date(date.getTime());
date.setDate(date.getDate() + 1);
}
}
]]></body>
</method>
<method name="setBusyDates">
<parameter name="arrayOfDates"/>
<body><![CDATA[
/* CODE FROM monthView.js for finding the events for the month. */
/*
document.getElementById( "lefthandcalendar" ).value = date;
//get a list of events for this month.
var monthEvents =
this.eventSource.getEventsForMonth( this.getSelectedDate() );
var arrayOfDates = new Array();
for( var eventIndex = 0; eventIndex < monthEvents.length; ++eventIndex )
{
var calendarEventDisplay = monthEvents[ eventIndex ];
var eventDate = new Date( calendarEventDisplay.displayDate );
//add them to an array
arrayOfDates[ eventDate.getDate() ] = true;
}
document.getElementById( "lefthandcalendar" ).setBusyDates( arrayOfDates );
*/
var aDate = new Date();
aDate.setDate( 1 );
//-------- Update the calendar
var calbox = document.getAnonymousNodes(this)[0].childNodes[1];
// weekStart day is set by preference
var firstWeekday = (7 + aDate.getDay() - this.weekStart) % 7;
var date = new Date(aDate.getTime());
date.setDate(date.getDate() - firstWeekday);
for (var k = 1; k < calbox.childNodes.length; k++) {
var row = calbox.childNodes[k];
for (var i = 0; i < 7; i++) {
var day = row.childNodes[i];
if (aDate.getMonth() == date.getMonth() &&
arrayOfDates[ date.getDate() ] == true ) {
day.setAttribute("busy", "true");
} else {
day.removeAttribute("busy");
}
// next date of month, may increment month
date.setDate(date.getDate() + 1);
}
}
]]></body>
</method>
<method name="advanceMonth">
<parameter name="aDir"/>
<body><![CDATA[
var ad = this.mEditorDate.getMonth() + aDir;
this.mEditorDate.setMonth(ad);
this.showMonth(this.mEditorDate);
if (this.mSelected) {
this.mSelected.removeAttribute("selected");
}
this.value = this.mEditorDate;
if (this.onmonthchange) this.onmonthchange();
]]></body>
</method>
<method name="dayClicked">
<parameter name="aDay"/>
<body><![CDATA[
if (this.mSelected) {
this.mSelected.setAttribute("selected", "");
}
this.mSelected = aDay;
aDay.setAttribute("selected", "true");
this.value = aDay.date;
if (this.onchange) this.onchange();
]]></body>
</method>
<method name="update">
<parameter name="aValue"/>
<body><![CDATA[
this.mValue = aValue;
this.showMonth(aValue);
]]></body>
</method>
<method name="getMonthName">
<parameter name="aDate"/>
<body><![CDATA[
return this.mMonthNames[aDate.getMonth()];
]]></body>
</method>
<method name="switchMonth">
<parameter name="aMonth"/>
<body><![CDATA[
this.mEditorDate.setMonth(aMonth);
this.showMonth(this.mEditorDate);
if (this.mSelected)
this.mSelected.removeAttribute("selected");
this.value = this.mEditorDate;
if (this.onmonthchange) this.onmonthchange();
]]></body>
</method>
<method name="switchYear">
<parameter name="aYear"/>
<body><![CDATA[
this.mEditorDate.setFullYear(aYear);
this.showMonth(this.mEditorDate);
if (this.mSelected)
this.mSelected.removeAttribute("selected");
this.value = this.mEditorDate;
if (this.onmonthchange) this.onmonthchange();
]]></body>
</method>
</implementation>
<!-- ::::::::::::::::: HANDLERS ::::::::::::::::::::::::: -->
<handlers>
<handler event="bindingattached" action="this.initialize();"/>
<handler event="click"><![CDATA[
var element = event.originalTarget;
if (element.parentNode.getAttribute("id") == "month-list")
this.switchMonth(element.getAttribute("value"));
if (element.parentNode.getAttribute("id") == "year-list")
this.switchYear(element.getAttribute("value"));
]]></handler>
</handlers>
</binding>
<binding id="minimonth-navbtn" inherits="dir">
<!-- ::::::::::::::::: HANDLERS ::::::::::::::::::::::::: -->
<handlers>
<handler event="click">
<![CDATA[
this.mCalendar.advanceMonth(parseInt(this.getAttribute('dir')));
]]>
</handler>
</handlers>
</binding>
<binding id="minimonth-day" extends="xul:text">
<!-- ::::::::::::::::: HANDLERS ::::::::::::::::::::::::: -->
<handlers>
<handler event="click" action="if (event.button == 0) this.calendar.dayClicked(this)"/>
</handlers>
</binding>
</bindings>