Author: jbeard
Date: Wed Jun 30 02:08:05 2010
New Revision: 959165

URL: http://svn.apache.org/viewvc?rev=959165&view=rev
Log:
Created an SVG demo without the HTML context to see if this resolves the 
strange drag behaviour in Firefox.

Added:
    
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.js
   (with props)
    
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.svg
   (with props)

Added: 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.js
URL: 
http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.js?rev=959165&view=auto
==============================================================================
--- 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.js
 (added)
+++ 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.js
 Wed Jun 30 02:08:05 2010
@@ -0,0 +1,662 @@
+function StatechartExecutionContext() {
+
+    var self = this; //used in the rare occasions we call public functions 
from inside this class
+    //system variable declarations
+    var _event = {
+        name: undefined,
+        data: undefined
+    },
+        _name = "",
+        _sessionid;
+
+    var _x = {
+        _event: _event,
+        _name: _name,
+        _sessionid: _sessionid
+    };
+
+    //variable declarations relating to data model
+    var firstEvent, eventStamp, tDelta, rawNode, textNode;
+
+
+    //abstract state
+
+    var AbstractState = new
+    function() {
+        //triggers are methods
+
+        this.$default = function() {};
+
+        this.init = function() {};
+
+        this.mousedown = function() {};
+
+        this.mouseup = function() {};
+
+        this.mousemove = function() {};
+
+
+        this.$default = function() {};
+    }
+
+
+    //states
+
+
+
+    var scxmlRoot = (function() {
+
+        function scxmlRootConstructor() {
+            this.parent = AbstractState;
+
+            this.initial = null;
+
+            this.depth = 0;
+
+            this.historyState = null;
+
+            //these variables facilitate fast In predicate
+            this.isBasic =
+
+            false;
+
+
+            this.toString = function() {
+                return "scxmlRoot"
+            }
+
+            this.enterAction = function() {
+
+                console.log("entering scxmlRoot");
+
+            }
+
+            this.exitAction = function() {
+
+                console.log("exiting scxmlRoot");
+
+            }
+
+
+
+
+        }
+        scxmlRootConstructor.prototype = AbstractState;
+        return new scxmlRootConstructor();
+    })();
+
+
+
+
+
+    var scxmlRoot_initial = (function() {
+
+        function scxmlRoot_initialConstructor() {
+            this.parent = scxmlRoot;
+
+            this.initial = null;
+
+            this.depth = 1;
+
+            this.historyState = null;
+
+            //these variables facilitate fast In predicate
+            this.isBasic =
+
+            true;
+
+            this.ancestors = [
+                scxmlRoot
+                ];
+
+            this.parent.initial = this; //init parent's pointer to initial 
state
+
+            this.toString = function() {
+                return "scxmlRoot_initial"
+            }
+
+            this.enterAction = function() {
+
+                console.log("entering scxmlRoot_initial");
+
+            }
+
+            this.exitAction = function() {
+
+                console.log("exiting scxmlRoot_initial");
+
+            }
+
+
+
+            this.$default = function() {
+
+
+                hasTakenDefaultTransition = true;
+
+
+                //exit states
+                scxmlRoot_initial.exitAction();
+
+
+                //transition action
+
+                //enter states
+                initial_default.enterAction();
+
+
+                //update configuration
+
+                currentConfiguration = [
+                    initial_default
+                    ];
+
+
+
+                //set whether preempted
+
+                return;
+                scxmlRoot['$default']();
+            }
+
+
+
+        }
+        scxmlRoot_initialConstructor.prototype = scxmlRoot;
+        return new scxmlRoot_initialConstructor();
+    })();
+
+
+
+
+
+    var initial_default = (function() {
+
+        function initial_defaultConstructor() {
+            this.parent = scxmlRoot;
+
+            this.initial = null;
+
+            this.depth = 1;
+
+            this.historyState = null;
+
+            //these variables facilitate fast In predicate
+            this.isBasic =
+
+            true;
+
+            this.ancestors = [
+                scxmlRoot
+                ];
+
+
+            this.toString = function() {
+                return "initial_default"
+            }
+
+            this.enterAction = function() {
+
+                console.log("entering initial_default");
+
+            }
+
+            this.exitAction = function() {
+
+                console.log("exiting initial_default");
+
+            }
+
+
+
+            this.init = function() {
+
+
+
+                //exit states
+                initial_default.exitAction();
+
+
+                //transition action
+                rawNode = _event.data.rawNode;
+                textNode = _event.data.textNode;
+                textNode.textContent = 'idle';
+
+
+                //enter states
+                idle.enterAction();
+
+
+                //update configuration
+
+                currentConfiguration = [
+                    idle
+                    ];
+
+
+
+                //set whether preempted
+
+                return;
+                scxmlRoot['init']();
+            }
+
+
+
+        }
+        initial_defaultConstructor.prototype = scxmlRoot;
+        return new initial_defaultConstructor();
+    })();
+
+
+
+
+
+    var idle = (function() {
+
+        function idleConstructor() {
+            this.parent = scxmlRoot;
+
+            this.initial = null;
+
+            this.depth = 1;
+
+            this.historyState = null;
+
+            //these variables facilitate fast In predicate
+            this.isBasic =
+
+            true;
+
+            this.ancestors = [
+                scxmlRoot
+                ];
+
+
+            this.toString = function() {
+                return "idle"
+            }
+
+            this.enterAction = function() {
+
+                console.log("entering idle");
+
+            }
+
+            this.exitAction = function() {
+
+                console.log("exiting idle");
+
+            }
+
+
+
+            this.mousedown = function() {
+
+
+
+                //exit states
+                idle.exitAction();
+
+
+                //transition action
+                firstEvent = _event.data;
+                eventStamp = _event.data;
+                textNode.textContent = 'dragging';
+
+
+                //enter states
+                dragging.enterAction();
+
+
+                //update configuration
+
+                currentConfiguration = [
+                    dragging
+                    ];
+
+
+
+                //set whether preempted
+
+                return;
+                scxmlRoot['mousedown']();
+            }
+
+
+
+        }
+        idleConstructor.prototype = scxmlRoot;
+        return new idleConstructor();
+    })();
+
+
+
+
+
+    var dragging = (function() {
+
+        function draggingConstructor() {
+            this.parent = scxmlRoot;
+
+            this.initial = null;
+
+            this.depth = 1;
+
+            this.historyState = null;
+
+            //these variables facilitate fast In predicate
+            this.isBasic =
+
+            true;
+
+            this.ancestors = [
+                scxmlRoot
+                ];
+
+
+            this.toString = function() {
+                return "dragging"
+            }
+
+            this.enterAction = function() {
+
+                console.log("entering dragging");
+
+            }
+
+            this.exitAction = function() {
+
+                console.log("exiting dragging");
+
+            }
+
+
+
+            this.mouseup = function() {
+
+
+
+                //exit states
+                dragging.exitAction();
+
+
+                //transition action
+                textNode.textContent = 'idle';
+
+
+                //enter states
+                idle.enterAction();
+
+
+                //update configuration
+
+                currentConfiguration = [
+                    idle
+                    ];
+
+
+
+                //set whether preempted
+
+                return;
+                scxmlRoot['mouseup']();
+            }
+
+
+            this.mousemove = function() {
+
+
+
+                //exit states
+                dragging.exitAction();
+
+
+                //transition action
+                tDelta = computeTDelta(eventStamp, _event.data);
+
+                translate(rawNode, tDelta);
+                eventStamp = _event.data;
+
+
+                //enter states
+                dragging.enterAction();
+
+
+                //update configuration
+
+                currentConfiguration = [
+                    dragging
+                    ];
+
+
+
+                //set whether preempted
+
+                return;
+                scxmlRoot['mousemove']();
+            }
+
+
+
+        }
+        draggingConstructor.prototype = scxmlRoot;
+        return new draggingConstructor();
+    })();
+
+
+
+
+    //states enum for glass-box unit testing
+
+    this._states = {
+        scxmlRoot_initial: scxmlRoot_initial,
+        initial_default: initial_default,
+        idle: idle,
+        dragging: dragging
+    }
+
+
+
+    //trigger methods for synchronous interaction
+
+    this.$default = function(data) {
+        if (isInStableState) {
+            runToCompletion("$default", data);
+        } else {
+            return undefined;
+        }
+    }
+
+
+    this.init = function(data) {
+        if (isInStableState) {
+            runToCompletion("init", data);
+        } else {
+            return undefined;
+        }
+    }
+
+
+    this.mousedown = function(data) {
+        if (isInStableState) {
+            runToCompletion("mousedown", data);
+        } else {
+            return undefined;
+        }
+    }
+
+
+    this.mouseup = function(data) {
+        if (isInStableState) {
+            runToCompletion("mouseup", data);
+        } else {
+            return undefined;
+        }
+    }
+
+
+    this.mousemove = function(data) {
+        if (isInStableState) {
+            runToCompletion("mousemove", data);
+        } else {
+            return undefined;
+        }
+    }
+
+
+    //initialization script
+
+    function computeTDelta(oldEvent, newEvent) {
+        //summary:computes the offset between two events; to be later used 
with this.translate
+        var dx = newEvent.clientX - oldEvent.clientX;
+        var dy = newEvent.clientY - oldEvent.clientY;
+
+        return {
+            'dx': dx,
+            'dy': dy
+        };
+    }
+
+    function translate(rawNode, tDelta) {
+        var tl = rawNode.transform.baseVal;
+        var t = tl.numberOfItems ? tl.getItem(0) : 
rawNode.ownerSVGElement.createSVGTransform();
+        var m = t.matrix;
+        var newM = 
rawNode.ownerSVGElement.createSVGMatrix().translate(tDelta.dx, 
tDelta.dy).multiply(m);
+        t.setMatrix(newM);
+        tl.initialize(t);
+        return newM;
+    }
+
+
+    //initialization method
+
+    this.initialize = function() {
+        currentConfiguration = [initial_default];
+        runToCompletion();
+        mainLoop();
+    }
+
+
+
+    //internal runtime functions
+
+    function sortByDepthDeepToShallow(a, b) {
+        return b.depth - a.depth;
+    }
+
+
+    //start static boilerplate code
+    //static private member variables
+    var currentConfiguration = []; //current configuration
+    var innerEventQueue = []; //inner event queue
+    var outerEventQueue = []; //outer event queue
+    var isInStableState = true;
+    var isPreempted = false;
+    var hasTakenDefaultTransition = false;
+    var destroyed = false;
+    var mainLoopCallback = null;
+
+    //static private member functions
+
+
+    function mainLoop() {
+
+        if (!destroyed) {
+            //take an event from the current outer event queue
+            if (outerEventQueue.length && isInStableState) {
+                runToCompletion(outerEventQueue.shift(), 
outerEventQueue.shift());
+            }
+            //call back
+            mainLoopCallback = window.setTimeout(function() {
+                mainLoop(); //FIXME: note that when calling mainloop this way, 
we won't have access to the "this" object. 
+                //I don't think we ever use it though. Everything we need is 
private in function scope.
+            }, 100);
+        }
+    }
+
+    function runToCompletion(e, data) {
+        isInStableState = false;
+
+        if (e) {
+            innerEventQueue.push(e, data);
+        }
+
+        do {
+            //take any available default transitions
+            microstep("$default");
+
+            if (!hasTakenDefaultTransition) {
+
+                if (!innerEventQueue.length) {
+                    //we have no more generated events, and no default 
transitions fired, so
+                    //we are done, and have run to completion
+                    break;
+                } else {
+                    //microstep, then dequeue next event sending in event
+                    microstep(innerEventQueue.shift(), 
innerEventQueue.shift());
+                }
+            } else {
+                //he has taken a default transition, so reset the global 
variable to false and loop again
+                hasTakenDefaultTransition = false;
+            }
+
+        } while (true)
+
+        isInStableState = true;
+    }
+
+    function microstep(e, data) {
+        currentConfiguration.forEach(function(state) {
+            if (!isPreempted) {
+                //we set the event as a global, rather than passing it into 
the function invocation as a parameter,
+                //because in cases of default events, the event object will be 
populated with previous event's data
+                if (e !== "$default") {
+                    _event.name = e;
+                    _event.data = data;
+                }
+                state[e]();
+            }
+        });
+
+        //reset the isPreempted flag
+        isPreempted = false;
+    }
+
+
+    this.destroy = function() {
+        //right now, this only disables timer and sets global destroyed 
variable to prevent future callbacks
+        window.clearTimeout(mainLoopCallback);
+        mainLoopCallback = null;
+        destroyed = true;
+    }
+
+
+    //this is for async communication
+    this.GEN = function(e, data) {
+        outerEventQueue.push(e, data);
+    }
+
+    //this may or may not be something we want to expose, but for right now, 
we at least need it for testing
+    this.getCurrentConfiguration = function() {
+        //slice it to return a copy of the configuration rather than the conf 
itself
+        //this saves us all kinds of confusion involving references and stuff
+        return currentConfiguration.slice();
+    }
+
+    //public API for In predicate
+    this.$in = function(state) {
+        return In(state);
+    }
+
+    //end static boilerplate code
+
+    function In(state) {
+        state = typeof state == "string" ? self._states[state] : state;
+
+        return state.isBasic ? currentConfiguration.indexOf(state) != -1 : 
currentConfiguration.some(function(s) {
+            return s.ancestors.indexOf(state) != -1;
+        });
+    }
+
+}

Propchange: 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.svg
URL: 
http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.svg?rev=959165&view=auto
==============================================================================
--- 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.svg
 (added)
+++ 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.svg
 Wed Jun 30 02:08:05 2010
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!--
+This demo illustrates mixing HTML, SVG, and SCXML content in a single compound
+XML document. 
+
+It also illustrates a fairly general technique, which would
+allow authoring of SVG content with inline, declarative behavioural 
descriptions
+using SCXML: 
+* the document is searched for scxml elements 
+* it compiles them locally to JavaScript, and then hooks up event listeners on 
the parent DOM node, 
+       so that DOM events are sent to the state machine for processing
+* the state machine is able to manipulate the DOM directly through executable 
content nodes
+-->
+
+<svg xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; width="100%" height="99%" 
id="svgRoot">
+       <script type="application/ecmascript" xlink:href="drag-and-drop3.js"/>
+       <g id="groupToTranslate">
+               <rect width="100" height="100" stroke="black" fill="red" 
id="rectToTranslate" />
+               <text id="textToTranslate" />
+       </g>
+
+       <script><![CDATA[
+               var resultText;
+
+               //hook up minimal console api
+               if(typeof console == "undefined"){
+                       console = {};
+                       
["log","info","error","dirxml"].forEach(function(m){console[m] = console[m] || 
function(){} });
+               } 
+
+               var svgRoot = document.getElementById("svgRoot");
+
+               var rectToTranslate = 
document.getElementById("rectToTranslate");
+               var groupToTranslate = 
document.getElementById("groupToTranslate");
+               var textToTranslate = 
document.getElementById("textToTranslate");
+
+               var compiledStatechartInstance = new 
StatechartExecutionContext(); 
+
+               //initialize
+               compiledStatechartInstance.initialize();
+               
+               //pass in reference to rect
+               
compiledStatechartInstance.init({rawNode:groupToTranslate,textNode:textToTranslate});
 
+
+               //hook up DOM events
+               ["mousedown","mouseup","mousemove"].forEach(function(eventName){
+                       
groupToTranslate.addEventListener(eventName,compiledStatechartInstance[eventName],false);
+               });
+
+               //quick hack to ensure that mm events get captured by the rect
+               
svgRoot.addEventListener("mousemove",compiledStatechartInstance["mousemove"],false);
+
+
+       ]]></script>
+</svg>

Propchange: 
commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop/drag-and-drop3.svg
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to