XForms/计算器
外观
< XForms
计算器是网络应用程序的经典示例之一。
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<!-- Licensed by the w3c.org under the GPL2 -->
<title>Calculator Sample</title>
<xf:model>
<xf:instance>
<equation xmlns="">
<display>0</display>
<displaybuffer>0</displaybuffer>
<first>0</first>
<second>0</second>
<memory>0</memory>
<result />
</equation>
</xf:instance>
</xf:model>
<style type="text/css">
table {
border: thin outset;
}
td {
border: thin inset;
}
.display {
text-align: right;
}
</style>
</head>
<body>
<p>A simple calculator</p>
<table>
<tr>
<td colspan="6" class="display">
<xf:output ref="/equation/display" />
</td>
</tr>
<tr>
<td>
<xf:output ref="/equation/memory">
<xf:label>M:</xf:label>
</xf:output>
</td>
<td />
<td />
<td />
<td colspan="2">
<xf:trigger>
<xf:label>Clear</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/first" value="0" />
<xf:setvalue ref="/equation/second" value="0" />
<xf:setvalue ref="/equation/result" value="0" />
<xf:setvalue ref="/equation/display" value="0" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
<xf:toggle case="add" />
</xf:action>
</xf:trigger>
</td>
</tr>
<tr>
<td>
<xf:trigger>
<xf:label>MC</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/memory" value="0" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>7</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 7" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>8</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 8" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>9</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 9" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>/</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/first" value="/equation/display" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
<xf:toggle case="divide" />
</xf:action>
</xf:trigger>
</td>
<td />
</tr>
<tr>
<td>
<xf:trigger>
<xf:label>MR</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/display" value="/equation/memory" />
<xf:setvalue ref="/equation/displaybuffer" value="/equation/memory" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>4</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 4" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>5</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 5" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>6</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 6" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>*</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/first" value="/equation/display" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
<xf:toggle case="multiply" />
</xf:action>
</xf:trigger>
</td>
</tr>
<tr>
<td>
<xf:trigger>
<xf:label>MS</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/memory" value="/equation/display" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>1</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 1" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>2</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 2" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>3</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 3" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>-</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/first" value="/equation/display" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
<xf:toggle case="subtract" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>1/x</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/display" value="1 div /equation/display" />
</xf:action>
</xf:trigger>
</td>
</tr>
<tr>
<td>
<xf:trigger>
<xf:label>M+</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/memory" value="/equation/memory + /equation/display" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>0</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10" />
<xf:setvalue ref="/equation/display" value="/equation/displaybuffer" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:trigger>
<xf:label>+/-</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/display" value="/equation/display * -1" />
</xf:action>
</xf:trigger>
</td>
<td />
<td>
<xf:trigger>
<xf:label>+</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/first" value="/equation/display" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
<xf:toggle case="add" />
</xf:action>
</xf:trigger>
</td>
<td>
<xf:switch>
<xf:case id="add" selected="true">
<xf:trigger>
<xf:label>=</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/second" value="/equation/displaybuffer" />
<xf:setvalue ref="/equation/result" value="/equation/first + /equation/second" />
<xf:setvalue ref="/equation/display" value="/equation/result" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
</xf:action>
</xf:trigger>
</xf:case>
<xf:case id="subtract">
<xf:trigger>
<xf:label>=</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/second" value="/equation/displaybuffer" />
<xf:setvalue ref="/equation/result" value="/equation/first - /equation/second" />
<xf:setvalue ref="/equation/display" value="/equation/result" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
</xf:action>
</xf:trigger>
</xf:case>
<xf:case id="multiply">
<xf:trigger>
<xf:label>=</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/second" value="/equation/displaybuffer" />
<xf:setvalue ref="/equation/result" value="/equation/first * /equation/second" />
<xf:setvalue ref="/equation/display" value="/equation/result" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
</xf:action>
</xf:trigger>
</xf:case>
<xf:case id="divide">
<xf:trigger>
<xf:label>=</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="/equation/second" value="/equation/displaybuffer" />
<xf:setvalue ref="/equation/result" value="/equation/first div /equation/second" />
<xf:setvalue ref="/equation/display" value="/equation/result" />
<xf:setvalue ref="/equation/displaybuffer" value="0" />
</xf:action>
</xf:trigger>
</xf:case>
</xf:switch>
</td>
</tr>
</table>
</body>
</html>
计算器程序大约有 300 行代码。但大部分代码只是说明当按钮被按下时应该执行什么操作。
计算器的模型非常简单,只有五个变量:
- display - 可见的显示
- displaybuffer - 一个不可见的辅助显示
- first - 第一个运算符
- second - 第二个运算符
- memory - 由内存功能使用
以下是“5”按钮的触发器
<td> <xf:trigger> <xf:label>5</xf:label> <xf:action ev:event="DOMActivate"> <xf:setvalue ref="/equation/displaybuffer" value="/equation/displaybuffer * 10 + 5" /> <xf:setvalue ref="/equation/display" value="/equation/displaybuffer" /> </xf:action> </xf:trigger> </td>
触发器的动作只是做两件事:
- 将显示缓冲区的值乘以 10(将数字向左移一位),然后加上 5。
- 将显示缓冲区的值复制到显示屏。
也有科学计算器,但它们的结构类似。
比较 JavaScript 版本和 XForms 版本很有趣。JavaScript 版本更短,但 JavaScript 可以利用一些可用的工具。