summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNo'am Rosenthal <noam.rosenthal@nokia.com>2009-11-07 18:22:56 -0800
committerNo'am Rosenthal <noam.rosenthal@nokia.com>2009-11-07 18:22:56 -0800
commit971072b2b14c6bcd356f79c43b1fc56974fb7134 (patch)
tree8edd269c3d39c1fc916b9128713343fc58858d86
parentcbc30076b037cafb872310577f83609cc3f88bb0 (diff)
Statechartz library for web development
-rw-r--r--statechartz/LICENSE.GPL342
-rw-r--r--statechartz/calc.scxml195
-rw-r--r--statechartz/demo.html69
-rw-r--r--statechartz/statechartz.js767
-rw-r--r--statechartz/style.css175
5 files changed, 1548 insertions, 0 deletions
diff --git a/statechartz/LICENSE.GPL b/statechartz/LICENSE.GPL
new file mode 100644
index 0000000..4ccd714
--- /dev/null
+++ b/statechartz/LICENSE.GPL
@@ -0,0 +1,342 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+-------------------------------------------------------------------------
diff --git a/statechartz/calc.scxml b/statechartz/calc.scxml
new file mode 100644
index 0000000..69df09f
--- /dev/null
+++ b/statechartz/calc.scxml
@@ -0,0 +1,195 @@
+<?xml version="1.0" ?>
+<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0"
+ initial="root" profile="ecmascript" name="calc">
+ <parallel id="root">
+ <state id="ui" initial="calc">
+ <onentry>
+ <script>showPopup('Press Spacebar to switch between widgets');</script>
+ </onentry>
+ <state id="calc">
+ <transition event="WIDGETS.NEXT" target="weather" />
+ </state>
+ <state id="weather">
+ <transition event="WIDGETS.NEXT" target="shopping" />
+ </state>
+ <state id="shopping">
+ <transition event="WIDGETS.NEXT" target="calc" />
+ </state>
+ </state>
+ <state id="popup_region" initial="popup_off">
+ <state id="popup_off">
+ <transition event="POPUP.SHOW" target="popup" />
+ </state>
+ <state id="popup">
+ <transition event="POPUP.HIDE" target="popup_off" />
+ <transition event="KEY.PRESS" target="popup_off" />
+ <onentry><script>
+ setTimeout(function(){raise("POPUP.HIDE");},2500);
+ </script></onentry>
+ </state>
+ </state>
+ <state initial="calc_logic">
+ <datamodel>
+ <data id="long_expr" expr="''" />
+ <data id="short_expr" expr="0" />
+ <data id="res" expr="0" />
+ </datamodel>
+ <state id="calc_logic" initial="on">
+ <state id="on" initial="ready">
+ <onentry>
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ <state id="ready" initial="begin">
+ <state id="begin">
+ <transition event="OPER.MINUS" target="negated1" />
+ <onentry>
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ </state>
+ <state id="result">
+ </state>
+ <transition event="OPER" target="opEntered" />
+ <transition event="DIGIT.0" target="zero1">
+ <assign dataid="short_expr" expr="''" />
+ </transition>
+ <transition event="DIGIT" target="int1">
+ <assign dataid="short_expr" expr="''" />
+ </transition>
+ <transition event="POINT" target="frac1">
+ <assign dataid="short_expr" expr="''" />
+ </transition>
+ </state>
+ <state id="negated1">
+ <onentry>
+ <assign dataid="short_expr" expr="'-'" />
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ <transition event="DIGIT.0" target="zero1" />
+ <transition event="DIGIT" target="int1" />
+ <transition event="POINT" target="frac1" />
+ </state>
+ <state id="operand1">
+ <state id="zero1">
+ <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int1" />
+ <transition event="POINT" target="frac1" />
+ </state>
+ <state id="int1">
+ <transition event="POINT" target="frac1" />
+ <transition event="DIGIT">
+ <assign dataid="short_expr" expr="_data.short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" />
+ <send event="DISPLAY.UPDATE" />
+ </transition>
+ <onentry>
+ <assign dataid="short_expr" expr="_data.short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" />
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ </state>
+ <state id="frac1">
+ <onentry>
+ <assign dataid="short_expr" expr="_data.short_expr+'.'" />
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ <transition event="DIGIT">
+ <assign dataid="short_expr" expr="_data.short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" />
+ <send event="DISPLAY.UPDATE" />
+ </transition>
+ </state>
+ <transition event="OPER" target="opEntered" />
+ </state>
+ <state id="opEntered">
+ <transition event="OPER.MINUS" target="negated2" />
+ <transition event="POINT" target="frac2" />
+ <transition event="DIGIT.0" target="zero2" />
+ <transition event="DIGIT" target="int2" />
+ <onentry>
+ <raise event="CALC.SUB" />
+ <send event="OP.INSERT">
+ <param name="operator" expr="_event.name" />
+ </send>
+ </onentry>
+ </state>
+ <state id="negated2">
+ <onentry>
+ <assign dataid="short_expr" expr="'-'" />
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ <transition event="DIGIT.0" target="zero2" />
+ <transition event="DIGIT" target="int2" />
+ <transition event="POINT" target="frac2" />
+ </state>
+ <state id="operand2">
+ <state id="zero2">
+ <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int2" />
+ <transition event="POINT" target="frac2" />
+ </state>
+ <state id="int2">
+ <transition event="DIGIT">
+ <assign dataid="short_expr" expr="_data.short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" />
+ <send event="DISPLAY.UPDATE" />
+ </transition>
+ <onentry>
+ <assign dataid="short_expr" expr="_data.short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" />
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ <transition event="POINT" target="frac2" />
+ </state>
+ <state id="frac2">
+ <onentry>
+ <assign dataid="short_expr" expr="_data.short_expr+'.'" />
+ <send event="DISPLAY.UPDATE" />
+ </onentry>
+ <transition event="DIGIT">
+ <assign dataid="short_expr" expr="_data.short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" />
+ <send event="DISPLAY.UPDATE" />
+ </transition>
+ </state>
+ <transition event="OPER" target="opEntered">
+ <raise event="CALC.SUB" />
+ <raise event="OP.INSERT" />
+ </transition>
+ <transition event="EQUALS" target="result">
+ <raise event="CALC.SUB" />
+ <raise event="CALC.DO" />
+ </transition>
+ </state>
+ <transition event="C" target="on">
+ <assign dataid="long_expr" expr="''" />
+ <assign dataid="short_expr" expr="0" />
+ <assign dataid="res" expr="0" />
+ </transition>
+ </state>
+ <transition event="CALC.DO">
+ <assign dataid="short_expr" expr="''+_data.res" />
+ <assign dataid="long_expr" expr="''" />
+ <assign dataid="res" expr="0" />
+ </transition>
+ <transition event="CALC.SUB">
+ <if cond="_data.short_expr!=''">
+ <assign dataid="long_expr" expr="_data.long_expr+'('+_data.short_expr+')'" />
+ </if>
+ <assign dataid="res" expr="eval(_data.long_expr)" />
+ <assign dataid="short_expr" expr="''" />
+ <send event="DISPLAY.UPDATE" />
+ </transition>
+ <transition event="DISPLAY.UPDATE">
+ <if cond="_data.short_expr == ''">
+ <script>outputText(_data.res);</script>
+ <else />
+ <script>outputText(_data.short_expr);</script>
+ </if>
+ </transition>
+ <transition event="OP.INSERT">
+ <if cond="_event.data.operator == 'OPER.PLUS'">
+ <assign dataid="long_expr" expr="_data.long_expr+'+'" />
+ <elseif cond="_event.data.operator=='OPER.MINUS'" />
+ <assign dataid="long_expr" expr="_data.long_expr+'-'" />
+ <elseif cond="_event.data.operator =='OPER.STAR'" />
+ <assign dataid="long_expr" expr="_data.long_expr+'*'" />
+ <elseif cond="_event.data.operator =='OPER.DIV'" />
+ <assign dataid="long_expr" expr="_data.long_expr+'/'" />
+ </if>
+ </transition>
+ </state>
+ </state>
+ </parallel>
+</scxml> \ No newline at end of file
diff --git a/statechartz/demo.html b/statechartz/demo.html
new file mode 100644
index 0000000..d4f1dc1
--- /dev/null
+++ b/statechartz/demo.html
@@ -0,0 +1,69 @@
+<html>
+ <head>
+ <link href="style.css" rel="stylesheet" />
+ <link href="calc.scxml" rel="statechart" />
+ <script src="statechartz.js"></script>
+ <script>
+
+ function outputText(txt) {
+ document.getElementById("calc_output").innerHTML = txt;
+ }
+ function showPopup(txt) {
+ document.getElementById('popup_text').innerHTML = txt;
+ document.statechart.raise("POPUP.SHOW",true);
+ }
+ function handleKey(ev) {
+ if (document.statechart != undefined) {
+ document.statechart.raise("KEY.PRESS");
+ if (ev.keyCode == 32) {
+ document.statechart.raise('WIDGETS.NEXT');
+ }
+ }
+ }
+ </script>
+ </head>
+ <body onkeydown="handleKey(event)">
+ <div id="screen_weather" class="screen">
+ <script type="text/javascript" src="http://voap.weather.com/weather/oap/USGA0028?template=OTDRH&par=3000000007&unit=0&key=twciweatherwidget"></script>
+ </div>
+ <div id="screen_shopping" class="screen">
+ <iframe src="http://onetrip.org/onetrip/?pass&go" height="240" width="320" scrolling="no" style="overflow:hidden" frameborderwidth="0"></iframe>
+ </div>
+ <div id="screen_calc" class="screen">
+ <table cellspacing="5">
+ <tr>
+ <td colspan="5"><div class="output" id="calc_output">&nbsp;</div></td>
+ </tr>
+ <tr>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.7')">7</a></td>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.8')">8</a></td>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.9')">9</a></td>
+ <td><a href="#" onmousedown="statechart.raise('OPER.PLUS')">+</a></td>
+ <td><a href="#" onmousedown="statechart.raise('OPER.MINUS')">-</a></td>
+ </tr>
+ <tr>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.4')">4</a></td>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.5')">5</a></td>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.6')">6</a></td>
+ <td><a href="#" onmousedown="statechart.raise('OPER.STAR')">*</a></td>
+ <td><a href="#" onmousedown="statechart.raise('OPER.DIV')">/</a></td>
+ </tr>
+ <tr>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.1')">1</a></td>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.2')">2</a></td>
+ <td><a href="#" onmousedown="statechart.raise('DIGIT.3')">3</a></td>
+ <td><a href="#" onmousedown="statechart.raise('CE')">CE</a></td>
+ <td><a href="#" onmousedown="statechart.raise('C')">C</a></td>
+ </tr>
+ <tr>
+ <td colspan="3"><a href="#" onmousedown="statechart.raise('DIGIT.0')">0</a></td>
+ <td><a href="#" onmousedown="statechart.raise('POINT')">.</a></td>
+ <td><a href="#" onmousedown="statechart.raise('EQUALS')">=</a></td>
+ </tr>
+ </table>
+ </div>
+ <div id="screen_popup">
+ <div id="popup_text">&nbsp</div>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/statechartz/statechartz.js b/statechartz/statechartz.js
new file mode 100644
index 0000000..547ab3d
--- /dev/null
+++ b/statechartz/statechartz.js
@@ -0,0 +1,767 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the SCXML module of the Qt Labs.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+function el_hasClass(ele,cls) {
+ return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
+}
+function el_addClass(ele,cls) {
+ if (!el_hasClass(ele,cls)) ele.className += " "+cls;
+}
+function el_removeClass(ele,cls) {
+ if (el_hasClass(ele,cls)) {
+ var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
+ ele.className=ele.className.replace(reg,' ');
+ }
+}
+var Set = Array;
+Set.prototype.add = function Set_add(o)
+{
+ for (var i=0; i < this.length; ++i) {
+ if (this[i] == o)
+ return;
+ }
+ this.push(o);
+};
+ function removeFromSet (s,o)
+ {
+ var index = s.indexOf(o);
+ var a = [];
+ for (var i=0; i < s.length; ++i)
+ if (s[i] != o)
+ a.push(s[i]);
+ return a;
+ };
+Array.prototype.clone = function() {
+ var a = new Array();
+ for (var i =0; i < this.length; ++i)
+ a[i] = this[i];
+ return a;
+};
+Object.prototype.clone = function() {
+ var o = {};
+ o.prototype = this.prototype;
+ for (var i=0; i < this.length; ++i)
+ o[i] = this[i];
+ return o;
+};
+function Signal()
+{
+ this.prototype = new Array();
+ this.connect = this.push;
+ this.emit = function() {
+ var a = arguments.clone();
+ for (var i = 0; i < this.length; ++i) {
+ this[i](a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
+ }
+ };
+
+};
+
+Statechartz =
+{
+ buildFromArgs: function(args,defaultFunc) {
+ var obj = {};
+ for (var i = 0; i < args.length; ++i) {
+ var a = args[i];
+ if (a != null) {
+ if (typeof(a) == "string") {
+ obj.id = a;
+ }
+ else
+ if (typeof(a) == "function") {
+ obj[defaultFunc] = a;
+ }
+ else
+ if (typeof(a) == "object") {
+ if (a.cls != undefined) {
+ if (obj[a.cls] == undefined)
+ obj[a.cls] = [a.obj];
+ else
+ obj[a.cls].push(a.obj);
+ }
+ else {
+ for (var n in a) {
+ obj[n] = a[n];
+ }
+ }
+ }
+ }
+ }
+ return obj;
+ },
+ buildState: function(type,args) {
+ var obj = this.buildFromArgs(args);
+ obj.type = type;
+ obj.historyStates = [];
+ obj.toString = function()
+ {
+ return ("state (id="+this.id+")");
+ };
+ if (obj.states != undefined) {
+ for (var i=0; i < obj.states.length; ++i) {
+ var s = obj.states[i];
+ s.parent = obj;
+ if (s.initial == true)
+ obj.initialState = s;
+ if (s.type == "H") {
+ obj.historyStates.push(s);
+ }
+ }
+ } else
+ obj.states = [];
+ if (obj.transitions != undefined) {
+ for (var i=0; i < obj.transitions.length; ++i) {
+ obj.transitions[i].source = obj;
+ obj.transitions[i].regexp =
+ new RegExp("^"+obj.transitions[i].event+"($|(\\.[A-Za-z0-9_]+)+$)");
+ }
+ } else
+ obj.transitions = [];
+ obj.atomic = (obj.type != "H" && obj.states.length == 0);
+ return {cls:"states",obj:obj};
+ },
+ fixStateIDs: function(state,stateByID,idx) {
+ state.sort_index = idx++;
+ stateByID[state.id] = state;
+ if (state.states != undefined)
+ for (var i = 0; i < state.states.length; ++i)
+ {
+ idx = this.fixStateIDs(state.states[i],stateByID,idx);
+ }
+ return idx;
+ },
+ fixTransitionTargets: function(state,stateByID) {
+ if (state.transitions != undefined) {
+ for (var i = 0; i < state.transitions.length; ++i)
+ {
+ var t = state.transitions[i];
+ if (t.targets != undefined)
+ for (var j=0; j < t.targets.length; ++j)
+ t.targets[j] = stateByID[t.targets[j]];
+ else
+ t.targets = [];
+ }
+ }
+ if (state.states != undefined) {
+ for (var i = 0; i < state.states.length; ++i)
+ {
+ this.fixTransitionTargets(state.states[i],stateByID);
+ }
+ }
+ },
+ fixTransitions: function(state)
+ {
+ var stateByID = {};
+ this.fixStateIDs(state,stateByID,0);
+ this.fixTransitionTargets(state,stateByID);
+ return state;
+ },
+
+ resolveFunction: function(f) {
+ if (typeof(f) == "function")
+ return f;
+ else if (typeof(f) == "string")
+ return function() { return eval(f); };
+ },
+ resolveEvent: function(e) {
+ if (typeof (e) == "string") {
+ return e;
+ } else if (typeof(e) == "function"){
+ var uid = "";
+ if (e.connect != undefined ) {
+ e.connect(function(){
+ this.raise(uid);
+ });
+ return uid;
+ }
+ } else if (typeof(e) == "object") {
+ var uid = "";
+ e += function() { this.raise(); };
+ }
+ },
+ Entry: function(f) {
+ return {onentry: this.resolveFunction(f)};
+ },
+ Exit: function(f) {
+ return {onexit: Statechartz.resolveFunction(f)};
+ },
+ Done: function(f) {
+ return {ondone: Statechartz.resolveFunction(f)};
+ },
+ Trigger: function(f) {
+ return {ontrigger: Statechartz.resolveFunction(f)};
+ },
+ Targets: function() {
+ var a = new Array();
+ for (var i =0; i < arguments.length; ++i)
+ a[i] = arguments[i];
+ return {targets: a};
+ },
+ Event: function(e) {
+ return {event:this.resolveEvent(e)};
+ },
+ Condition: function(f) {
+ return {condition: Statechartz.resolveFunction(f)};
+ },
+ Target: function(s) {return this.Targets(s);},
+ Initial: {initial:true},
+ Deep: {deep:true},
+ Shallow: {deep:false},
+ Final: function() {
+ return Statechartz.buildState("F",arguments);
+ },
+ State: function() {
+ return Statechartz.buildState("S",arguments);
+ },
+ Parallel: function() {
+ return Statechartz.buildState("P",arguments);
+ },
+ History: function() {
+ return Statechartz.buildState("H",arguments);
+ },
+ Attribute: function(element,attr,value) {
+ return {cls:"attributes", obj:{type:'A',element:element,attr:attr,value:value}};
+ },
+ Css: function(element,attr,value) {
+ return {cls:"attributes", obj:{type:'S',element:element,attr:attr,value:value}};
+ },
+ Transition: function() {
+ var t = {cls: "transitions", obj:this.buildFromArgs(arguments,"ontrigger")};
+ if (t.targets == undefined)
+ t.targets = [];
+ return t;
+ },
+ build: function(rootState) {
+
+ return {
+ rootState: Statechartz.fixTransitions(rootState.obj,{}),
+ event: {name:"",data:{}},
+ historyValues: {},
+
+ processing: false,
+ doContinue: false,
+ raise: function raise(event,external,payload)
+ {
+ if (this.externalQueue == undefined) {
+ start();
+ }
+ if (!this.processing)
+ external = true;
+ (external?this.externalQueue:this.internalQueue).push(
+ {name:event,data:payload}
+ );
+ if (!this.processing)
+ this.process();
+ },
+ start: function()
+ {
+ this.doContinue = true;
+ this.rootState.parent = undefined;
+
+ this.configuration = new Set();
+ this.externalQueue = [];
+ this.internalQueue = [];
+ this.processing = true;
+ this.enterStates([{source:this.rootState,targets:[this.rootState.initialState]}]);
+ this.process();
+ },
+ stop: function stop()
+ {
+ this.doContinue = false;
+ this.configuration = new Set();
+ this.externalQueue = this.internalQueue = [];
+ },
+ pause: function pause()
+ {
+ this.doContinue = false;
+ this.running = false;
+ },
+ configuration: new Set(),
+ eventMatch: function eventMatch(trre,transitionEvent,actualEvent)
+ {
+
+ if (transitionEvent == undefined && actualEvent == undefined)
+ return true;
+ else if (transitionEvent != undefined && actualEvent != undefined) {
+
+ return (
+ transitionEvent == "*"
+ || transitionEvent == actualEvent
+ || actualEvent.match(trre));
+
+// actualEvent.indexOf(transitionEvent+'.')==0)
+ } else
+ return false;
+ },
+ startEventLoop: function startEventLoop() {
+ var initialStepComplete = false;
+ this.processing = true;
+ while (true) {
+ var enabledTransitions = this.selectTransitions();
+ if (enabledTransitions.length == 0) {
+ var internalEvent = this.internalQueue.shift();
+ if (internalEvent != undefined ) {
+ this.event = internalEvent;
+ enabledTransitions = this.selectTransitions(internalEvent);
+ }
+ }
+ if (enabledTransitions.length != 0) {
+ microstep(this.enabledTransitions);
+ } else
+ break;
+ }
+ this.process();
+ },
+ process: function process() {
+ this.processing = true;
+ while (this.externalQueue.length > 0)
+ {
+ var externalEvent = this.externalQueue.shift();
+ this.event = externalEvent;
+ status = externalEvent.name;
+ var enabledTransitions = this.selectTransitions(externalEvent);
+ if (enabledTransitions.length) {
+ this.microstep(enabledTransitions);
+ var macrostepComplete = false;
+ while (!macrostepComplete) {
+ enabledTransitions = this.selectTransitions();
+ if (enabledTransitions.length == 0) {
+ var internalEvent = this.internalQueue.shift();
+ if (internalEvent != undefined) {
+ this.event = internalEvent;
+ enabledTransitions = this.selectTransitions(internalEvent);
+ }
+ }
+ if (enabledTransitions.length == 0) {
+ macrostepComplete = true;
+ } else {
+ this.microstep(enabledTransitions);
+ }
+ }
+
+ }
+ }
+ this.processing = false;
+ },
+ exitOrder: function(state_a,state_b)
+ {
+ return state_b.sort_index - state_a.sort_index;
+ },
+ entryOrder: function(state_a,state_b)
+ {
+ return state_a.sort_index - state_b.sort_index;
+ },
+ exitInterpreter: function() {
+ var inFinalState = false;
+ var statesToExit = this.configuration.sort(this.exitOrder);
+ for (var s=0; s < statesToExit.length; ++s) {
+ s.onexit();
+ }
+ },
+ selectTransitions: function selectTransitions(e) {
+ var enabledTransitions = new Set();
+ for (var i=0; i < this.configuration.length; ++i) {
+ var state = this.configuration[i];
+ if (state.atomic)
+ {
+ if (!this.isPreempted(state,enabledTransitions)) {
+ var ancs = [state].concat(this.getProperAncestors(state));
+ var breakLoop = false;
+ for (var j =0; j < ancs.length && !breakLoop; ++j) {
+ var tt = ancs[j].transitions;
+ if (tt != undefined) {
+ for (var ti =0; ti < tt.length; ++ti) {
+ var t = tt[ti];
+ if (t!=undefined)
+ if ((this.eventMatch(t.regexp,t.event,e==undefined?undefined:e.name)) && this.func(t.condition,e)) {
+ enabledTransitions.add(t);
+ breakLoop = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return enabledTransitions;
+ },
+ microstep: function microstep(enabledTransitions) {
+ this.exitStates(enabledTransitions);
+ for (var t=0; t < enabledTransitions.length; ++t)
+ this.func(enabledTransitions[t].ontrigger,this.event);
+ this.enterStates(enabledTransitions);
+// alert("config is now "+this.configuration);
+ },
+ exitStates: function exitStates(enabledTransitions) {
+ var statesToExit = new Set();
+ for (x=0; x < enabledTransitions.length; ++x) {
+ var t = enabledTransitions[x];
+ if (t.targets!= undefined && t.targets.length) {
+ var LCA = this.findLCA([t.source].concat(t.targets));
+ for (var i=0; i <this.configuration.length; ++i) {
+ var s = this.configuration[i];
+ if (this.isDescendant(s,LCA)) {
+ statesToExit.add(s);
+ }
+ }
+ }
+ }
+ statesToExit = statesToExit.sort(this.exitOrder);
+ for (var i=0; i< statesToExit.length;++i) {
+ var s = statesToExit[i];
+ if (s.historyStates != undefined)
+ for (var j=0;j< s.historyStates.length;++j) {
+ var h = s.historyStates[j];
+ var hconf = [];
+ for (var k = 0; k < this.configuration.length; k++) {
+ var conf = this.configuration[k];
+ if ((h.deep && this.isDescendant(conf,s)) || (!h.deep && conf.parent == s)) {
+ hconf.push(conf);
+ }
+ }
+ this.historyValues[h.id] = hconf;
+ }
+ }
+
+ for (var i =0; i< statesToExit.length;++i) {
+ var s = statesToExit[i];
+ this.func(s.onexit);
+ this.configuration = removeFromSet(this.configuration,s);
+ if (s.id != undefined && s.id != "") {
+ this.removeCssClass("state_"+s.id);
+ /*
+ var sel = document.getElementById("screen_"+s.id);
+ if (sel != null)
+ sel.style.visibility = "hidden";
+ */
+ }
+ }
+ },
+ enterStates: function enterStates(enabledTransitions) {
+ var statesToEnter = new Set();
+ var statesForDefaultEntry = new Set();
+ for (var i =0; i < enabledTransitions.length; ++i) {
+ var t = enabledTransitions[i];
+ if (t.targets!= undefined && t.targets.length) {
+ var LCA = this.findLCA([t.source].concat(t.targets));
+ for (var j =0; j < t.targets.length; ++j) {
+ this.addStatesToEnter(t.targets[j],LCA,statesToEnter,statesForDefaultEntry);
+ }
+ }
+ }
+ statesToEnter = statesToEnter.sort(this.entryOrder);
+ for (var i =0; i < statesToEnter.length; ++i) {
+ var s =statesToEnter[i];
+ this.configuration.push(s);
+ if (s.id != undefined && s.id != "") {
+ this.addCssClass("state_"+s.id);
+ var sel = document.getElementById("screen_"+s.id);
+ if (sel != null)
+ sel.style.visibility = "visible";
+ }
+ this.func(s.onentry,this.event);
+ if (s.type == "F") {
+ var parent = s.parent;
+ var gparent = parent.parent;
+ this.raise("done."+parent.id);
+ if (gparent != undefined ){
+ if (gparent.type == "P" && this.isInFinalState("P")) {
+ this.raise("done."+gparent.oid);
+ }
+ }
+ if (this.isInFinalState(this.rootState)) {
+ this.doContinue = false;
+ this.finished();
+ }
+ }
+ }
+ },
+ addStatesToEnter: function addStatesToEnter(s,root,statesToEnter)
+ {
+ if (s == undefined)
+ return;
+ if (s.type == 'H') {
+ var h =this.historyValues[s.id];
+ if (h != undefined) {
+ for (var i=0; i < h.length; ++i) {
+ this.addStatesToEnter(h[i],root,statesToEnter);
+ }
+ } else if (s.states.length) {
+ this.addStatesToEnter(s.initialState,s,statesToEnter);
+ }
+ } else {
+ statesToEnter.add(s);
+ if (s.type=='P') {
+ for (var i=0; i < s.states.length; ++i) {
+ this.addStatesToEnter(s.states[i],s,statesToEnter);
+ }
+ } else if (s.type =='S' && s.states.length) {
+ this.addStatesToEnter(s.initialState,s,statesToEnter);
+ }
+ var pa = this.getProperAncestors(s,root);
+ if (root!=undefined && root.type=='P') {
+ for (var i=0; i < root.states.length; ++i)
+ pa.add(root.states[i]);
+ }
+ for (var i=0; i < pa.length; ++i) {
+ var anc = pa[i];
+ statesToEnter.add(anc);
+ if (anc.type == "P") {
+ for (var j=0; j < anc.states.length; ++j) {
+ var pChild = anc.states[j];
+ var doAdd = true;
+ for (var k=0; k < statesToEnter.length; ++k) {
+ var s2 = statesToEnter[k];
+ if (this.isDescendant(s2,pChild)) {
+ doAdd = false;
+ break;
+ }
+ }
+ if (doAdd)
+ this.addStatesToEnter(pChild,anc,statesToEnter);
+ }
+ }
+ }
+
+ }
+ },
+ isInFinalState: function isInFinalState(state)
+ {
+ if (state.type == 'F')
+ return true;
+ else if (state.type == 'S') {
+ for (var i=0; i < this.configuration.length; ++i) {
+ var s = this.configuration[i];
+ if (s.parent == state && s.type == 'F')
+ return true;
+ }
+ } else if (state.type == 'P') {
+ var all_done = true;
+ for (var j=0; j<state.children.length; ++j) {
+ if (state.children[j].type != 'F') {
+ all_done = false;
+ break;
+ }
+ }
+ if (all_done) {
+ return true;
+ }
+ } else
+ return false;
+ },
+ isDescendant: function isDescendant(child,parent) {
+ for (var s = child.parent; s != parent; s = s.parent) {
+
+ if (typeof(s) == "undefined")
+ return false;
+ }
+ return typeof(s) != "undefined";
+ },
+ getProperAncestors: function getProperAncestors(state,root) {
+ var ancs = [];
+ var i = 0;
+ if (state!=undefined) {
+ for (var s = state.parent; s !=root && s !=undefined; s = s.parent) {
+ ancs[i++] = s;
+ }
+ }
+ return ancs;
+ },
+ findLCA: function findLCA(states) {
+ var ancs = this.getProperAncestors(states[0]);
+ for (var i=0; i < ancs.length; ++i) {
+ var anc = ancs[i];
+ var all_are_descendants = true;
+ for (var j =1; j < states.length; ++j) {
+ var s = states[j];
+ if (!this.isDescendant(s,anc)) {
+ all_are_descendants = false;
+ break;
+ }
+ }
+ if (all_are_descendants)
+ return anc;
+ else
+ return this.rootState;
+ }
+ },
+ isPreempted: function isPreempted(state,transitionList) {
+ for (var i = 0; i<transitionList.length; ++i) {
+ t = transitionList[i];
+ if (t.targets.length > 0) {
+ if (this.isDescendant(state,this.findLCA([t.source].concat(t.targets)))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ func: function func(f,e) {
+ if (typeof(f) == "function")
+ return f.call(this,e);
+ else
+ return true;
+ },
+ addCssClass: function addCssClass(cls)
+ {
+ var ctx = [document.body];
+ if (typeof(this.cssContext) != "undefined")
+ ctx = document.querySelectorAll(this.cssContext);
+ for (var i=0; i < ctx.length; ++i)
+ el_addClass(ctx[i],cls);
+ },
+ removeCssClass: function removeCssClass(cls)
+ {
+ var ctx = [document.body];
+ if (typeof(this.cssContext) != "undefined")
+ ctx = document.querySelectorAll(this.cssContext);
+ if (typeof(ctx) != 'undefined')
+ for (var i=0; i < ctx.length; ++i)
+ el_removeClass(ctx[i],cls);
+ },
+ };
+ },
+ loadScxml: function(doc) {
+ var scxmlElement = doc.documentElement;
+ function createFunctionFromExecutionContext(args) {
+ if (args.length==0)
+ return {};
+ var f = "function(_event){with(this){"+(args.join(';'))+";}}";
+// alert(f);
+ return eval(f);
+ }
+ function resolveElement(el) {
+ var args = [];
+ for (var e=el.firstElementChild; e!=null; e=e.nextElementSibling) {
+ args.push(resolveElement(e));
+ }
+
+ var tagName = el.localName.toLowerCase();
+ if (tagName=='initial' || ((tagName=='state' || tagName=='parallel' || tagName=='history') &&
+ el.parentNode.getAttribute("initial") == el.getAttribute('id')))
+ args.push(Statechartz.Initial);
+ if (tagName == "scxml") {
+ for (var e=el.firstElementChild; e!=null; e=e.nextElementSibling) {
+ if (e.localName.toLowerCase()=='script') {
+ eval(e.textContent);
+ }
+ }
+ var sc =Statechartz.build(Statechartz.buildState("S",args));
+ sc._data = {};
+ var datas = el.getElementsByTagName("data");
+ for (var i=0; i < datas.length; ++i) {
+ var data = datas[i];
+ sc._data[data.getAttribute("id")] = eval(data.getAttribute("expr"));
+ }
+ return sc;
+ } else if (tagName == "state" || tagName == "initial") {
+ args.push(el.getAttribute("id"));
+ return Statechartz.buildState("S",args);
+ } else if (tagName == "parallel") {
+ args.push(el.getAttribute("id"));
+ return Statechartz.buildState("P",args);
+ } else if (tagName == "final") {
+ args.push(el.getAttribute("id"));
+ return Statechartz.buildState("F",args);
+ } else if (tagName == "history") {
+ if (el.getAttribute("type") == "shallow")
+ args.push(el.getAttribute("type") == "shallow"?Statechartz.Shallow:Statechartz.Deep);
+ args.push(el.getAttribute("id"));
+ return Statechartz.buildState("H",args);
+ } else if (tagName == "onentry") {
+ return Statechartz.Entry(createFunctionFromExecutionContext(args));
+ } else if (tagName == "onexit") {
+ return Statechartz.Exit(createFunctionFromExecutionContext(args));
+
+ } else if (tagName == "transition") {
+ var func = createFunctionFromExecutionContext(args);
+ args = [];
+ var cond = el.getAttribute("cond");
+ var ev= el.getAttribute("event");
+ var target = el.getAttribute("target");
+ if (func != undefined)
+ args.push(func);
+ if (cond != null) {
+ args.push(Statechartz.Condition(cond));
+ }
+ if (ev != null) {
+ args.push(Statechartz.Event(ev));
+ }
+ if (target != null) {
+ args.push(Statechartz.Targets(target.split(' ')));
+ }
+ var t = {cls: "transitions", obj:Statechartz.buildFromArgs(args,"ontrigger")};
+ if (t.targets == undefined)
+ t.targets = [];
+ return t;
+ } else if (tagName == "if") {
+ return "with(this) {if ("+el.getAttribute("cond")+") {"
+ +args.join(';')
+ +"}}";
+ } else if (tagName == "elseif") {
+ return "} else if ("+el.getAttribute("cond")+") {";
+ } else if (tagName == "else") {
+ return "} else {";
+ } else if (tagName == "log") {
+ return "";
+ } else if (tagName == "raise") {
+ return 'raise("'+el.getAttribute("event")+'",false,{'+args.join(',')+'})';
+ } else if (tagName == "send") {
+ var delay_attr = el.getAttribute("delay");
+ if (delay_attr == null)
+ delay_attr = "0";
+ return 'setTimeout(function(){raise("'+el.getAttribute("event")+'",'+(el.getAttribute("target")!="_internal"?'true':'false')+',{'+args.join(',')+'}),'+
+ delay_attr
+ +'});';
+ } else if (tagName == "assign") {
+ var loc = el.getAttribute("location");
+ if (loc==null)
+ loc = "_data."+el.getAttribute("dataid");
+ return loc+"="+el.getAttribute("expr");
+ } else if (tagName == "script") {
+ return el.textContent;
+ } else if (tagName == "param") {
+ return el.getAttribute("name")+":"+el.getAttribute("expr");
+ }
+ }
+ return resolveElement(scxmlElement);
+ },
+ loadFromDocument: function() {
+ var links = document.getElementsByTagName("link");
+ for (var i=0; i < links.length;++i) {
+ var link = links[i];
+ var rel = link.getAttribute("rel");
+ if (rel == "statechart") {
+ var href = link.getAttribute("href");
+ var xhttp=new XMLHttpRequest();
+ xhttp.open("GET",href,false);
+ xhttp.send("");
+ var xmlDoc=xhttp.responseXML;
+ document.statechart = Statechartz.loadScxml(xmlDoc);
+ document.statechart.start();
+ }
+ }
+ }
+
+
+};
+
+window.onload = Statechartz.loadFromDocument;
diff --git a/statechartz/style.css b/statechartz/style.css
new file mode 100644
index 0000000..0e19be1
--- /dev/null
+++ b/statechartz/style.css
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the SCXML module of the Qt Labs.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+body {
+ background-image: -webkit-gradient(linear, left top, right bottom, from(#000000), to(#001133));
+ width: 400px;
+ height: 400px;
+}
+div.screen {
+ position: absolute;
+ -webkit-border-radius: 8px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+ border-width: 5px;
+ border-style: groove;
+ opacity: 0.1;
+ -webkit-transition-duration: 1s;
+}
+
+#screen_weather {
+ border-color: #cccc66;
+ left: -250px;
+ top: -250px;
+ position: absolute;
+ -webkit-transform: rotate(90deg) scale(0.8);
+}
+.state_weather #screen_weather {
+ left: 0px;
+ top: 0px;
+ -webkit-transform: rotate(0deg) scale(1);
+ -webkit-transition-duration: 600ms;
+ opacity: 1;
+}
+#screen_shopping {
+ border-color: #cccc66;
+ left: 0px;
+ top: -350px;
+ position: absolute;
+ -webkit-transform: rotate(90deg) scale(0.8);
+ -webkit-transition-duration: 1s;
+}
+.state_shopping #screen_shopping {
+ left: 0px;
+ top: 0px;
+ -webkit-transform: rotate(0deg) scale(1);
+ opacity: 1;
+}
+.state_calc #screen_shopping {
+ -webkit-transform: rotate(-360deg) scale(0.4);
+}
+#instructions {
+ left: 20px;
+ top: 400px;
+ position: absolute;
+}
+#screen_calc {
+ border-color: #cc66cc;
+ left: -350px;
+ top: 0px;
+ -webkit-transform: rotate(270deg);
+}
+.state_calc #screen_calc {
+ left: 0px;
+ top: 0px;
+ -webkit-transform: rotate(360deg) scale(1);
+ opacity: 1;
+}
+.state_shopping #screen_weather {
+ -webkit-transform: rotate(90deg) scale(0.4);
+}
+.state_weather #screen_calc {
+ -webkit-transform: rotate(640deg) scale(0.4);
+}
+.state_weather #screen_weather {
+ left: 0px;
+ top: 0px;
+ -webkit-transform: rotate(360deg);
+}
+* {
+ font-family: verdana,arial;
+ font-weight: bold;
+}
+#screen_calc table {
+ -webkit-border-radius: 3px;
+ background-color: #999999;
+ width: 200px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+}
+#screen_calc .output {
+ background-image: -webkit-gradient(linear, left top, right bottom, from(#66ccff), to(#bbbbee));
+ color: black;
+ text-align: right;
+ padding: 2px;
+ width: 170px;
+ margin: 0px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+#screen_calc a {
+ text-decoration: none;
+ color: #EEDDFF;
+ -webkit-text-stroke: 1px #ffffcc;
+ display: block;
+ width: 100%;
+ height: 100%;
+}
+@-webkit-keyframes bounce {
+ 0% {
+ margin-top: 0px;
+ }
+ 50% {
+ margin-top: -30px;
+ }
+ 100% {
+ margin-top: 0px;
+ }
+}
+
+#screen_calc a:active {
+ -webkit-animation-name: bounce;
+ -webkit-animation-duration: 300ms;
+ -webkit-animation-properties: top;
+ -webkit-animation-iteration-count: 1;
+ -webkit-animation-easing-function: ease;
+}
+#screen_calc td {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#333), to(#005));
+ padding: 4px;
+ margin: 3px;
+ text-align: center;
+ width: 20%;
+ -webkit-border-radius: 3px;
+ border-color: #444466;
+ border-width: 3px;
+ border-style: solid;
+}
+#screen_popup {
+ opacity: 0;
+ -webkit-transition-duration: 400ms;
+ position: absolute;
+ left: 30px;
+ top: 90px;
+ -webkit-transform: scale(0.8);
+ text-align: center;
+ width: 200px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ffcc66), to(#ffffcc));
+ -webkit-border-radius: 4px;
+ border-color: #993300;
+ border-style: solid;
+ padding: 4px;
+ z-index: -1;
+}
+.state_popup #screen_popup {
+ opacity: 1;
+ z-index: 2;
+ -webkit-transform: scale(1);
+ top: 60px;
+}