You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jb...@apache.org on 2010/06/30 04:08:05 UTC
svn commit: r959165 - in
/commons/sandbox/gsoc/2010/scxml-js/branches/SCXML-141-148/demo/drag-and-drop:
drag-and-drop3.js drag-and-drop3.svg
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