diff options
Diffstat (limited to 'toolkit/content/widgets/numberbox.xml')
-rw-r--r-- | toolkit/content/widgets/numberbox.xml | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/toolkit/content/widgets/numberbox.xml b/toolkit/content/widgets/numberbox.xml new file mode 100644 index 000000000..0e1225f09 --- /dev/null +++ b/toolkit/content/widgets/numberbox.xml @@ -0,0 +1,304 @@ +<?xml version="1.0"?> +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + + +<bindings id="numberboxBindings" + xmlns="http://www.mozilla.org/xbl" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:xbl="http://www.mozilla.org/xbl"> + + <binding id="numberbox" + extends="chrome://global/content/bindings/textbox.xml#textbox"> + + <resources> + <stylesheet src="chrome://global/skin/numberbox.css"/> + </resources> + + <content> + <xul:hbox class="textbox-input-box numberbox-input-box" flex="1" xbl:inherits="context,disabled,focused"> + <html:input class="numberbox-input textbox-input" anonid="input" + xbl:inherits="value,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/> + </xul:hbox> + <xul:spinbuttons anonid="buttons" xbl:inherits="disabled,hidden=hidespinbuttons"/> + </content> + + <implementation> + <field name="_valueEntered">false</field> + <field name="_spinButtons">null</field> + <field name="_value">0</field> + <field name="decimalSymbol">"."</field> + + <property name="spinButtons" readonly="true"> + <getter> + <![CDATA[ + if (!this._spinButtons) + this._spinButtons = document.getAnonymousElementByAttribute(this, "anonid", "buttons"); + return this._spinButtons; + ]]> + </getter> + </property> + + <property name="value" onget="return '' + this.valueNumber" + onset="return this.valueNumber = val;"/> + + <property name="valueNumber"> + <getter> + if (this._valueEntered) { + var newval = this.inputField.value; + newval = newval.replace(this.decimalSymbol, "."); + this._validateValue(newval, false); + } + return this._value; + </getter> + <setter> + this._validateValue(val, false); + return val; + </setter> + </property> + + <property name="wrapAround"> + <getter> + <![CDATA[ + return (this.getAttribute('wraparound') == 'true') + ]]> + </getter> + <setter> + <![CDATA[ + if (val) + this.setAttribute('wraparound', 'true'); + else + this.removeAttribute('wraparound'); + this._enableDisableButtons(); + return val; + ]]> + </setter> + </property> + + <property name="min"> + <getter> + var min = this.getAttribute("min"); + return min ? Number(min) : 0; + </getter> + <setter> + <![CDATA[ + if (typeof val == "number") { + this.setAttribute("min", val); + if (this.valueNumber < val) + this._validateValue(val, false); + } + return val; + ]]> + </setter> + </property> + + <property name="max"> + <getter> + var max = this.getAttribute("max"); + return max ? Number(max) : Infinity; + </getter> + <setter> + <![CDATA[ + if (typeof val != "number") + return val; + var min = this.min; + if (val < min) + val = min; + this.setAttribute("max", val); + if (this.valueNumber > val) + this._validateValue(val, false); + return val; + ]]> + </setter> + </property> + + <property name="decimalPlaces"> + <getter> + var places = this.getAttribute("decimalplaces"); + return places ? Number(places) : 0; + </getter> + <setter> + if (typeof val == "number") { + this.setAttribute("decimalplaces", val); + this._validateValue(this.valueNumber, false); + } + return val; + </setter> + </property> + + <property name="increment"> + <getter> + var increment = this.getAttribute("increment"); + return increment ? Number(increment) : 1; + </getter> + <setter> + <![CDATA[ + if (typeof val == "number") + this.setAttribute("increment", val); + return val; + ]]> + </setter> + </property> + + <method name="decrease"> + <body> + return this._validateValue(this.valueNumber - this.increment, true); + </body> + </method> + + <method name="increase"> + <body> + return this._validateValue(this.valueNumber + this.increment, true); + </body> + </method> + + <method name="_modifyUp"> + <body> + <![CDATA[ + if (this.disabled || this.readOnly) + return; + var oldval = this.valueNumber; + var newval = this.increase(); + this.inputField.select(); + if (oldval != newval) + this._fireChange(); + ]]> + </body> + </method> + <method name="_modifyDown"> + <body> + <![CDATA[ + if (this.disabled || this.readOnly) + return; + var oldval = this.valueNumber; + var newval = this.decrease(); + this.inputField.select(); + if (oldval != newval) + this._fireChange(); + ]]> + </body> + </method> + + <method name="_enableDisableButtons"> + <body> + <![CDATA[ + var buttons = this.spinButtons; + if (this.wrapAround) { + buttons.decreaseDisabled = buttons.increaseDisabled = false; + } + else if (this.disabled || this.readOnly) { + buttons.decreaseDisabled = buttons.increaseDisabled = true; + } + else { + buttons.decreaseDisabled = (this.valueNumber <= this.min); + buttons.increaseDisabled = (this.valueNumber >= this.max); + } + ]]> + </body> + </method> + + <method name="_validateValue"> + <parameter name="aValue"/> + <parameter name="aIsIncDec"/> + <body> + <![CDATA[ + aValue = Number(aValue) || 0; + + var min = this.min; + var max = this.max; + var wrapAround = this.wrapAround && + min != -Infinity && max != Infinity; + if (aValue < min) + aValue = (aIsIncDec && wrapAround ? max : min); + else if (aValue > max) + aValue = (aIsIncDec && wrapAround ? min : max); + + var places = this.decimalPlaces; + aValue = (places == Infinity) ? "" + aValue : aValue.toFixed(places); + + this._valueEntered = false; + this._value = Number(aValue); + this.inputField.value = aValue.replace(/\./, this.decimalSymbol); + + if (!wrapAround) + this._enableDisableButtons(); + + return aValue; + ]]> + </body> + </method> + + <method name="_fireChange"> + <body> + var evt = document.createEvent("Events"); + evt.initEvent("change", true, true); + this.dispatchEvent(evt); + </body> + </method> + + <constructor><![CDATA[ + if (this.max < this.min) + this.max = this.min; + + var dsymbol = (Number(5.4)).toLocaleString().match(/\D/); + if (dsymbol != null) + this.decimalSymbol = dsymbol[0]; + + var value = this.inputField.value || 0; + this._validateValue(value, false); + ]]></constructor> + + </implementation> + + <handlers> + <handler event="input" phase="capturing"> + this._valueEntered = true; + </handler> + + <handler event="keypress"> + <![CDATA[ + if (!event.ctrlKey && !event.metaKey && !event.altKey && event.charCode) { + if (event.charCode == this.decimalSymbol.charCodeAt(0) && + this.decimalPlaces && + String(this.inputField.value).indexOf(this.decimalSymbol) == -1) + return; + + if (event.charCode == 45 && this.min < 0) + return; + + if (event.charCode < 48 || event.charCode > 57) + event.preventDefault(); + } + ]]> + </handler> + + <handler event="keypress" keycode="VK_UP"> + this._modifyUp(); + </handler> + + <handler event="keypress" keycode="VK_DOWN"> + this._modifyDown(); + </handler> + + <handler event="up" preventdefault="true"> + this._modifyUp(); + </handler> + + <handler event="down" preventdefault="true"> + this._modifyDown(); + </handler> + + <handler event="change"> + if (event.originalTarget == this.inputField) { + var newval = this.inputField.value; + newval = newval.replace(this.decimalSymbol, "."); + this._validateValue(newval, false); + } + </handler> + </handlers> + + </binding> + +</bindings> |