mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-11 02:10:17 +01:00
331 lines
12 KiB
XML
331 lines
12 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
<!-- ***** 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
|
|
- Novell, Inc.
|
|
- Portions created by the Initial Developer are Copyright (C) 2005
|
|
- the Initial Developer. All Rights Reserved.
|
|
-
|
|
- Contributor(s):
|
|
- Allan Beaufour <abeaufour@novell.com>
|
|
- Alexander Surkov <surkov.alexander@gmail.com>
|
|
- 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 ***** -->
|
|
|
|
<bindings xmlns="http://www.mozilla.org/xbl"
|
|
xmlns:html="http://www.w3.org/1999/xhtml">
|
|
|
|
<!-- RANGE: BASE
|
|
This binding is base for xforms range controls. It assumes successors
|
|
bindings implement getElementControl() method that returns the object:
|
|
{
|
|
get/set value(); // get/set value
|
|
set readonly(); // makes range disabled
|
|
get/set start(); // get/set @start attribute
|
|
get/set end(); // get/set @end attribute
|
|
get/set step(); // get/set @step attribute
|
|
focus() // set the focus
|
|
set(); // set start, end, step, value
|
|
}
|
|
|
|
Successor bindings should override isInRange and adjustRangeValues to do
|
|
what is appropriate for the particular datatype they use.
|
|
-->
|
|
<binding id="xformswidget-range-base"
|
|
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
|
|
|
|
<implementation>
|
|
<method name="refresh">
|
|
<body>
|
|
<![CDATA[
|
|
// The start/end/step attrs are all optional and if any are omitted
|
|
// we need to adjust their values.
|
|
if (!this.adjustRangeValues(this.start, this.end, this.step))
|
|
return;
|
|
|
|
this.changed = false;
|
|
|
|
this.control.readonly = this.accessors.isReadonly();
|
|
|
|
var value = this.accessors.getValue();
|
|
var inrange = this.isInRange(value);
|
|
this.accessors.setInRange(inrange);
|
|
|
|
this.control.set(this.start, this.end, this.step, value);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- Determine whether or not the current value is between the start
|
|
and end values for the range so we can dispatch xforms-in-range
|
|
or xforms-out-of-range events.
|
|
-->
|
|
<method name="isInRange">
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<!-- The start/end/step attrs are all optional and if any are omitted
|
|
we need to adjust their values.
|
|
-->
|
|
<method name="adjustRangeValues">
|
|
<body>
|
|
return true;
|
|
</body>
|
|
</method>
|
|
|
|
<method name="focus">
|
|
<body>
|
|
this.control.focus();
|
|
</body>
|
|
</method>
|
|
|
|
|
|
<property name="start"
|
|
onget="return this.control.start;"
|
|
onset="this.setAttribute('start', val); this.control.start = val;"/>
|
|
|
|
<property name="end"
|
|
onget="return this.control.end;"
|
|
onset="this.setAttribute('end', val); this.control.end = val;"/>
|
|
|
|
<property name="step"
|
|
onget="return this.control.step;"
|
|
onset="this.setAttribute('step', val); this.control.step = val;"/>
|
|
|
|
<property name="incremental">
|
|
<getter>
|
|
return this.getAttribute("incremental") == "true";
|
|
</getter>
|
|
<setter>
|
|
if (val)
|
|
this.setAttribute("incremental", "true");
|
|
else
|
|
this.removeAttribute("incremental");
|
|
</setter>
|
|
</property>
|
|
|
|
<property name="accessors" readonly="true">
|
|
<getter>
|
|
<![CDATA[
|
|
if (!this._accessors && this.delegate) {
|
|
this._accessors = this.delegate.getXFormsAccessors().
|
|
QueryInterface(Components.interfaces.nsIXFormsRangeAccessors);
|
|
}
|
|
return this._accessors;
|
|
]]>
|
|
</getter>
|
|
</property>
|
|
|
|
<method name="getCurrentValue">
|
|
<body>
|
|
return this.control.value;
|
|
</body>
|
|
</method>
|
|
|
|
<!--
|
|
updateInstanceData updates the instance data bound to this control
|
|
under certain conditions.
|
|
|
|
If aIncremental is false, it means that this function was called due
|
|
to a blur event on the control. In this case, we should update the
|
|
instance data only if the control is NOT incremental and the user has
|
|
interacted with the control since the last refresh.
|
|
|
|
If aIncremental is true, it means that this function was called because
|
|
the user interacted with the control (either through mouse or keyboard
|
|
action) and we set a flag to indicate this fact. If the control is
|
|
incremental, we update the value of the bound instance data.
|
|
-->
|
|
<method name="updateInstanceData">
|
|
<parameter name="aIncremental"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (!this.accessors.hasBoundNode())
|
|
return;
|
|
|
|
if (aIncremental) {
|
|
this.changed = true;
|
|
if (!this.incremental)
|
|
return;
|
|
} else {
|
|
if (!this.changed)
|
|
return;
|
|
}
|
|
|
|
this.accessors.setValue(this.control.value);
|
|
this.changed = false;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!--
|
|
We need to remember if the user has interacted with this control.
|
|
We don't want to change the value of the node that this control is
|
|
bound to unless the user caused the change.
|
|
-->
|
|
<field name="changed">false</field>
|
|
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- RANGE: <NUMBER>
|
|
This binding is base for xforms range controls with numeric types.
|
|
Successor bindings should implement a getElementControl() method
|
|
that returns numeric types.
|
|
-->
|
|
<binding id="xformswidget-range-numeric-base"
|
|
extends="chrome://xforms/content/range.xml#xformswidget-range-base">
|
|
|
|
<implementation implements="nsIAccessibleProvider">
|
|
<!-- Any range type that uses a slider widget as the element control
|
|
should return Components.interfaces.nsIAccessibleProvider.XFormsRange
|
|
as its accessible type.
|
|
-->
|
|
<property name="accessibleType" readonly="true">
|
|
<getter>
|
|
return Components.interfaces.nsIAccessibleProvider.XFormsSliderRange;
|
|
</getter>
|
|
</property>
|
|
|
|
<method name="getCurrentValue">
|
|
<body>
|
|
var value = this.control.value;
|
|
return isNaN(value) ? "" : value;
|
|
</body>
|
|
</method>
|
|
|
|
<method name="isInRange">
|
|
<parameter name="aValue"/>
|
|
<body>
|
|
<![CDATA[
|
|
var value = parseFloat(aValue);
|
|
if (isNaN(value))
|
|
return false;
|
|
return value >= this.start && value <= this.end;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- A range control with numeric types is currently implemented as a
|
|
slider and a slider with a large number of steps does not look
|
|
nice or perform very well; therefore, we limit the maximum number
|
|
of steps to a reasonable value of 20. The start/end/step values
|
|
will be adjusted accordingly if any are omitted.
|
|
-->
|
|
<method name="adjustRangeValues">
|
|
<parameter name="aStart"/>
|
|
<parameter name="aEnd"/>
|
|
<parameter name="aStep"/>
|
|
<body>
|
|
<![CDATA[
|
|
// Start > End is an error.
|
|
if (!isNaN(aStart) && !isNaN(aEnd)) {
|
|
if (aStart > aEnd) {
|
|
this.delegate.reportError("rangeBeginEndError");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (isNaN(aStep)) {
|
|
// Step is not specified and will depend on the values of start
|
|
// and end (which also may not be specified).
|
|
if (isNaN(aStart) && isNaN(aEnd)) {
|
|
// None of the range attributes are specified! Show a default
|
|
// slider with 20 steps.
|
|
this.start = 0;
|
|
this.end = 20;
|
|
this.step = 1;
|
|
} else if (!isNaN(aStart) && isNaN(aEnd)) {
|
|
// Start is specified but End is not. Set end to start + 20 with
|
|
// a default step of 1 to maintain our maximum range of 20 steps.
|
|
this.start = aStart;
|
|
this.end = this.start + 20;
|
|
this.step = 1;
|
|
} else if (isNaN(aStart) && !isNaN(aEnd)) {
|
|
// End is specified but Start is not. Use a default step of 1
|
|
// and adjust start to maintain the maximum range of 20 steps.
|
|
this.start = aEnd - 20;
|
|
this.end = aEnd;
|
|
this.step = 1;
|
|
} else {
|
|
// Both Start and End are specified. Calculate a step value
|
|
// that will maintain our maximum range of 20 steps.
|
|
this.start = aStart;
|
|
this.end = aEnd;
|
|
this.step = Math.round((aEnd - aStart) / 20);
|
|
}
|
|
} else {
|
|
// Step is specified. Adjust start and end to maintain our
|
|
// maximum range of 20 steps.
|
|
if (isNaN(aStart) && isNaN(aEnd)) {
|
|
// Neither Start nor End is specified. Calculate values for start
|
|
// and end such that the slider has a maximum of 20 steps of size
|
|
// aStep.
|
|
this.start = 0;
|
|
this.end = this.start + (aStep * 20);
|
|
this.step = aStep;
|
|
} else if (!isNaN(aStart) && isNaN(aEnd)) {
|
|
// Begin is specified but End is not. Adjust end such that we
|
|
// have 20 steps of size aStep between start and end.
|
|
this.start = aStart;
|
|
this.end = this.start + (aStep * 20);
|
|
this.step = aStep;
|
|
} else if (isNaN(aStart) && !isNaN(aEnd)) {
|
|
// End is specified but Start is not. Adjust start such that we
|
|
// have 20 steps of size aStep between start and end.
|
|
this.start = aEnd - (aStep * 20);
|
|
this.end = aEnd;
|
|
this.step = aStep;
|
|
} else {
|
|
// Both Start and End are specified, but the specified Step
|
|
// value may not be suitable for maintaining the maximum
|
|
// range of 20 steps.
|
|
if ((aEnd - aStart) / aStep > 20) {
|
|
// Honor the specified start and end values, but adjust
|
|
// the Step value.
|
|
this.step = Math.round((aEnd - aStart) / 20);
|
|
} else {
|
|
this.step = aStep;
|
|
}
|
|
this.start = aStart;
|
|
this.end = aEnd;
|
|
}
|
|
}
|
|
return true;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
</bindings>
|