[XForms] Expose abstract interface for input[type="date"]. Bug 327584, r=doronr+me, patch by surkov@dc.baikal.ru

This commit is contained in:
allan%beaufour.dk 2006-04-12 07:57:55 +00:00
Родитель b3f53c5fe8
Коммит e6f59b1289
5 изменённых файлов: 324 добавлений и 647 удалений

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

@ -28,4 +28,5 @@ xforms.jar:
locale/en-US/xforms/xforms.properties (resources/locale/en-US/xforms.properties)
locale/en-US/xforms/xforms.dtd (resources/locale/en-US/xforms.dtd)
* skin/xforms/contents.rdf (resources/skin/contents.rdf)
skin/xforms/widgets-xhtml.css (resources/skin/widgets-xhtml.css)

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

@ -184,6 +184,310 @@
</binding>
<!-- INPUT: DATE -->
<binding id="xformswidget-input-date"
extends="chrome://xforms/content/input.xml#xformswidget-input-base">
<content>
<children includes="label"/>
<html:input anonid="control" xbl:inherits="accesskey" size="10"
class="xf-value"/>
<html:input type="button" anonid="dropmarker"
title="&xforms.datepicker.title;"/>
<html:span mozType:calendar="true" anonid="picker"
style="position:absolute; display:none;"/>
<children/>
</content>
<implementation>
<method name="getControlElement">
<body>
return {
__proto__: this.inputField,
pickerButton: this.dropmarker,
set readonly(val) {
if (val) {
this.setAttribute('disabled', 'disabled');
this.pickerButton.setAttribute('disabled', 'disabled');
} else {
this.removeAttribute('disabled');
this.pickerButton.removeAttribute('disabled');
}
}
};
</body>
</method>
<!-- Show date picker when it is hidden and hide when it is shown. -->
<method name="togglePicker">
<body>
if (this._isPickerVisible)
this.hidePicker(true);
else
this.showPicker();
</body>
</method>
<!-- Show date picker -->
<method name="showPicker">
<body>
<![CDATA[
if (this._isPickerVisible || this.accessors.isReadonly()) {
return;
}
// show the picker
this.picker.style.display = "block";
this._isPickerVisible = true;
// refresh the picker
this.picker.value = this.inputField.value;
// move the picker, aligning it's right side with the calendar
// button's right side
var dropmarkerBox = this.ownerDocument.
getBoxObjectFor(this.dropmarker);
var pickerWidth = this.ownerDocument.
getBoxObjectFor(this.picker).width;
// we use window.innerWidth because XHTML documents are not always
// 100% width, and innerWidth will always give use the browser size
var windowWidth = this.ownerDocument.defaultView.innerWidth;
var position = dropmarkerBox.x - pickerWidth + dropmarkerBox.width;
// reset position if it will bleed to the left or right
if (position < 0) {
position = 0;
} else if ((position + pickerWidth) > windowWidth) {
position = windowWidth - pickerWidth;
}
this.picker.style.left = position + "px";
this.picker.focus();
this.ownerDocument.
addEventListener("blur", this.hidePickerHandler, true);
this.ownerDocument.
addEventListener("focus", this.hidePickerHandler, true);
]]>
</body>
</method>
<!-- Hide date picker -->
<method name="hidePicker">
<parameter name="aFocusInput"/>
<body>
<![CDATA[
if (!this._isPickerVisible)
return;
this.ownerDocument.
removeEventListener("blur", this.hidePickerHandler, true);
this.ownerDocument.
removeEventListener("focus", this.hidePickerHandler, true);
this.picker.style.display = "none";
this._isPickerVisible = false;
if (aFocusInput)
this.inputField.focus();
]]>
</body>
</method>
<!--
'hidePickerHandler' object serves to hide date picker when date
picker looses a focus. When date picker is shown then
'hidePickerHandler' object is attached to the window to handle 'focus'
and 'blur' events as event listener. When date picker is hidden then
event listener 'hidePickerHandler' is removed.
-->
<property name="hidePickerHandler" readonly="true">
<getter>
<![CDATA[
if (!this._hidePickerHandler) {
this._hidePickerHandler = {
inputElm: this,
dropmarkerElm: this.dropmarker,
pickerContent: this.ownerDocument.getAnonymousNodes(this.picker)[0],
inputContentNodes: this.ownerDocument.getAnonymousNodes(this),
ownerDocument: this.ownerDocument,
shouldHandleFocus: false,
handleEvent: function(aEvent) {
var target = aEvent.originalTarget;
switch (aEvent.type) {
case "blur":
if (this.ownerDocument == target) {
this.inputElm.hidePicker();
} else {
this.shouldHandleFocus =
this.isPickerNode(target) || this.isInputNode(target);
}
break;
case "focus":
if (this.shouldHandleFocus && target != this.dropmarkerElm &&
!this.isPickerNode(target)) {
this.inputElm.hidePicker();
}
break;
}
},
// Return true if aNode is a child of anonymous content of date
// picker.
isPickerNode: function(aNode) {
var walker = this.ownerDocument.createTreeWalker(
this.pickerContent, NodeFilter.SHOW_ELEMENT, null, false);
var child = null;
while (child = walker.nextNode()) {
if (child == aNode)
return true;
}
return false;
},
// Return true if aNode is a child of anonymous content of input.
isInputNode: function(aNode) {
for (var i = 0; i < this.inputContentNodes.length; i++) {
if (this.inputContentNodes[i] == aNode)
return true;
}
return false;
}
};
}
return this._hidePickerHandler;
]]>
</getter>
</property>
<field name="_hidePickerHandler">null</field>
<constructor>
// Add event handlers to update instance data when date picker value is
// changed.
// Add event handler on 'change' event.
var changePickerValueHandlerOnChange = {
inputElm: this,
handleEvent: function(event) {
this.inputElm.inputField.value = this.inputElm.picker.value;
this.inputElm.hidePicker(true);
this.inputElm.updateInstanceData(true);
}
};
this.picker.addEventListener("change", changePickerValueHandlerOnChange,
false);
// Add event handler on 'enter' key pressing.
var changePickerValueHandlerOnKeypress = {
inputElm: this,
pickerElm: this.picker,
handleEvent: function(event) {
if (event.keyCode != event.DOM_VK_RETURN ||
!this.pickerElm.isDayControl(event.originalTarget))
return;
var date = this.pickerElm.getDate();
if (date) {
this.inputElm.inputField.value = date.toLocaleFormat('%Y-%m-%d');
this.inputElm.hidePicker(true);
this.inputElm.updateInstanceData(true);
}
}
};
this.picker.addEventListener("keypress",
changePickerValueHandlerOnKeypress, false);
</constructor>
<!-- Input field control -->
<property name="inputField" readonly="true">
<getter>
if (!this._inputField) {
this._inputField =
document.getAnonymousElementByAttribute(this, "anonid", "control");
}
return this._inputField;
</getter>
</property>
<field name="_inputField">null</field>
<!-- Date picker control -->
<property name="picker" readonly="true">
<getter>
if (!this._picker) {
this._picker =
document.getAnonymousElementByAttribute(this, "anonid", "picker");
}
return this._picker;
</getter>
</property>
<field name="_picker">null</field>
<!-- Dropmarker control used to open/hide date picker -->
<property name="dropmarker" readonly="true">
<getter>
if (!this._dropmarker) {
this._dropmarker =
document.getAnonymousElementByAttribute(this, "anonid", "dropmarker");
}
return this._dropmarker;
</getter>
</property>
<field name="_dropmarker">null</field>
<field name="_isPickerVisible">false</field>
</implementation>
<handlers>
<handler event="keypress" keycode="VK_ESCAPE">
this.hidePicker();
</handler>
<handler event="keypress" keycode="VK_RETURN">
var target = event.originalTarget;
if (target == this.inputField) {
this.dispatchDOMUIEvent('DOMActivate');
}
</handler>
<handler event="keypress">
<![CDATA[
if (event.keyCode == event.DOM_VK_F4 ||
event.altKey && (event.keyCode == event.DOM_VK_DOWN ||
event.keyCode == event.DOM_VK_UP)) {
this.togglePicker();
}
]]>
</handler>
<handler event="input">
this.updateInstanceData(true);
</handler>
<handler event="click">
if (event.originalTarget == this.dropmarker) {
this.togglePicker();
}
</handler>
<handler event="focus" phase="capturing">
if (event.originalTarget == this.inputField) {
this.dispatchDOMUIEvent('DOMFocusIn');
}
</handler>
<handler event="blur" phase="capturing">
if (event.originalTarget == this.inputField) {
this.updateInstanceData(false);
this.dispatchDOMUIEvent('DOMFocusOut');
}
</handler>
</handlers>
</binding>
<!-- INPUT: <DATE, APPEARANCE='FULL' -->
<binding id="xformswidget-input-date-full"
extends="chrome://xforms/content/input.xml#xformswidget-input-base">

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

@ -46,11 +46,6 @@
-->
<!DOCTYPE bindings [
<!ENTITY % xformsDTD SYSTEM "chrome://xforms/locale/xforms.dtd">
%xformsDTD;
]>
<bindings id="xformsInputBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml"
@ -160,576 +155,6 @@
</binding>
<!-- INPUT: DATE
XXX: The widget doesn't support interface based on getElementControl()
method (see a bug https://bugzilla.mozilla.org/show_bug.cgi?id=323845).
-->
<binding id="xformswidget-input-date"
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
<content>
<children includes="label"/>
<html:input anonid="control"
onblur="this.parentNode.accessors.setValue(this.value); this.parentNode.dispatchDOMUIEvent('DOMFocusOut');"
onfocus="this.parentNode.dispatchDOMUIEvent('DOMFocusIn'); this.parentNode._hidePicker(true);"
onclick="this.parentNode._change(); this.parentNode._hidePicker(true);"
onkeypress="if (event.keyCode == event.DOM_VK_RETURN) this.parentNode.dispatchDOMUIEvent('DOMActivate');"
xbl:inherits="accesskey" size="10"
class="xf-value"/>
<html:input type="button" anonid="dropmarker" title="&xforms.datepicker.title;"
onkeypress="if (event.keyCode == event.DOM_VK_ENTER) this.parentNode._togglePicker();"
onclick="this.parentNode._togglePicker();"/>
<html:div style="position:absolute; display:none;" anonid="picker">
<html:table>
<html:tbody anonid="tbody">
<html:tr>
<html:td colspan="1">
<html:input type="button" anonid="back-button"
class="-moz-date-back-button" title="&xforms.datepicker.prevMonth.title;"
onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.goBack(true);"/>
</html:td>
<html:td colspan="5" align="center">
<html:span anonid="date"/>
</html:td>
<html:td colspan="1">
<html:input type="button" anonid="fwd-button"
class="-moz-date-fwd-button" title="&xforms.datepicker.nextMonth.title;"
onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.goForward(true);"/>
</html:td>
</html:tr>
</html:tbody>
</html:table>
</html:div>
<children/>
</content>
<implementation>
<method name="refresh">
<body>
this.inputField.value = this.stringValue;
if (this.accessors.isReadonly()) {
this.inputField.setAttribute("readonly", "readonly");
this.dropmarker.setAttribute("disabled", "true");
} else {
this.inputField.removeAttribute("readonly");
this.dropmarker.removeAttribute("disabled");
}
return true;
</body>
</method>
<method name="_change">
<body>
if (this.getAttribute("incremental") == "true") {
this.accessors.setValue(this.inputField.value);
}
return true;
</body>
</method>
<field name="_inputField">null</field>
<property name="inputField" readonly="true">
<getter>
if (!this._inputField) {
this._inputField =
document.getAnonymousElementByAttribute(this, "anonid", "control");
}
return this._inputField;
</getter>
</property>
<field name="_picker">null</field>
<property name="picker" readonly="true">
<getter>
if (!this._picker) {
this._picker =
document.getAnonymousElementByAttribute(this, "anonid", "picker");
}
return this._picker;
</getter>
</property>
<field name="_dropmarker">null</field>
<property name="dropmarker" readonly="true">
<getter>
if (!this._dropmarker) {
this._dropmarker =
document.getAnonymousElementByAttribute(this, "anonid", "dropmarker");
}
return this._dropmarker;
</getter>
</property>
<field name="_dateField">null</field>
<property name="dateField" readonly="true">
<getter>
if (!this._dateField) {
this._dateField =
document.getAnonymousElementByAttribute(this, "anonid", "date");
}
return this._dateField;
</getter>
</property>
<field name="_uibuilt">false</field>
<field name="_isPickerVisible">false</field>
<field name="_cells">null</field>
<field name="_date">null</field>
<field name="_currentCellIndex">-1</field>
<method name="_togglePicker">
<body>
<![CDATA[
if (this._isPickerVisible)
this._hidePicker(true);
else
this._showPicker();
]]>
</body>
</method>
<method name="_showPicker">
<body>
<![CDATA[
if (this._isPickerVisible || this.accessors.isReadonly()) {
return;
}
// show the picker
var picker = this.picker;
picker.style.display = "block";
this._isPickerVisible = true;
var value = this.inputField.value;
// js date likes YYYY/MM/DD, schema's is YYYY-MM-DD
value = value.replace(/-/g, "/");
// we check if the delgate is valid since javascript Date()
// returns a valid date for 2005-04-56.
var tmpDate = new Date(value);
if (!this.accessors.isValid() || tmpDate == "Invalid Date")
this._date = new Date();
else
this._date = tmpDate;
if (!this._uibuilt)
this._buildUI(this._date);
// position the dropdown, aligning it's right side with the calendar
// button's right side
var dropmarker = document.getAnonymousElementByAttribute(this, "anonid", "dropmarker");
var dropmarkerBox = document.getBoxObjectFor(dropmarker);
var width = document.getBoxObjectFor(picker).width;
var position = dropmarkerBox.x - width + dropmarkerBox.width;
// reset position if it will bleed to the left or right
if (position < 0) {
position = 0;
} else if ((position + width) > window.innerWidth) {
// we use window.innerWidth because XHTML documents are not always
// 100% width, and innerWidth will always give use the browser size.
position = window.innerWidth - width;
}
picker.style.left = position + "px";
this._refreshCells(this._date, this._date.getDate());
]]>
</body>
</method>
<method name="_hidePicker">
<parameter name="aFocusInput"/>
<body>
<![CDATA[
if (!this._isPickerVisible)
return;
this._cells[this._currentCellIndex].node.setAttribute("tabindex", "-1");
this._currentCellIndex = -1;
this.picker.style.display = "none";
this._isPickerVisible = false;
if (aFocusInput)
this.inputField.focus();
]]>
</body>
</method>
<method name="_buildUI">
<parameter name="aDate"/>
<body>
<![CDATA[
var xhtmlNS = "http://www.w3.org/1999/xhtml";
// 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;
}
var month = aDate.getMonth();
var year = aDate.getFullYear();
// clear the cells array
this._cells = new Array();
var table = document.getAnonymousElementByAttribute(this, "anonid", "tbody");
var row, cell, header, caption;
// create the table headers
row = document.createElementNS(xhtmlNS, "tr");
for (var i = 0; i < 7; i++) {
header = document.createElementNS(xhtmlNS, "th");
// day shorthands
header.textContent = dayShort[i];
row.appendChild(header);
}
table.appendChild(row);
// create a table of 7 columns, 6 rows
for (var i = 0; i < 6; i++) {
row = document.createElementNS(xhtmlNS, "tr");
for (var y = 0; y < 7; y++) {
cell = document.createElementNS(xhtmlNS, "td");
cell.setAttribute("num", this._cells.length);
this._cells[this._cells.length] = {row:i, col:y, node: cell};
row.appendChild(cell);
}
table.appendChild(row);
}
this._uibuilt = true;
]]>
</body>
</method>
<method name="_refreshCells">
<parameter name="aDate"/>
<parameter name="aDayToSelect"/>
<parameter name="aSkipFocus"/>
<body>
<![CDATA[
var month = aDate.getMonth();
var year = aDate.getFullYear();
var totaldays = this._getDaysInMonth(month, year);
// first day of month is?
var firstDay = new Date(year, month, 1).getDay();
// get the previous month's date so we can prefill that section. The
// next month is easy, we go from 1..x as far as we need
var prevDate = this._getPrevDate(month, year);
var showsPrevDays = 0;
// init cells
for (var i = 0; i < this._cells.length; i++) {
if (i < firstDay || i >= (firstDay + totaldays)) {
// either previous or next month
if (i < firstDay) {
// previous month
var prevyear = prevDate.getFullYear();
var prevmonth = prevDate.getMonth();
var maxprev = this._getDaysInMonth(prevmonth, prevyear);
this._cells[i].node.textContent = maxprev - firstDay + i + 1;
this._cells[i].node.className = "prevMonth";
showsPrevDays++;
} else {
// next month
this._cells[i].node.textContent = i - (firstDay + totaldays) + 1;
this._cells[i].node.className = "nextMonth";
}
} else {
// current month
// this._cells add one since the first day is 1, not 0!
this._cells[i].node.textContent = i - firstDay + 1;
this._cells[i].node.className = "currentMonth";
}
this._cells[i].node.setAttribute("tabindex", "-1");
}
// first time
if (this._currentCellIndex == -1) {
// select the current day
this._currentCellIndex = aDate.getDate() + showsPrevDays - 1;
} else {
// if the day is larger that the total days in this month
if (aDayToSelect > totaldays)
aDayToSelect = totaldays;
this._currentCellIndex = aDayToSelect + showsPrevDays - 1;
}
this._cells[this._currentCellIndex].node.setAttribute("tabindex", "0");
if (!aSkipFocus)
this._cells[this._currentCellIndex].node.focus();
// update the month year heading
this.dateField.textContent = this._date.toLocaleFormat("%B %Y");
]]>
</body>
</method>
<method name="_getPrevDate">
<parameter name="aMonth"/>
<parameter name="aYear"/>
<body>
var month, year = aYear;
if (aMonth == 0) {
month = 11;
year--;
} else {
month = aMonth - 1;
}
return new Date(year, month);
</body>
</method>
<method name="_getNextDate">
<parameter name="aMonth"/>
<parameter name="aYear"/>
<body>
var month, year = aYear;
if (aMonth == 11) {
month = 0;
year++;
} else {
month = aMonth + 1;
}
return new Date(year, month);
</body>
</method>
<method name="_getDaysInMonth">
<parameter name="aMonth"/>
<parameter name="aYear"/>
<body>
<![CDATA[
var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// check for leap year
if ((aYear % 4 == 0 && aYear % 100 != 0) || aYear % 400 == 0)
days[1] = 29;
return days[aMonth];
]]>
</body>
</method>
<method name="goBack">
<parameter name="aCalledFromButton"/>
<body>
<![CDATA[
var day = parseInt(this._cells[this._currentCellIndex].node.textContent);
this._date = this._getPrevDate(this._date.getMonth(), this._date.getFullYear());
this._refreshCells(this._date, day, aCalledFromButton);
]]>
</body>
</method>
<method name="goForward">
<parameter name="aCalledFromButton"/>
<body>
<![CDATA[
var day = parseInt(this._cells[this._currentCellIndex].node.textContent);
this._date = this._getNextDate(this._date.getMonth(), this._date.getFullYear());
this._refreshCells(this._date, day, aCalledFromButton);
]]>
</body>
</method>
<method name="selectCell">
<parameter name="aCellNum"/>
<body>
<![CDATA[
if (aCellNum == this._currentCellIndex) {
// make sure it is focused. We keep the currentCellIndex even if we
// switch to the prev/next buttons, so we just need to refocus the
// cell.
this._cells[this._currentCellIndex].node.focus();
} else {
this._cells[this._currentCellIndex].node.setAttribute("tabindex", "-1");
this._currentCellIndex = aCellNum;
this._cells[this._currentCellIndex].node.setAttribute("tabindex", "0");
this._cells[this._currentCellIndex].node.focus();
}
]]>
</body>
</method>
<method name="_valueSet">
<body>
<![CDATA[
// called when a cell is choosen (enter or mouse click)
var value = this._cells[this._currentCellIndex].node.textContent;
var date = new Date(this._date.getFullYear(), this._date.getMonth(),
parseInt(value));
this.inputField.value = date.toLocaleFormat("%Y-%m-%d");
// check if we should update the instance data
this._change();
this._hidePicker(true);
]]>
</body>
</method>
</implementation>
<handlers>
<handler event="keypress">
<![CDATA[
// first we handle events that will always toggle the picker dropdown -
// F4 and alt-down/up
if (event.keyCode == event.DOM_VK_F4 ||
event.altKey && (event.keyCode == event.DOM_VK_DOWN ||
event.keyCode == event.DOM_VK_UP)) {
// first set the accessor value, since the input's value hasn't
// been validated yet, and forcing this will.
this.accessors.setValue(this.inputField.value);
this._togglePicker();
} else if (this._isPickerVisible) {
// handle events if the picker dropdown is visible - we always
// hide the picker if focus returns to the input
var index = this._currentCellIndex;
var currentElement = event.originalTarget;
if (event.keyCode == event.DOM_VK_DOWN) {
if (currentElement.localName == "input") {
// if we are on the button, down should focus the current selected
// cell
this.selectCell(index);
} else if ((index + 7) < this._cells.length) {
this.selectCell(index + 7);
}
} else if (event.keyCode == event.DOM_VK_UP) {
// td means we are on a cell
if (currentElement.localName == "td" && (index - 7) >= 0) {
this.selectCell(index - 7);
} else {
// focus the back button
document.getAnonymousElementByAttribute(this, "anonid", "back-button").focus();
}
} else if (event.keyCode == event.DOM_VK_LEFT) {
// ctrl-left goes back a month
if (event.ctrlKey) {
this.goBack();
} else if (currentElement.localName == "input") {
// input means we are on one of the back/fwd buttons
document.getAnonymousElementByAttribute(this, "anonid", "back-button").focus();
} else if ((index - 1) >= 0) {
this.selectCell(index - 1);
}
} else if (event.keyCode == event.DOM_VK_RIGHT) {
// ctrl-right goes forward a month
if (event.ctrlKey) {
this.goForward();
} else if (currentElement.localName == "input") {
// input means we are on one of the back/fwd buttons
document.getAnonymousElementByAttribute(this, "anonid", "fwd-button").focus();
} else if ((index + 1) < this._cells.length) {
this.selectCell(index + 1);
}
} else if (event.keyCode == event.DOM_VK_RETURN &&
event.originalTarget.localName == "td") {
var type = event.originalTarget.className;
if (type == "currentMonth") {
this.selectCell(event.originalTarget.getAttribute("num"));
this._valueSet();
} else if (type == "prevMonth") {
this.goBack();
} else if (type == "nextMonth") {
this.goForward();
}
} else if (event.keyCode == event.DOM_VK_ESCAPE) {
this._hidePicker(true);
}
} else {
// pressing down if the picker is hidden will show it
if (event.keyCode == event.DOM_VK_DOWN) {
// first set the accessor value, since the input's value hasn't
// been validated yet, and forcing this will.
this.accessors.setValue(this.inputField.value);
this._showPicker();
} else {
// check if something changed
this._change();
}
}
]]>
</handler>
<handler event="keyup">
<![CDATA[
if (!this._isPickerVisible) {
// check if something changed
this._change();
}
]]>
</handler>
<handler event="mousedown">
<![CDATA[
if (event.originalTarget.localName == "td") {
var type = event.originalTarget.className;
var cell = parseInt(event.originalTarget.getAttribute("num"));
if (type == "currentMonth") {
this.selectCell(cell);
this._valueSet();
} else if (type == "prevMonth") {
this._currentCellIndex = cell;
this.goBack();
} else if (type == "nextMonth") {
this._currentCellIndex = cell;
this.goForward();
}
}
]]>
</handler>
<handler event="xforms-next">
<![CDATA[
this._hidePicker(false);
]]>
</handler>
<handler event="xforms-previous">
<![CDATA[
this._hidePicker(false);
]]>
</handler>
</handlers>
</binding>
<!-- INPUT: Month
The input[type="xsd:gMonth"] widget assumes successors bindings implement
getElementControl() method what returns the object:

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

@ -54,6 +54,10 @@
<binding id="calendar-compact"
extends="chrome://xforms/content/widgets.xml#calendar-base">
<resources>
<stylesheet src="chrome://xforms/skin/widgets-xhtml.css"/>
</resources>
<content>
<html:table>
<html:tbody anonid="dayContainer"/>

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

@ -140,6 +140,8 @@ range {
}
/* input widgets */
/* input */
html|*:root input {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input');
}
@ -148,6 +150,7 @@ xul|*:root input {
-moz-binding: url('chrome://xforms/content/input-xul.xml#xformswidget-input');
}
/* input type="xsd:boolean" */
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#boolean"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-boolean');
}
@ -156,19 +159,16 @@ xul|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#boolean"] {
-moz-binding: url('chrome://xforms/content/input-xul.xml#xformswidget-input-boolean');
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] {
-moz-binding: url('chrome://xforms/content/input.xml#xformswidget-input-date');
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"][appearance="full"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-date-full');
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"][appearance="full"]
html|span[mozType|calendar] {
/* input type="xsd:date" */
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|span[mozType|calendar] {
-moz-binding: url('chrome://xforms/content/widgets-xhtml.xml#calendar-full');
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|input[anonid="dropmarker"] {
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-date');
}
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|input[anonid="dropmarker"] {
min-width:27px;
min-height: 1.3em;
background-image: url(chrome://xforms/content/calendar.png) !important;
@ -176,78 +176,21 @@ input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|input[anonid="d
background-repeat: no-repeat !important;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|div[anonid="picker"],
html|span[mozType|calendar] html|table {
border: 1px outset black !important;
background-color: -moz-Field;
font: -moz-list;
text-align: start;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td,
html|span[mozType|calendar] html|td {
border: 1px solid transparent;
text-align: center;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td.prevMonth,
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td.nextMonth,
html|span[mozType|calendar] html|td.prevMonth,
html|span[mozType|calendar] html|td.nextMonth {
color: GrayText;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td.prevMonth:hover,
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td.nextMonth:hover,
html|span[mozType|calendar] html|td.prevMonth:hover,
html|span[mozType|calendar] html|td.nextMonth:hover {
background-color: grey;
cursor: pointer;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td.currentMonth,
html|span[mozType|calendar] html|td.currentMonth {
color: black;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|td.currentMonth:hover,
html|span[mozType|calendar] html|td.currentMonth:hover{
color: HighlightText;
background-color: Highlight;
cursor: pointer;
}
input[mozType|type="http://www.w3.org/2001/XMLSchema#date"] html|div[anonid="picker"] html|td[tabindex="0"],
html|span[mozType|calendar] html|td[selected] {
border: 1px solid black;
}
html|input.-moz-date-back-button {
width: 20px;
background-image: url("chrome://global/skin/arrow/arrow-lft.gif") !important;
background-repeat: no-repeat !important;
background-position: center !important;
}
html|input.-moz-date-fwd-button {
width: 20px;
background-image: url("chrome://global/skin/arrow/arrow-rit.gif") !important;
background-repeat: no-repeat !important;
background-position: center !important;
/* input type="xsd:date", appearance="full" */
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#date"][appearance="full"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-date-full');
}
/* input type="xsd:gMonth" */
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#gMonth"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-month');
}
/* input type="xsd:gDay" */
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#gDay"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-day');
}
html|*:root input[mozType|type="http://www.w3.org/2001/XMLSchema#gYear"] {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-input-year');
}
/* secret widgets */
html|*:root secret {
-moz-binding: url('chrome://xforms/content/input-xhtml.xml#xformswidget-secret');