mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 03:30:17 +01:00
1787 lines
57 KiB
XML
1787 lines
57 KiB
XML
<!-- ***** 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 Mozilla XForms support.
|
|
-
|
|
- The Initial Developer of the Original Code is
|
|
- IBM Corporation.
|
|
- Portions created by the Initial Developer are Copyright (C) 2006
|
|
- the Initial Developer. All Rights Reserved.
|
|
-
|
|
- Contributor(s):
|
|
- Doron Rosenberg <doronr@us.ibm.com>
|
|
- Alexander Surkov <surkov@dc.baikal.ru>
|
|
- Merle Sterling <msterlin@us.ibm.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 GPL or the LGPL. 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 ***** -->
|
|
|
|
<!DOCTYPE bindings [
|
|
<!ENTITY % xformsDTD SYSTEM "chrome://xforms/locale/xforms.dtd">
|
|
%xformsDTD;
|
|
]>
|
|
|
|
<bindings id="widgetsBindings"
|
|
xmlns="http://www.mozilla.org/xbl"
|
|
xmlns:xbl="http://www.mozilla.org/xbl">
|
|
|
|
|
|
<!-- CALENDAR WIDGETS -->
|
|
|
|
<!-- CALENDAR BASE
|
|
The widget assumes successor widgets have following interface:
|
|
refresh(aCurrentDay, aDaysRefreshOnly) - update UI, the method is called
|
|
when current date is changed.
|
|
@param aCurrentDay - day of current date
|
|
@param aDaysRefreshOnly - if true then day of current date will be
|
|
updated only.
|
|
focus() - set focus on the widget.
|
|
currentDay - return day of current date.
|
|
-->
|
|
<binding id="calendar-base">
|
|
<implementation implements="nsIAccessibleProvider">
|
|
<!-- nsIAccessibleProvider -->
|
|
<property name="accessibleType" readonly="true">
|
|
<getter>
|
|
return Components.interfaces.nsIAccessibleProvider.XFormsCalendarWidget;
|
|
</getter>
|
|
</property>
|
|
|
|
<!-- interface -->
|
|
<!-- Set/get readonly state -->
|
|
<property name="readonly">
|
|
<getter>
|
|
return this.hasAttribute("readonly");
|
|
</getter>
|
|
<setter>
|
|
if (val)
|
|
this.setAttribute("readonly", "readonly");
|
|
else
|
|
this.removeAttribute("readonly");
|
|
</setter>
|
|
</property>
|
|
|
|
<!-- The following interface methods serve to manage current date (the date
|
|
you see) -->
|
|
|
|
<!-- Return year of current date -->
|
|
<property name="year"
|
|
onget="return parseInt(this.getAttribute('year'));"
|
|
onset="this.setAttribute('year', val); this.refresh();"/>
|
|
|
|
<!-- Return month of current date -->
|
|
<property name="month"
|
|
onget="return parseInt(this.getAttribute('month'));"
|
|
onset="this.setDate(this.year, val);"/>
|
|
|
|
<!-- Set current date-->
|
|
<method name="setDate">
|
|
<parameter name="aYear"/>
|
|
<parameter name="aMonth"/>
|
|
<parameter name="aDay"/>
|
|
<body>
|
|
<![CDATA[
|
|
var month = parseInt(aMonth) - 1;
|
|
var deltayear = parseInt(month / 12);
|
|
if (!deltayear && month < 0)
|
|
deltayear = -1;
|
|
|
|
month %= 12;
|
|
if (month < 0)
|
|
month = (month + 12) % 12;
|
|
|
|
this.setAttribute("year", aYear + deltayear);
|
|
this.setAttribute("month", month + 1);
|
|
this.refresh(aDay);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Return current date -->
|
|
<method name="getDate">
|
|
<body>
|
|
if (this.focusedDay == -1)
|
|
return null;
|
|
return new Date(this.year, this.month - 1, this.currentDay);
|
|
</body>
|
|
</method>
|
|
|
|
<!-- The following methods serve to manage selected date -->
|
|
|
|
<!-- Return/set selected date as string of format 'yyyy-MM-dd' -->
|
|
<property name="value"
|
|
onget="return this.selectedDate ? this.selectedDate.toLocaleFormat('%Y-%m-%d') : null;"
|
|
onset="this.selectedDate = new Date(val.replace(/-/g, '/'));"/>
|
|
|
|
<!-- Return day of selected date -->
|
|
<property name="selectedDay" readonly="true"
|
|
onget="return this._selectedDate ? this._selectedDate.getDate() : null;"/>
|
|
|
|
<!-- Return month of selected date -->
|
|
<property name="selectedMonth" readonly="true"
|
|
onget="return this._selectedDate ? this._selectedDate.getMonth() + 1 : null;"/>
|
|
|
|
<!-- Return year of selected date -->
|
|
<property name="selectedYear" readonly="true"
|
|
onget="return this._selectedDate ? this._selectedDate.getFullYear() : null;"/>
|
|
|
|
<!-- Set/return selected date -->
|
|
<property name="selectedDate">
|
|
<getter>
|
|
return this._selectedDate;
|
|
</getter>
|
|
<setter>
|
|
// if passed date is empty or invalid then we use today date.
|
|
if (!val || String(val) == this.invalidDate)
|
|
val = new Date();
|
|
|
|
this._selectedDate = val;
|
|
if (!this.isSelectedDate())
|
|
this.setDate(this.selectedYear, this.selectedMonth, this.selectedDay);
|
|
else
|
|
this.refresh(this.selectedDay, true);
|
|
</setter>
|
|
</property>
|
|
|
|
<!-- Return true if year and month of current date are the same like for
|
|
selected date -->
|
|
<method name="isSelectedDate">
|
|
<body>
|
|
<![CDATA[
|
|
if (this.selectedYear == this.year && this.selectedMonth == this.month)
|
|
return true;
|
|
return false;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- interface for successor widgets -->
|
|
|
|
<!-- Return day of the week of the first day of the month -->
|
|
<property name="dayOffset" readonly="true">
|
|
<getter>
|
|
return new Date(this.year, this.month - 1, 1).getDay();
|
|
</getter>
|
|
</property>
|
|
|
|
<!-- Return days count in current month -->
|
|
<property name="daysCount" readonly="true"
|
|
onget="return this.getDaysCount(this.month, this.year);"/>
|
|
|
|
<!-- Return days count in previous month -->
|
|
<property name="prevDaysCount" readonly="true">
|
|
<getter>
|
|
<![CDATA[
|
|
var month = this.month - 1;
|
|
var year = this.year;
|
|
if (month <= 0) {
|
|
month = 12;
|
|
year--;
|
|
}
|
|
return this.getDaysCount(month, year);
|
|
]]>
|
|
</getter>
|
|
</property>
|
|
|
|
<!-- Return short names of days of the week -->
|
|
<method name="getDaysOfWeekNames">
|
|
<body>
|
|
<![CDATA[
|
|
// shortname defaults
|
|
var dayShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
|
|
// try to get localized short names.
|
|
// May 2005's first day is a Sunday - also, month is 0-indexed in JS
|
|
var day;
|
|
for (var i = 0; i < 7; i++) {
|
|
day = new Date(2005, 4, i+1).toLocaleFormat("%a");
|
|
if (day)
|
|
dayShort[i] = day;
|
|
}
|
|
return dayShort;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Fire 'change' event -->
|
|
<method name="fireChangeEvent">
|
|
<body>
|
|
var event = this.ownerDocument.createEvent("Events");
|
|
event.initEvent("change", true, false);
|
|
this.dispatchEvent(event);
|
|
</body>
|
|
</method>
|
|
|
|
<!-- private -->
|
|
<method name="getDaysCount">
|
|
<parameter name="aMonth"/>
|
|
<parameter name="aYear"/>
|
|
<body>
|
|
<![CDATA[
|
|
switch (aMonth) {
|
|
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
|
|
return 31;
|
|
|
|
case 2:
|
|
if (aYear % 4 == 0 && aYear % 100 != 0 || aYear % 400 == 0)
|
|
return 29; // leap-year
|
|
return 28;
|
|
|
|
case 4: case 6: case 9: case 11:
|
|
return 30;
|
|
}
|
|
return 0;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Selected date -->
|
|
<field name="_selectedDate">null</field>
|
|
|
|
<!-- String presentation of invalid javascript date -->
|
|
<field name="invalidDate">String(new Date(undefined))</field>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- COMPACT CALENDAR BASE
|
|
The widget is the interface binding for xhtml and xul calendars widgets.
|
|
It assumes that successor widgets have following interface:
|
|
setDayControl(aControl, aType, aLabel) - set type and label for day control
|
|
selectDayControl(aControl) - makes day control selected
|
|
unselectDayControl(aControl) - unselect day control
|
|
isDayControl(aNode) - return true if aNode is a day control
|
|
-->
|
|
<binding id="calendar-compact-base" extends="#calendar-base">
|
|
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- Set focus on day element of current date -->
|
|
<method name="focus">
|
|
<body>
|
|
if (this.currentDayIndex != -1)
|
|
this._dayElements[this.currentDayIndex].focus();
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Updates UI -->
|
|
<method name="refresh">
|
|
<parameter name="aCurrentDay"/>
|
|
<parameter name="aDaysRefreshOnly"/>
|
|
<body>
|
|
this.refreshInternal(aCurrentDay, aDaysRefreshOnly);
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Return day of current date -->
|
|
<property name="currentDay" readonly="true">
|
|
<getter>
|
|
<![CDATA[
|
|
var day = this.currentDayIndex - this.dayOffset + 1;
|
|
if (day < 0 || day > this.daysCount)
|
|
return -1;
|
|
return day;
|
|
]]>
|
|
</getter>
|
|
</property>
|
|
|
|
<!-- private -->
|
|
<method name="refreshInternal">
|
|
<parameter name="aCurrentDay"/>
|
|
<parameter name="aDaysRefreshOnly"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (!this._isUIBuilt) {
|
|
this.buildUI();
|
|
this._isUIBuilt = true;
|
|
}
|
|
|
|
if (!aDaysRefreshOnly) {
|
|
// set days for previous month
|
|
var dayOffset = this.dayOffset;
|
|
var prevDayCount = this.prevDaysCount;
|
|
for (var i = 0; i < dayOffset; i++) {
|
|
this.setDayControl(this._dayElements[i], "prevMonth",
|
|
prevDayCount + i - dayOffset + 1);
|
|
}
|
|
|
|
// set days for current month
|
|
var count = this.daysCount + dayOffset;
|
|
for (; i < count; i++) {
|
|
this.setDayControl(this._dayElements[i], "currentMonth",
|
|
i - dayOffset + 1);
|
|
}
|
|
|
|
// set days for next month
|
|
for (var day = 1; i < this._dayElements.length; i++, day++) {
|
|
this.setDayControl(this._dayElements[i], "nextMonth", day);
|
|
}
|
|
}
|
|
|
|
var selectedIndex = this.dayOffset + this.selectedDay - 1;
|
|
var currentIndex = null;
|
|
if (aCurrentDay)
|
|
currentIndex = this.dayOffset + parseInt(aCurrentDay) - 1;
|
|
else
|
|
currentIndex = this.currentDayIndex;
|
|
|
|
this.setSelectedDayByIndex(selectedIndex, currentIndex);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="setSelectedDayByIndex">
|
|
<parameter name="aSelectedIndex"/>
|
|
<parameter name="aCurrentIndex"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (!aCurrentIndex)
|
|
aCurrentIndex = aSelectedIndex;
|
|
|
|
if (this._selectedDayIndex != -1) {
|
|
this.unselectDayControl(this._dayElements[this._selectedDayIndex]);
|
|
}
|
|
|
|
if (this.isSelectedDate()) {
|
|
this.selectDayControl(this._dayElements[aSelectedIndex]);
|
|
this._selectedDayIndex = aSelectedIndex;
|
|
} else {
|
|
this._selectedDayIndex = -1;
|
|
}
|
|
|
|
this.currentDayIndex = aCurrentIndex;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<property name="currentDayIndex"
|
|
onget="return this._currentDayIndex;"
|
|
onset="this.setCurrentDayByIndex(val);"/>
|
|
|
|
<method name="setCurrentDayByIndex">
|
|
<parameter name="aIndex"/>
|
|
<body>
|
|
if (this._currentDayIndex == aIndex)
|
|
return;
|
|
|
|
var dayElm = null;
|
|
if (this._currentDayIndex != -1) {
|
|
dayElm = this._dayElements[this._currentDayIndex];
|
|
dayElm.setAttribute("tabindex", "-1");
|
|
}
|
|
|
|
dayElm = this._dayElements[aIndex];
|
|
dayElm.setAttribute("tabindex", "1");
|
|
|
|
this._currentDayIndex = aIndex;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- The method alters day of current date on aDay and if
|
|
1) action type is 'currentMonth' then it selects current date.
|
|
2) action type is 'prevMonth' then it alters month of current date on
|
|
previous month.
|
|
3) action type is 'nextMonth' then it alters month of current date on
|
|
next month.
|
|
-->
|
|
<method name="processAction">
|
|
<parameter name="aActionType"/>
|
|
<parameter name="aDay"/>
|
|
<parameter name="aSkipFocus"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (aDay != null)
|
|
aDay = parseInt(aDay);
|
|
|
|
switch (aActionType) {
|
|
case "prevMonth":
|
|
this.setDate(this.year, this.month - 1, aDay);
|
|
break;
|
|
|
|
case "nextMonth":
|
|
this.setDate(this.year, this.month + 1, aDay);
|
|
break;
|
|
|
|
case "currentMonth":
|
|
if (!this.readonly) {
|
|
this.selectedDate = new Date(this.year, this.month - 1, aDay);
|
|
this.fireChangeEvent();
|
|
} else {
|
|
if (aDay != null)
|
|
this.currentDayIndex = this.dayOffset + aDay - 1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!aSkipFocus)
|
|
this.focus();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- UI controls array for days -->
|
|
<field name="_dayElements">new Array()</field>
|
|
|
|
<!-- Index of _dayElements array item pointing on day of selected date -->
|
|
<field name="_selectedDayIndex">-1</field>
|
|
|
|
<!-- Index of _dayElements array item pointing on day of current date -->
|
|
<field name="_currentDayIndex">-1</field>
|
|
|
|
<!-- The flag pointing whether UI was builded -->
|
|
<field name="_isUIBuilt">false</field>
|
|
</implementation>
|
|
|
|
<handlers>
|
|
<handler event="keypress" keycode="VK_LEFT" phase="capturing">
|
|
<![CDATA[
|
|
if (!this.isDayControl(event.originalTarget))
|
|
return;
|
|
|
|
if (this.currentDayIndex - 1 >= 0) {
|
|
this.currentDayIndex--;
|
|
this.focus();
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="VK_RIGHT" phase="capturing">
|
|
<![CDATA[
|
|
if (!this.isDayControl(event.originalTarget))
|
|
return;
|
|
|
|
if (this.currentDayIndex + 1 < this._dayElements.length) {
|
|
this.currentDayIndex++;
|
|
this.focus();
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="VK_UP" phase="capturing">
|
|
<![CDATA[
|
|
if (!this.isDayControl(event.originalTarget))
|
|
return;
|
|
|
|
if (this.currentDayIndex - 7 >= 0) {
|
|
this.currentDayIndex -= 7;
|
|
this.focus();
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="VK_DOWN" phase="capturing">
|
|
<![CDATA[
|
|
if (!this.isDayControl(event.originalTarget))
|
|
return;
|
|
|
|
if (this.currentDayIndex + 7 < this._dayElements.length) {
|
|
this.currentDayIndex += 7;
|
|
this.focus();
|
|
}
|
|
]]>
|
|
</handler>
|
|
|
|
<handler event="keypress" keycode="VK_PAGE_UP">
|
|
this.month++;
|
|
</handler>
|
|
<handler event="keypress" keycode="VK_PAGE_DOWN">
|
|
this.month--;
|
|
</handler>
|
|
</handlers>
|
|
</binding>
|
|
|
|
<!-- RANGE
|
|
Interface for range widgets that use one or more spinbuttons/numberbox
|
|
combinations to represent a type. The widget assumes that successor
|
|
widgets have the following interface:
|
|
updateLabels() - Update range start and end labels.
|
|
updateValue() - Update the value by putting together the individual
|
|
values from each spinbutton.
|
|
updateFields() - Update the value of each individual spinbutton.
|
|
This method is called when a new value is set.
|
|
setSpinButtonMinMax() - Set the min and max attributes of the
|
|
spinbuttons.
|
|
isInRange(aValue) - Is aValue between the start and end values?
|
|
-->
|
|
<binding id="range">
|
|
<implementation>
|
|
<!-- Start label separator -->
|
|
<field name="_startSeparator">&xforms.range.start.separator.field;</field>
|
|
|
|
<!-- End label separator -->
|
|
<field name="_endSeparator">&xforms.range.end.separator.field;</field>
|
|
|
|
<!-- interface -->
|
|
<!-- Get/set lower bound of values. -->
|
|
<property name="start"
|
|
onget="return this.getAttribute('start');"
|
|
onset="this.setAttribute('start', val);"/>
|
|
|
|
<!-- Get/set upper bound of values. -->
|
|
<property name="end"
|
|
onget="return this.getAttribute('end');"
|
|
onset="this.setAttribute('end', val);"/>
|
|
|
|
<!-- Get/set step of values. -->
|
|
<property name="step"
|
|
onget="return this.getAttribute('step');"
|
|
onset="this.setAttribute('step', val);"/>
|
|
|
|
<!-- Get/set value. -->
|
|
<property name="value">
|
|
<getter>
|
|
return this.getAttribute('value');
|
|
</getter>
|
|
<setter>
|
|
<![CDATA[
|
|
var value = val;
|
|
if (!value)
|
|
value = this.start;
|
|
|
|
this.setAttribute("value", value);
|
|
this.updateFields();
|
|
this.setSpinbuttonMinMax();
|
|
this.fireValueChange();
|
|
]]>
|
|
</setter>
|
|
</property>
|
|
|
|
|
|
<!-- Set start/end/step/value -->
|
|
<method name="set">
|
|
<parameter name="aStart"/>
|
|
<parameter name="aEnd"/>
|
|
<parameter name="aStep"/>
|
|
<parameter name="aValue"/>
|
|
<body>
|
|
this.start = aStart;
|
|
this.end = aEnd;
|
|
this.step = aStep;
|
|
this.value = aValue;
|
|
|
|
this.updateLabels();
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Format a value to the given number of digits by padding with
|
|
leading zeros.
|
|
-->
|
|
<method name="formatValue">
|
|
<parameter name="aValue"/>
|
|
<parameter name="aDigits"/>
|
|
<body>
|
|
<![CDATA[
|
|
var formattedValue = aValue;
|
|
while (formattedValue.length < aDigits) {
|
|
formattedValue = "0" + formattedValue;
|
|
}
|
|
return formattedValue;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Update the text content of range widget labels.
|
|
For example, a range widget may want to have labels
|
|
for the start and end values of the range.
|
|
-->
|
|
<method name="updateLabels">
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Update the widget's value attribute by putting together the
|
|
individual spinbutton values in the correct format for the type.
|
|
-->
|
|
<method name="updateValue">
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
|
|
<!-- Parse the widget's value attribute and update the value of
|
|
of each individual spinbutton.
|
|
-->
|
|
<method name="updateFields">
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Set the min and max attributes for the spinbuttons.
|
|
If any one of the spinbuttons/numberboxes changes value,
|
|
the valid min and max for one or more of the others may
|
|
have to change too.
|
|
|
|
Example: In a dateTime range, if the current date is 2007-02-28
|
|
and the year is changed to 2008 (a leap year), the max day for
|
|
the month of February will change from 28 to 29. Likewise, if
|
|
the current date were 2007-03-31 and the month is changed to 04,
|
|
the max day will have to change from 31 to 30.
|
|
-->
|
|
<method name="setSpinbuttonMinMax">
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Is aValue between the start and end values? -->
|
|
<method name="isInRange">
|
|
<parameter name="aValue"/>
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Increment value -->
|
|
<method name="increment">
|
|
<body>
|
|
this.updateSpinbuttons();
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Decrement value -->
|
|
<method name="decrement">
|
|
<body>
|
|
this.updateSpinbuttons();
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Update the spinbutton min and max attributes and the range
|
|
value when an increment or decrement event occurs.
|
|
-->
|
|
<method name="updateSpinbuttons">
|
|
<body>
|
|
this.setSpinbuttonMinMax();
|
|
this.updateValue();
|
|
this.fireValueChange();
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Fire the 'ValueChange' event.
|
|
Range widgets must fire their own change event because the act of
|
|
incrementing/decrementing one spinbutton may change one or more
|
|
of the others at the same time as SetSpinbuttonMinMax will change
|
|
the min and max attributes on the fly.
|
|
|
|
The range widget updates its value on each 'change' event from the
|
|
spinbuttons and then fires ValueChange after they have all been
|
|
updated so that the range binding can update the instance data.
|
|
-->
|
|
<method name="fireValueChange">
|
|
<body>
|
|
var event = this.ownerDocument.createEvent("Events");
|
|
event.initEvent("ValueChange", true, false);
|
|
this.dispatchEvent(event);
|
|
</body>
|
|
</method>
|
|
|
|
<constructor>
|
|
// Spinup events are generated by the numberbox widget
|
|
// defined in "widgets-xul.xml".
|
|
var upHandler = {
|
|
range: this,
|
|
handleEvent: function(aEvent) {
|
|
this.range.increment();
|
|
}
|
|
};
|
|
// Spindown events are generated by the numberbox widgets
|
|
// defined in "widgets-xul.xml".
|
|
var downHandler = {
|
|
range: this,
|
|
handleEvent: function(aEvent) {
|
|
this.range.decrement();
|
|
}
|
|
};
|
|
// Change events are generated by the numberbox widget
|
|
// defined in "widgets-xul.xml".
|
|
var changeHandler = {
|
|
range: this,
|
|
handleEvent: function(aEvent) {
|
|
this.range.updateValue();
|
|
}
|
|
};
|
|
this.addEventListener("spinup", upHandler, false);
|
|
this.addEventListener("spindown", downHandler, false);
|
|
this.addEventListener("change", changeHandler, false);
|
|
</constructor>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- DATETIME -->
|
|
<binding id="datetime" extends="#range">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- dateTime format: yyyy-mm-ddThh:mm:ss[.s+] -->
|
|
|
|
<!-- Extract the year from a date or dateTime -->
|
|
<method name="getYear">
|
|
<parameter name="aDate"/>
|
|
<body>
|
|
return parseFloat(aDate.substr(0,4));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the month from a date or dateTime -->
|
|
<method name="getMonth">
|
|
<parameter name="aDate"/>
|
|
<body>
|
|
return parseFloat(aDate.substr(5,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the day from a date or dateTime -->
|
|
<method name="getDay">
|
|
<parameter name="aDate"/>
|
|
<body>
|
|
return parseFloat(aDate.substr(8,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the hours from a dateTime -->
|
|
<method name="getHours">
|
|
<parameter name="aDateTime"/>
|
|
<body>
|
|
return parseFloat(aDateTime.substr(11,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the minutes from a dateTime -->
|
|
<method name="getMinutes">
|
|
<parameter name="aDateTime"/>
|
|
<body>
|
|
return parseFloat(aDateTime.substr(14,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the seconds from a dateTime -->
|
|
<method name="getSeconds">
|
|
<parameter name="aDateTime"/>
|
|
<body>
|
|
return parseFloat(aDateTime.substr(17,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Year value. -->
|
|
<method name="getYearMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the year spinbutton will always
|
|
// be the year of the start date.
|
|
return this.getYear(this.start);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Year value. -->
|
|
<method name="getYearMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the year spinbutton will always
|
|
// be the year of the end date.
|
|
return this.getYear(this.end);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Month value. -->
|
|
<method name="getMonthMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the month spinbutton depends on the year
|
|
// range and the current value of the year.
|
|
var startYear = this.getYear(this.start);
|
|
var endYear = this.getYear(this.end);
|
|
var currentYear = this.getYear(this.value);
|
|
var minMonth = 0;
|
|
|
|
if (startYear == endYear || currentYear == startYear) {
|
|
// Min month is the month of the start date.
|
|
minMonth = this.getMonth(this.start);
|
|
} else {
|
|
// Current year falls between the start and end dates so
|
|
// the minimum month is the first month of the year.
|
|
minMonth = 1;
|
|
}
|
|
return minMonth;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Month value. -->
|
|
<method name="getMonthMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the month spinbutton depends on the year
|
|
// range and the current value of the year.
|
|
var startYear = this.getYear(this.start);
|
|
var endYear = this.getYear(this.end);
|
|
var currentYear = this.getYear(this.value);
|
|
var maxMonth = 0;
|
|
|
|
if (startYear == endYear || currentYear == endYear) {
|
|
// Max month is the month of the end date.
|
|
maxMonth = this.getMonth(this.end);
|
|
} else {
|
|
// Current year falls between the start and end dates so
|
|
// the maximum month is the last month of the year.
|
|
maxMonth = 12;
|
|
}
|
|
return maxMonth;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Day value. -->
|
|
<method name="getDayMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the day spinbutton depends on the current
|
|
// month and year but may also be constrained by the day of the
|
|
// start date.
|
|
var startYear = this.getYear(this.start);
|
|
var endYear = this.getYear(this.end);
|
|
var currentYear = this.getYear(this.value);
|
|
var startMonth = this.getMonth(this.start);
|
|
var endMonth = this.getMonth(this.end);
|
|
var currentMonth = this.getMonth(this.value);
|
|
var minDay = 0;
|
|
|
|
if (startYear == endYear) {
|
|
if (startMonth == endMonth || currentMonth == startMonth) {
|
|
// Start and end month are the same month of the same year or
|
|
// the current month is the start month. Min day is the day of
|
|
// the start date.
|
|
minDay = this.getDay(this.start);
|
|
} else {
|
|
// Current month is between the start and end months.
|
|
// Min day is the first day of the month.
|
|
minDay = 1;
|
|
}
|
|
} else {
|
|
// Start and End year span 1 or more years.
|
|
if (currentYear == startYear) {
|
|
if (currentMonth == startMonth) {
|
|
// Current month is the start month of the start year.
|
|
// Min day is the day of the start date.
|
|
minDay = this.getDay(this.start);
|
|
} else {
|
|
// Current month is between the start month and the last
|
|
// month of the current year.
|
|
// Min day is the first day of the month.
|
|
minDay = 1;
|
|
}
|
|
} else {
|
|
// Current year is between the start and end years.
|
|
// Min day is the first day of the month.
|
|
minDay = 1;
|
|
}
|
|
}
|
|
return minDay;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Day value. -->
|
|
<method name="getDayMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the day spinbutton depends on the current
|
|
// month and year but may also be constrained by the day of the
|
|
// end date.
|
|
var startYear = this.getYear(this.start);
|
|
var endYear = this.getYear(this.end);
|
|
var currentYear = this.getYear(this.value);
|
|
var startMonth = this.getMonth(this.start);
|
|
var endMonth = this.getMonth(this.end);
|
|
var currentMonth = this.getMonth(this.value);
|
|
var currentDay = this.getDay(this.value);
|
|
var daysCount = this.getDaysCount(currentMonth, currentYear);
|
|
var maxDay = 0;
|
|
|
|
if (startYear == endYear) {
|
|
if (startMonth == endMonth || currentMonth == endMonth) {
|
|
// Start and end month are the same month of the same year or
|
|
// the current month is the end month. Max day is the day of
|
|
// the end month.
|
|
maxDay = this.getDay(this.end);
|
|
} else {
|
|
// Current month is between the start and end months.
|
|
// Max day is the number of days in the month.
|
|
maxDay = daysCount;
|
|
}
|
|
} else {
|
|
// Start and End year span 1 or more years.
|
|
if (currentYear == endYear) {
|
|
if (currentMonth == endMonth) {
|
|
// Current month is the end month of the end year.
|
|
// Max day is the day of the end month;
|
|
maxDay = this.getDay(this.end);
|
|
} else {
|
|
// Current month falls between the first month of the
|
|
// current (end) year and the month of the end date.
|
|
// May day is the number of days in the month.
|
|
maxDay = daysCount;
|
|
}
|
|
} else {
|
|
// Current year is between the start and end years.
|
|
// Max day is the number of days in the month.
|
|
maxDay = daysCount;
|
|
}
|
|
}
|
|
return maxDay;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Hours value. -->
|
|
<method name="getHoursMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the hours spinbutton will always be the
|
|
// hours of the start time.
|
|
return this.getHours(this.start);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Hours value. -->
|
|
<method name="getHoursMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the hours spinbutton will always be the
|
|
// hours of the end time.
|
|
return this.getHours(this.end);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Minutes value. -->
|
|
<method name="getMinutesMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the minutes spinbutton depends on the hours
|
|
// range and the current value of the hours.
|
|
var startHours = this.getHours(this.start);
|
|
var endHours = this.getHours(this.end);
|
|
var currentHours = this.getHours(this.value);
|
|
var startMinutes = this.getMinutes(this.start);
|
|
var minMinutes = 0;
|
|
|
|
if (startHours == endHours || currentHours == startHours) {
|
|
// Min minutes is the minutes of the start time.
|
|
minMinutes = startMinutes;
|
|
|
|
} else {
|
|
// Current hours falls between the start and end hours.
|
|
// Min minutes is the first minute of the hour.
|
|
minMinutes = 0;
|
|
}
|
|
return minMinutes;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Minutes value. -->
|
|
<method name="getMinutesMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the minutes spinbutton depends on the hours
|
|
// range and the current value of the hours.
|
|
var startHours = this.getHours(this.start);
|
|
var endHours = this.getHours(this.end);
|
|
var currentHours = this.getHours(this.value);
|
|
var endMinutes = this.getMinutes(this.end);
|
|
var maxMinutes = 0;
|
|
|
|
if (startHours == endHours || currentHours == endHours) {
|
|
// Max minutes is the minutes of the end time.
|
|
maxMinutes = endMinutes;
|
|
|
|
} else {
|
|
// Current hours falls between start hours and end hours.
|
|
// Max minutes is the last minute of the hour.
|
|
maxMinutes = 59;
|
|
}
|
|
return maxMinutes;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Seconds value. -->
|
|
<method name="getSecondsMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the seconds spinbutton depends on the current
|
|
// hours and minutes but may also be constrained by the seconds of
|
|
// the start time.
|
|
var startHours = this.getHours(this.start);
|
|
var endHours = this.getHours(this.end);
|
|
var currentHours = this.getHours(this.value);
|
|
var startMinutes = this.getMinutes(this.start);
|
|
var endMinutes = this.getMinutes(this.end);
|
|
var currentMinutes = this.getMinutes(this.value);
|
|
var startSeconds = this.getSeconds(this.start);
|
|
var minSeconds = 0;
|
|
|
|
if (startHours == endHours || currentHours == startHours) {
|
|
// The minimum seconds value depends on the current minutes.
|
|
if (startMinutes == endMinutes || currentMinutes == startMinutes) {
|
|
// Min seconds is the seconds of the start time.
|
|
minSeconds = startSeconds;
|
|
} else {
|
|
// Current minutes falls between the start and end minutes of
|
|
// the start hours. Min seconds is the first second of a minute.
|
|
minSeconds = 0;
|
|
}
|
|
} else {
|
|
// Current hours falls between the start and end hours.
|
|
// The range of minutes will vary from a minimum of 0 to
|
|
// a maximum of 59 and so will the seconds.
|
|
minSeconds = 0;
|
|
}
|
|
return minSeconds;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Seconds value. -->
|
|
<method name="getSecondsMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the seconds spinbutton depends on the current
|
|
// hours and minutes but may also be constrained by the seconds of
|
|
// the end time.
|
|
var startHours = this.getHours(this.start);
|
|
var endHours = this.getHours(this.end);
|
|
var currentHours = this.getHours(this.value);
|
|
var startMinutes = this.getMinutes(this.start);
|
|
var endMinutes = this.getMinutes(this.end);
|
|
var currentMinutes = this.getMinutes(this.value);
|
|
var endSeconds = this.getSeconds(this.end);
|
|
var maxSeconds = 0;
|
|
|
|
if (startHours == endHours || currentHours == endHours) {
|
|
// The maximum seconds value depends on the current minutes.
|
|
if (startMinutes == endMinutes || currentMinutes == endMinutes) {
|
|
// Max seconds is the seconds of the end time.
|
|
maxSeconds = endSeconds;
|
|
} else {
|
|
// Current minutes falls between the start and end minutes of
|
|
// the end hour. Max seconds is the last second of a minute.
|
|
maxSeconds = 59;
|
|
}
|
|
} else {
|
|
// Current hours falls between the start and end hours.
|
|
// The range of minutes will vary from a minimum of 0 to
|
|
// a maximum of 59 and so will the seconds.
|
|
maxSeconds = 59;
|
|
}
|
|
return maxSeconds;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the number of days in the month for a given year. -->
|
|
<method name="getDaysCount">
|
|
<parameter name="aMonth"/>
|
|
<parameter name="aYear"/>
|
|
<body>
|
|
<![CDATA[
|
|
switch (aMonth) {
|
|
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
|
|
return 31;
|
|
|
|
case 2:
|
|
if (aYear % 4 == 0 && aYear % 100 != 0 || aYear % 400 == 0)
|
|
return 29; // leap-year
|
|
return 28;
|
|
|
|
case 4: case 6: case 9: case 11:
|
|
return 30;
|
|
}
|
|
return 0;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get a Javacript Date object initialized to the value of aDateTime.
|
|
-->
|
|
<method name="getDate">
|
|
<parameter name="aDateTime"/>
|
|
<body>
|
|
var date = new Date();
|
|
date.setFullYear(this.getYear(aDateTime));
|
|
date.setMonth(this.getMonth(aDateTime));
|
|
date.setDate(this.getDay(aDateTime));
|
|
date.setHours(this.getHours(aDateTime));
|
|
date.setMinutes(this.getMinutes(aDateTime));
|
|
date.setSeconds(this.getSeconds(aDateTime));
|
|
return date;
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- DATE -->
|
|
<binding id="date" extends="#datetime">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- date format: yyyy-mm-dd -->
|
|
|
|
<!-- Get a Javacript Date object initialized to the value of aDate.
|
|
-->
|
|
<method name="getDate">
|
|
<parameter name="aDate"/>
|
|
<body>
|
|
var date = new Date();
|
|
date.setFullYear(this.getYear(aDate));
|
|
date.setMonth(this.getMonth(aDate));
|
|
date.setDate(this.getDay(aDate));
|
|
return date;
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- TIME -->
|
|
<binding id="time" extends="#datetime">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- Time format: hh:mm:ss[.s+] -->
|
|
|
|
<!-- Extract the hours from a time -->
|
|
<method name="getHours">
|
|
<parameter name="aTime"/>
|
|
<body>
|
|
return parseFloat(aTime.substr(0,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the minutes from a time -->
|
|
<method name="getMinutes">
|
|
<parameter name="aTime"/>
|
|
<body>
|
|
return parseFloat(aTime.substr(3,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the seconds from a time -->
|
|
<method name="getSeconds">
|
|
<parameter name="aTime"/>
|
|
<body>
|
|
return parseFloat(aTime.substr(6,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get a Javacript Date object initialized to the value of aTime.
|
|
A JS Date object also accepts a time and we can use a Date
|
|
initialized with a Time to compare times.
|
|
-->
|
|
<method name="getDate">
|
|
<parameter name="aTime"/>
|
|
<body>
|
|
var date = new Date();
|
|
date.setHours(this.getHours(aTime));
|
|
date.setMinutes(this.getMinutes(aTime));
|
|
date.setSeconds(this.getSeconds(aTime));
|
|
return date;
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- GREGORIAN
|
|
This widget is the base interface for ranges that support gregorian
|
|
calendar types: gDay, gMonth, gMonthDay, gYear, and gYearMonth.
|
|
-->
|
|
<binding id="gregorian" extends="#range">
|
|
<implementation>
|
|
<method name="getDaysCount">
|
|
<parameter name="aMonth"/>
|
|
<body>
|
|
<![CDATA[
|
|
switch (aMonth) {
|
|
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
|
|
return 31;
|
|
|
|
case 2:
|
|
return 28;
|
|
|
|
case 4: case 6: case 9: case 11:
|
|
return 30;
|
|
}
|
|
return 0;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- GMONTHDAY -->
|
|
<binding id="gmonthday" extends="#gregorian">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- gMonthDay format: mm-dd -->
|
|
|
|
<!-- Extract the month from a gMonthDay -->
|
|
<method name="getMonth">
|
|
<parameter name="aMonthDay"/>
|
|
<body>
|
|
return parseFloat(aMonthDay.substr(0,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the day from a gMonthDay -->
|
|
<method name="getDay">
|
|
<parameter name="aMonthDay"/>
|
|
<body>
|
|
return parseFloat(aMonthDay.substr(3,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Month value. -->
|
|
<method name="getMonthMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the month spinbutton will always be
|
|
// the month of the start gMonthDay.
|
|
return this.getMonth(this.start);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Month value. -->
|
|
<method name="getMonthMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the month spinbutton will always be
|
|
// the month of the end gMonthDay.
|
|
return this.getMonth(this.end);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Day value. -->
|
|
<method name="getDayMin">
|
|
<body>
|
|
<![CDATA[
|
|
var startMonth = this.getMonth(this.start);
|
|
var endMonth = this.getMonth(this.end);
|
|
var currentMonth = this.getMonth(this.value);
|
|
var minDay = 0;
|
|
|
|
if (startMonth == endMonth || currentMonth == startMonth) {
|
|
// Min day is the day of the start gMonthDay.
|
|
minDay = this.getDay(this.start);
|
|
} else {
|
|
// Current month falls between the start and end month.
|
|
// Min day is the first day of the month.
|
|
minDay = 1;
|
|
}
|
|
return minDay;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Day value. -->
|
|
<method name="getDayMax">
|
|
<body>
|
|
<![CDATA[
|
|
var startMonth = this.getMonth(this.start);
|
|
var endMonth = this.getMonth(this.end);
|
|
var currentMonth = this.getMonth(this.value);
|
|
var maxDay = 0;
|
|
|
|
if (startMonth == endMonth || currentMonth == endMonth) {
|
|
// Max day is the day of the end gMonthDay.
|
|
maxDay = this.getDay(this.end);
|
|
} else {
|
|
// Current month falls between the start and end month.
|
|
// Max day is the number of days in the month.
|
|
maxDay = this.getDaysCount(currentMonth);
|
|
}
|
|
return maxDay;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get a Javacript Date object initialized to the value of aMonthDay.
|
|
JS Date objects can be used to compare gMonthDays.
|
|
-->
|
|
<method name="getDate">
|
|
<parameter name="aMonthDay"/>
|
|
<body>
|
|
<![CDATA[
|
|
var date = new Date();
|
|
// A gMonthDay type does not have a year. Any year is acceptable.
|
|
date.setFullYear(2007);
|
|
date.setMonth(this.getMonth(aMonthDay));
|
|
date.setDate(this.getDay(aMonthDay));
|
|
return date;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- GYEARMONTH -->
|
|
<binding id="gyearmonth" extends="#gregorian">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- gYearMonth format: yyyy-mm -->
|
|
|
|
<!-- Extract the year from a gYearMonth -->
|
|
<method name="getYear">
|
|
<parameter name="aYearMonth"/>
|
|
<body>
|
|
return parseFloat(aYearMonth.substr(0,4));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the month from a gYearMonth -->
|
|
<method name="getMonth">
|
|
<parameter name="aYearMonth"/>
|
|
<body>
|
|
return parseFloat(aYearMonth.substr(5,2));
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Year value. -->
|
|
<method name="getYearMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the year spinbutton will always be
|
|
// the year of the start gYearMonth.
|
|
return this.getYear(this.start);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Year value. -->
|
|
<method name="getYearMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the year spinbutton will always be
|
|
// the year of the end gYearMonth.
|
|
return this.getYear(this.end);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum Month value. -->
|
|
<method name="getMonthMin">
|
|
<body>
|
|
<![CDATA[
|
|
var startYear = this.getYear(this.start);
|
|
var endYear = this.getYear(this.end);
|
|
var currentYear = this.getYear(this.value);
|
|
var minMonth = 0;
|
|
|
|
if (startYear == endYear || currentYear == endYear) {
|
|
// Min month is the month of the start gYearMonth.
|
|
minMonth = this.getMonth(this.start);
|
|
} else {
|
|
// Current year falls between the start and end year.
|
|
// Min month is the first month of the year.
|
|
minMonth = 1;
|
|
}
|
|
return minMonth;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum Month value. -->
|
|
<method name="getMonthMax">
|
|
<body>
|
|
<![CDATA[
|
|
var startYear = this.getYear(this.start);
|
|
var endYear = this.getYear(this.end);
|
|
var currentYear = this.getYear(this.value);
|
|
var maxMonth = 0;
|
|
|
|
if (startYear == endYear || currentYear == endYear) {
|
|
// Max month is the month of the end gYearMonth.
|
|
maxMonth = this.getMonth(this.end);
|
|
} else {
|
|
// Current year falls between the start and end year.
|
|
// Max month is the last month of the year.
|
|
maxMonth = 12;
|
|
}
|
|
return maxMonth;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get a Javacript Date object initialized to the value of aYearMonth.
|
|
JS Date objects can be used to compare gYearMonths.
|
|
-->
|
|
<method name="getDate">
|
|
<parameter name="aYearMonth"/>
|
|
<body>
|
|
<![CDATA[
|
|
var date = new Date();
|
|
date.setFullYear(this.getYear(aYearMonth));
|
|
date.setMonth(this.getMonth(aYearMonth));
|
|
// A gYearMonth type does not have a day. Any day is acceptable.
|
|
date.setDate(1);
|
|
return date;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- DURATION -->
|
|
<binding id="duration" extends="#range">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- Duration format: PnYnMnDTnHnMnS
|
|
dayTimeDuration: PnDnTHnMnS (days, hours, minutes, seconds).
|
|
yearMonthDuration: PnYnM (years and months)
|
|
|
|
- The designator 'P' must always be present.
|
|
- The designator 'T' must be absent if and only if all of the
|
|
time items are absent.
|
|
- If the number of years, months, days, hours, minutes or seconds
|
|
equals zero, the number and its corresponding designator may be
|
|
omitted.
|
|
- There are no restrictions on the number of digits in 'n'.
|
|
-->
|
|
|
|
<!-- Set start/end/step/value -->
|
|
<method name="set">
|
|
<parameter name="aStart"/>
|
|
<parameter name="aEnd"/>
|
|
<parameter name="aStep"/>
|
|
<parameter name="aValue"/>
|
|
<body>
|
|
this.start = this.formatDuration(aStart);
|
|
this.end = this.formatDuration(aEnd);
|
|
this.step = aStep;
|
|
if (!aValue)
|
|
this.value = this.start;
|
|
else
|
|
this.value = this.formatDuration(aValue);
|
|
|
|
this.updateLabels();
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Format a duration value to the proper format. -->
|
|
<method name="formatDuration">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the years from a duration -->
|
|
<method name="getYears">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
return this.getDurationValue(aDuration, "Y");
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the months from a duration -->
|
|
<method name="getMonths">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
return this.getDurationValue(aDuration, "M");
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the days from a duration -->
|
|
<method name="getDays">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
return this.getDurationValue(aDuration, "D");
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the hours from a duration -->
|
|
<method name="getHours">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
return this.getDurationValue(aDuration, "H");
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the minutes from a duration -->
|
|
<method name="getMinutes">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
<![CDATA[
|
|
// Minutes is represented by the designator 'M', but so is
|
|
// Months, so first extract the time portion of the duration.
|
|
var indexT = aDuration.indexOf("T");
|
|
var time = aDuration.substring(indexT);
|
|
return this.getDurationValue(time, "M");
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Extract the seconds from a duration -->
|
|
<method name="getSeconds">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
return this.getDurationValue(aDuration, "S");
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the value of a given duration designator.
|
|
The value precedes the designator and may be any length.
|
|
-->
|
|
<method name="getDurationValue">
|
|
<parameter name="aDuration"/>
|
|
<parameter name="aDesignator"/>
|
|
<body>
|
|
<![CDATA[
|
|
var duration = 0;
|
|
// Find the designator.
|
|
var index = aDuration.indexOf(aDesignator);
|
|
if (index != -1) {
|
|
// Find the starting index of the value by searching
|
|
// backwards until we encounter another designator.
|
|
var i = index - 1;
|
|
while (!this.isDesignator(aDuration.charCodeAt(i)))
|
|
--i;
|
|
|
|
// The value is between the two designators.
|
|
duration = parseFloat(aDuration.substring(i + 1, index));
|
|
}
|
|
|
|
return duration;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Is the character one of the duration designators?
|
|
-->
|
|
<method name="isDesignator">
|
|
<parameter name="aCharCode"/>
|
|
<body>
|
|
<![CDATA[
|
|
// Char codes: 'P' == 80
|
|
// 'Y' == 89
|
|
// 'M' == 77
|
|
// 'D' == 68
|
|
// 'T' == 84
|
|
// 'H' == 72
|
|
// 'S' == 83
|
|
var isdesignator = false;
|
|
|
|
if (aCharCode == 80 || aCharCode == 89 ||
|
|
aCharCode == 77 || aCharCode == 68 ||
|
|
aCharCode == 84 || aCharCode == 72 ||
|
|
aCharCode == 83)
|
|
isdesignator = true;
|
|
|
|
return isdesignator;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- YEARMONTHDURATION -->
|
|
<binding id="yearmonthduration" extends="#duration">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- yearMonthDuration format: PnYnM (years and months) -->
|
|
|
|
<!-- Format a yearMonthDuration to the format PnYnM so that we
|
|
have a non-zero number of years and the months range between
|
|
0 - 11.
|
|
|
|
If aDuration is null, this method will return a yearMonthDuration
|
|
of zero years and zero months (P0Y0M).
|
|
-->
|
|
<method name="formatDuration">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
<![CDATA[
|
|
var years = this.getYears(aDuration);
|
|
var months = this.getMonths(aDuration);
|
|
|
|
years = years + Math.floor(months / 12);
|
|
months = months % 12;
|
|
|
|
return "P" + years + "Y" + months + "M";
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the total number of months in a yearMonthDuration. -->
|
|
<method name="getDurationMonths">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
<![CDATA[
|
|
var years = this.getYears(aDuration);
|
|
var months = this.getMonths(aDuration);
|
|
var durationMonths = (years * 12) + months;
|
|
|
|
return durationMonths;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum years value. -->
|
|
<method name="getYearsMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the years spinbutton will always
|
|
// be the year of the start duration.
|
|
return this.getYears(this.start);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum years value. -->
|
|
<method name="getYearsMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the years spinbutton will always
|
|
// be the year of the end duration.
|
|
return this.getYears(this.end);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the minimum months value. -->
|
|
<method name="getMonthsMin">
|
|
<body>
|
|
<![CDATA[
|
|
// The min value for the month spinbutton depends on the year
|
|
// range and the current value of the year.
|
|
var minMonth = 0;
|
|
|
|
var startYear = this.getYears(this.start);
|
|
var endYear = this.getYears(this.end);
|
|
var currentYear = this.getYears(this.value);
|
|
|
|
if (startYear == endYear || currentYear == startYear) {
|
|
// Min month is the month of the start duration.
|
|
minMonth = this.getMonths(this.start);
|
|
} else {
|
|
// Current year falls between the start and end year.
|
|
minMonth = 0;
|
|
}
|
|
return minMonth;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the maximum months value. -->
|
|
<method name="getMonthsMax">
|
|
<body>
|
|
<![CDATA[
|
|
// The max value for the month spinbutton depends on the year
|
|
// range and the current value of the year.
|
|
var maxMonth = 0;
|
|
|
|
var startYear = this.getYears(this.start);
|
|
var endYear = this.getYears(this.end);
|
|
var currentYear = this.getYears(this.value);
|
|
|
|
if (startYear == endYear || currentYear == endYear) {
|
|
// Max month is the month of the end duration.
|
|
maxMonth = this.getMonths(this.end);
|
|
} else {
|
|
// Current year falls between the start and end year.
|
|
maxMonth = 11;
|
|
}
|
|
|
|
return maxMonth;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- DAYTIMEDURATION -->
|
|
<binding id="daytimeduration" extends="#duration">
|
|
<implementation>
|
|
<!-- interface -->
|
|
<!-- dayTimeDuration format: PnDTnHnMnS (days, hours, minutes, seconds). -->
|
|
|
|
<!-- Format a dayTimeDuration to the format PnDTnHnMnS so that we have a
|
|
whole number of days, hours are between 0 - 23, minutes are between
|
|
0 - 59, and seconds are between 0 - 59.
|
|
|
|
If aDuration is null, this method will return a dayTimeDuration of
|
|
zero days, zero hours, zero minutes, and zero seconds (P0DT0H0M0S).
|
|
-->
|
|
<method name="formatDuration">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
<![CDATA[
|
|
var days = this.getDays(aDuration);
|
|
var hours = this.getHours(aDuration);
|
|
var minutes = this.getMinutes(aDuration);
|
|
var seconds = this.getSeconds(aDuration);
|
|
|
|
// If the seconds value exceeds 60, allocate the number of
|
|
// minutes in the seconds to the minutes value.
|
|
minutes = minutes + Math.floor(seconds / 60);
|
|
seconds = seconds % 60;
|
|
|
|
// If the minutes value now exceeds 60, allocate the number of
|
|
// hours in the minutes to the hours value.
|
|
hours = hours + Math.floor(minutes / 60);
|
|
minutes = minutes % 60;
|
|
|
|
// If the hours value now exceeds 23, allocate the number of
|
|
// days in the hours to the days value.
|
|
days = days + Math.floor(hours / 24);
|
|
hours = hours % 24;
|
|
|
|
return "P" + days + "DT" + hours + "H" + minutes + "M" + seconds + "S";
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Get the total number of seconds in a dayTimeDuration -->
|
|
<method name="getDurationSeconds">
|
|
<parameter name="aDuration"/>
|
|
<body>
|
|
<![CDATA[
|
|
var days = this.getDays(aDuration);
|
|
var hours = this.getHours(aDuration);
|
|
var minutes = this.getMinutes(aDuration);
|
|
var seconds = this.getSeconds(aDuration);
|
|
|
|
var durationSeconds = (days * 86400) +
|
|
(hours * 3600) +
|
|
(minutes * 60) +
|
|
seconds;
|
|
|
|
return durationSeconds;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
</bindings>
|