├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── flexCompiler.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── workspace.xml ├── README.md ├── flex ├── flex.iml ├── html-template │ ├── expressInstall.swf │ ├── history │ │ ├── history.css │ │ ├── history.js │ │ └── historyFrame.html │ ├── index.template.html │ └── swfobject.js └── src │ ├── Main.mxml │ ├── Tool.as │ ├── canvas │ ├── MainCanvas.mxml │ └── NullDragProxy.mxml │ └── components │ ├── ArrowLeft.mxml │ ├── ArrowRight.mxml │ ├── Line.mxml │ ├── Node.mxml │ └── NodeDragProxy.mxml └── web ├── Main.html ├── Main.swf ├── dagre.js ├── expressInstall.swf ├── history ├── history.css ├── history.js └── historyFrame.html ├── index.html ├── script.js ├── swfobject.js ├── web.iml └── wf.gif /.idea/.name: -------------------------------------------------------------------------------- 1 | flexdagre -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/flexCompiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # workflowcanvas 2 | flex 绘制流程图 算法是 dagre.js 提供 3 | 可以实现拖拽绘制流程图 4 | 5 | 6 | ![alt text](https://raw.githubusercontent.com/aruis/workflowcanvas/master/web/wf.gif) 7 | -------------------------------------------------------------------------------- /flex/flex.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /flex/html-template/expressInstall.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruis/workflowcanvas/fce2572b1584c39a94554b125c4b3ca054a65aac/flex/html-template/expressInstall.swf -------------------------------------------------------------------------------- /flex/html-template/history/history.css: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * contributor license agreements. See the NOTICE file distributed with 5 | * this work for additional information regarding copyright ownership. 6 | * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * (the "License"); you may not use this file except in compliance with 8 | * the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | */ 19 | /* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */ 20 | 21 | #ie_historyFrame { width: 0px; height: 0px; display:none } 22 | #firefox_anchorDiv { width: 0px; height: 0px; display:none } 23 | #safari_formDiv { width: 0px; height: 0px; display:none } 24 | #safari_rememberDiv { width: 0px; height: 0px; display:none } 25 | -------------------------------------------------------------------------------- /flex/html-template/history/history.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * contributor license agreements. See the NOTICE file distributed with 5 | * this work for additional information regarding copyright ownership. 6 | * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * (the "License"); you may not use this file except in compliance with 8 | * the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | */ 19 | BrowserHistoryUtils = { 20 | addEvent: function(elm, evType, fn, useCapture) { 21 | useCapture = useCapture || false; 22 | if (elm.addEventListener) { 23 | elm.addEventListener(evType, fn, useCapture); 24 | return true; 25 | } 26 | else if (elm.attachEvent) { 27 | var r = elm.attachEvent('on' + evType, fn); 28 | return r; 29 | } 30 | else { 31 | elm['on' + evType] = fn; 32 | } 33 | } 34 | } 35 | 36 | BrowserHistory = (function() { 37 | // type of browser 38 | var browser = { 39 | ie: false, 40 | ie8: false, 41 | firefox: false, 42 | safari: false, 43 | opera: false, 44 | version: -1 45 | }; 46 | 47 | // Default app state URL to use when no fragment ID present 48 | var defaultHash = ''; 49 | 50 | // Last-known app state URL 51 | var currentHref = document.location.href; 52 | 53 | // Initial URL (used only by IE) 54 | var initialHref = document.location.href; 55 | 56 | // Initial URL (used only by IE) 57 | var initialHash = document.location.hash; 58 | 59 | // History frame source URL prefix (used only by IE) 60 | var historyFrameSourcePrefix = 'history/historyFrame.html?'; 61 | 62 | // History maintenance (used only by Safari) 63 | var currentHistoryLength = -1; 64 | 65 | // Flag to denote the existence of onhashchange 66 | var browserHasHashChange = false; 67 | 68 | var historyHash = []; 69 | 70 | var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash); 71 | 72 | var backStack = []; 73 | var forwardStack = []; 74 | 75 | var currentObjectId = null; 76 | 77 | //UserAgent detection 78 | var useragent = navigator.userAgent.toLowerCase(); 79 | 80 | if (useragent.indexOf("opera") != -1) { 81 | browser.opera = true; 82 | } else if (useragent.indexOf("msie") != -1) { 83 | browser.ie = true; 84 | browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4)); 85 | if (browser.version == 8) 86 | { 87 | browser.ie = false; 88 | browser.ie8 = true; 89 | } 90 | } else if (useragent.indexOf("safari") != -1) { 91 | browser.safari = true; 92 | browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7)); 93 | } else if (useragent.indexOf("gecko") != -1) { 94 | browser.firefox = true; 95 | } 96 | 97 | if (browser.ie == true && browser.version == 7) { 98 | window["_ie_firstload"] = false; 99 | } 100 | 101 | function hashChangeHandler() 102 | { 103 | currentHref = document.location.href; 104 | var flexAppUrl = getHash(); 105 | //ADR: to fix multiple 106 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 107 | var pl = getPlayers(); 108 | for (var i = 0; i < pl.length; i++) { 109 | pl[i].browserURLChange(flexAppUrl); 110 | } 111 | } else { 112 | getPlayer().browserURLChange(flexAppUrl); 113 | } 114 | } 115 | 116 | // Accessor functions for obtaining specific elements of the page. 117 | function getHistoryFrame() 118 | { 119 | return document.getElementById('ie_historyFrame'); 120 | } 121 | 122 | function getFormElement() 123 | { 124 | return document.getElementById('safari_formDiv'); 125 | } 126 | 127 | function getRememberElement() 128 | { 129 | return document.getElementById("safari_remember_field"); 130 | } 131 | 132 | // Get the Flash player object for performing ExternalInterface callbacks. 133 | // Updated for changes to SWFObject2. 134 | function getPlayer(id) { 135 | var i; 136 | 137 | if (id && document.getElementById(id)) { 138 | var r = document.getElementById(id); 139 | if (typeof r.SetVariable != "undefined") { 140 | return r; 141 | } 142 | else { 143 | var o = r.getElementsByTagName("object"); 144 | var e = r.getElementsByTagName("embed"); 145 | for (i = 0; i < o.length; i++) { 146 | if (typeof o[i].browserURLChange != "undefined") 147 | return o[i]; 148 | } 149 | for (i = 0; i < e.length; i++) { 150 | if (typeof e[i].browserURLChange != "undefined") 151 | return e[i]; 152 | } 153 | } 154 | } 155 | else { 156 | var o = document.getElementsByTagName("object"); 157 | var e = document.getElementsByTagName("embed"); 158 | for (i = 0; i < e.length; i++) { 159 | if (typeof e[i].browserURLChange != "undefined") 160 | { 161 | return e[i]; 162 | } 163 | } 164 | for (i = 0; i < o.length; i++) { 165 | if (typeof o[i].browserURLChange != "undefined") 166 | { 167 | return o[i]; 168 | } 169 | } 170 | } 171 | return undefined; 172 | } 173 | 174 | function getPlayers() { 175 | var i; 176 | var players = []; 177 | if (players.length == 0) { 178 | var tmp = document.getElementsByTagName('object'); 179 | for (i = 0; i < tmp.length; i++) 180 | { 181 | if (typeof tmp[i].browserURLChange != "undefined") 182 | players.push(tmp[i]); 183 | } 184 | } 185 | if (players.length == 0 || players[0].object == null) { 186 | var tmp = document.getElementsByTagName('embed'); 187 | for (i = 0; i < tmp.length; i++) 188 | { 189 | if (typeof tmp[i].browserURLChange != "undefined") 190 | players.push(tmp[i]); 191 | } 192 | } 193 | return players; 194 | } 195 | 196 | function getIframeHash() { 197 | var doc = getHistoryFrame().contentWindow.document; 198 | var hash = String(doc.location.search); 199 | if (hash.length == 1 && hash.charAt(0) == "?") { 200 | hash = ""; 201 | } 202 | else if (hash.length >= 2 && hash.charAt(0) == "?") { 203 | hash = hash.substring(1); 204 | } 205 | return hash; 206 | } 207 | 208 | /* Get the current location hash excluding the '#' symbol. */ 209 | function getHash() { 210 | // It would be nice if we could use document.location.hash here, 211 | // but it's faulty sometimes. 212 | var idx = document.location.href.indexOf('#'); 213 | return (idx >= 0) ? document.location.href.substr(idx+1) : ''; 214 | } 215 | 216 | /* Get the current location hash excluding the '#' symbol. */ 217 | function setHash(hash) { 218 | // It would be nice if we could use document.location.hash here, 219 | // but it's faulty sometimes. 220 | if (hash == '') hash = '#' 221 | document.location.hash = hash; 222 | } 223 | 224 | function createState(baseUrl, newUrl, flexAppUrl) { 225 | return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; 226 | } 227 | 228 | /* Add a history entry to the browser. 229 | * baseUrl: the portion of the location prior to the '#' 230 | * newUrl: the entire new URL, including '#' and following fragment 231 | * flexAppUrl: the portion of the location following the '#' only 232 | */ 233 | function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { 234 | 235 | //delete all the history entries 236 | forwardStack = []; 237 | 238 | if (browser.ie) { 239 | //Check to see if we are being asked to do a navigate for the first 240 | //history entry, and if so ignore, because it's coming from the creation 241 | //of the history iframe 242 | if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { 243 | currentHref = initialHref; 244 | return; 245 | } 246 | if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { 247 | newUrl = baseUrl + '#' + defaultHash; 248 | flexAppUrl = defaultHash; 249 | } else { 250 | // for IE, tell the history frame to go somewhere without a '#' 251 | // in order to get this entry into the browser history. 252 | getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; 253 | } 254 | setHash(flexAppUrl); 255 | } else { 256 | 257 | //ADR 258 | if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { 259 | initialState = createState(baseUrl, newUrl, flexAppUrl); 260 | } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { 261 | backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); 262 | } 263 | 264 | if (browser.safari && !browserHasHashChange) { 265 | // for Safari, submit a form whose action points to the desired URL 266 | if (browser.version <= 419.3) { 267 | var file = window.location.pathname.toString(); 268 | file = file.substring(file.lastIndexOf("/")+1); 269 | getFormElement().innerHTML = '
'; 270 | //get the current elements and add them to the form 271 | var qs = window.location.search.substring(1); 272 | var qs_arr = qs.split("&"); 273 | for (var i = 0; i < qs_arr.length; i++) { 274 | var tmp = qs_arr[i].split("="); 275 | var elem = document.createElement("input"); 276 | elem.type = "hidden"; 277 | elem.name = tmp[0]; 278 | elem.value = tmp[1]; 279 | document.forms.historyForm.appendChild(elem); 280 | } 281 | document.forms.historyForm.submit(); 282 | } else { 283 | top.location.hash = flexAppUrl; 284 | } 285 | // We also have to maintain the history by hand for Safari 286 | historyHash[history.length] = flexAppUrl; 287 | _storeStates(); 288 | } else { 289 | // Otherwise, just tell the browser to go there 290 | setHash(flexAppUrl); 291 | } 292 | } 293 | backStack.push(createState(baseUrl, newUrl, flexAppUrl)); 294 | } 295 | 296 | function _storeStates() { 297 | if (browser.safari) { 298 | getRememberElement().value = historyHash.join(","); 299 | } 300 | } 301 | 302 | function handleBackButton() { 303 | //The "current" page is always at the top of the history stack. 304 | var current = backStack.pop(); 305 | if (!current) { return; } 306 | var last = backStack[backStack.length - 1]; 307 | if (!last && backStack.length == 0){ 308 | last = initialState; 309 | } 310 | forwardStack.push(current); 311 | } 312 | 313 | function handleForwardButton() { 314 | //summary: private method. Do not call this directly. 315 | 316 | var last = forwardStack.pop(); 317 | if (!last) { return; } 318 | backStack.push(last); 319 | } 320 | 321 | function handleArbitraryUrl() { 322 | //delete all the history entries 323 | forwardStack = []; 324 | } 325 | 326 | /* Called periodically to poll to see if we need to detect navigation that has occurred */ 327 | function checkForUrlChange() { 328 | 329 | if (browser.ie) { 330 | if (currentHref != document.location.href && currentHref + '#' != document.location.href) { 331 | //This occurs when the user has navigated to a specific URL 332 | //within the app, and didn't use browser back/forward 333 | //IE seems to have a bug where it stops updating the URL it 334 | //shows the end-user at this point, but programatically it 335 | //appears to be correct. Do a full app reload to get around 336 | //this issue. 337 | if (browser.version < 7) { 338 | currentHref = document.location.href; 339 | document.location.reload(); 340 | } else { 341 | if (getHash() != getIframeHash()) { 342 | // this.iframe.src = this.blankURL + hash; 343 | var sourceToSet = historyFrameSourcePrefix + getHash(); 344 | getHistoryFrame().src = sourceToSet; 345 | currentHref = document.location.href; 346 | } 347 | } 348 | } 349 | } 350 | 351 | if (browser.safari && !browserHasHashChange) { 352 | // For Safari, we have to check to see if history.length changed. 353 | if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { 354 | //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); 355 | var flexAppUrl = getHash(); 356 | if (browser.version < 528.16 /* Anything earlier than Safari 4.0 */) 357 | { 358 | // If it did change and we're running Safari 3.x or earlier, 359 | // then we have to look the old state up in our hand-maintained 360 | // array since document.location.hash won't have changed, 361 | // then call back into BrowserManager. 362 | currentHistoryLength = history.length; 363 | flexAppUrl = historyHash[currentHistoryLength]; 364 | } 365 | 366 | //ADR: to fix multiple 367 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 368 | var pl = getPlayers(); 369 | for (var i = 0; i < pl.length; i++) { 370 | pl[i].browserURLChange(flexAppUrl); 371 | } 372 | } else { 373 | getPlayer().browserURLChange(flexAppUrl); 374 | } 375 | _storeStates(); 376 | } 377 | } 378 | if (browser.firefox && !browserHasHashChange) { 379 | if (currentHref != document.location.href) { 380 | var bsl = backStack.length; 381 | 382 | var urlActions = { 383 | back: false, 384 | forward: false, 385 | set: false 386 | } 387 | 388 | if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { 389 | urlActions.back = true; 390 | // FIXME: could this ever be a forward button? 391 | // we can't clear it because we still need to check for forwards. Ugg. 392 | // clearInterval(this.locationTimer); 393 | handleBackButton(); 394 | } 395 | 396 | // first check to see if we could have gone forward. We always halt on 397 | // a no-hash item. 398 | if (forwardStack.length > 0) { 399 | if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { 400 | urlActions.forward = true; 401 | handleForwardButton(); 402 | } 403 | } 404 | 405 | // ok, that didn't work, try someplace back in the history stack 406 | if ((bsl >= 2) && (backStack[bsl - 2])) { 407 | if (backStack[bsl - 2].flexAppUrl == getHash()) { 408 | urlActions.back = true; 409 | handleBackButton(); 410 | } 411 | } 412 | 413 | if (!urlActions.back && !urlActions.forward) { 414 | var foundInStacks = { 415 | back: -1, 416 | forward: -1 417 | } 418 | 419 | for (var i = 0; i < backStack.length; i++) { 420 | if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { 421 | arbitraryUrl = true; 422 | foundInStacks.back = i; 423 | } 424 | } 425 | for (var i = 0; i < forwardStack.length; i++) { 426 | if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { 427 | arbitraryUrl = true; 428 | foundInStacks.forward = i; 429 | } 430 | } 431 | handleArbitraryUrl(); 432 | } 433 | 434 | // Firefox changed; do a callback into BrowserManager to tell it. 435 | currentHref = document.location.href; 436 | var flexAppUrl = getHash(); 437 | //ADR: to fix multiple 438 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 439 | var pl = getPlayers(); 440 | for (var i = 0; i < pl.length; i++) { 441 | pl[i].browserURLChange(flexAppUrl); 442 | } 443 | } else { 444 | getPlayer().browserURLChange(flexAppUrl); 445 | } 446 | } 447 | } 448 | } 449 | 450 | var _initialize = function () { 451 | 452 | browserHasHashChange = ("onhashchange" in document.body); 453 | 454 | if (browser.ie) 455 | { 456 | var scripts = document.getElementsByTagName('script'); 457 | for (var i = 0, s; s = scripts[i]; i++) { 458 | if (s.src.indexOf("history.js") > -1) { 459 | var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); 460 | } 461 | } 462 | historyFrameSourcePrefix = iframe_location + "?"; 463 | var src = historyFrameSourcePrefix; 464 | 465 | var iframe = document.createElement("iframe"); 466 | iframe.id = 'ie_historyFrame'; 467 | iframe.name = 'ie_historyFrame'; 468 | iframe.src = 'javascript:false;'; 469 | 470 | try { 471 | document.body.appendChild(iframe); 472 | } catch(e) { 473 | setTimeout(function() { 474 | document.body.appendChild(iframe); 475 | }, 0); 476 | } 477 | } 478 | 479 | if (browser.safari && !browserHasHashChange) 480 | { 481 | var rememberDiv = document.createElement("div"); 482 | rememberDiv.id = 'safari_rememberDiv'; 483 | document.body.appendChild(rememberDiv); 484 | rememberDiv.innerHTML = ''; 485 | 486 | var formDiv = document.createElement("div"); 487 | formDiv.id = 'safari_formDiv'; 488 | document.body.appendChild(formDiv); 489 | 490 | var reloader_content = document.createElement('div'); 491 | reloader_content.id = 'safarireloader'; 492 | var scripts = document.getElementsByTagName('script'); 493 | for (var i = 0, s; s = scripts[i]; i++) { 494 | if (s.src.indexOf("history.js") > -1) { 495 | html = (new String(s.src)).replace(".js", ".html"); 496 | } 497 | } 498 | reloader_content.innerHTML = ''; 499 | document.body.appendChild(reloader_content); 500 | reloader_content.style.position = 'absolute'; 501 | reloader_content.style.left = reloader_content.style.top = '-9999px'; 502 | iframe = reloader_content.getElementsByTagName('iframe')[0]; 503 | 504 | if (document.getElementById("safari_remember_field").value != "" ) { 505 | historyHash = document.getElementById("safari_remember_field").value.split(","); 506 | } 507 | } 508 | 509 | if (browserHasHashChange) 510 | document.body.onhashchange = hashChangeHandler; 511 | } 512 | 513 | return { 514 | historyHash: historyHash, 515 | backStack: function() { return backStack; }, 516 | forwardStack: function() { return forwardStack }, 517 | getPlayer: getPlayer, 518 | initialize: function(src) { 519 | _initialize(src); 520 | }, 521 | setURL: function(url) { 522 | document.location.href = url; 523 | }, 524 | getURL: function() { 525 | return document.location.href; 526 | }, 527 | getTitle: function() { 528 | return document.title; 529 | }, 530 | setTitle: function(title) { 531 | try { 532 | backStack[backStack.length - 1].title = title; 533 | } catch(e) { } 534 | //if on safari, set the title to be the empty string. 535 | if (browser.safari) { 536 | if (title == "") { 537 | try { 538 | var tmp = window.location.href.toString(); 539 | title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); 540 | } catch(e) { 541 | title = ""; 542 | } 543 | } 544 | } 545 | document.title = title; 546 | }, 547 | setDefaultURL: function(def) 548 | { 549 | defaultHash = def; 550 | def = getHash(); 551 | //trailing ? is important else an extra frame gets added to the history 552 | //when navigating back to the first page. Alternatively could check 553 | //in history frame navigation to compare # and ?. 554 | if (browser.ie) 555 | { 556 | window['_ie_firstload'] = true; 557 | var sourceToSet = historyFrameSourcePrefix + def; 558 | var func = function() { 559 | getHistoryFrame().src = sourceToSet; 560 | window.location.replace("#" + def); 561 | setInterval(checkForUrlChange, 50); 562 | } 563 | try { 564 | func(); 565 | } catch(e) { 566 | window.setTimeout(function() { func(); }, 0); 567 | } 568 | } 569 | 570 | if (browser.safari) 571 | { 572 | currentHistoryLength = history.length; 573 | if (historyHash.length == 0) { 574 | historyHash[currentHistoryLength] = def; 575 | var newloc = "#" + def; 576 | window.location.replace(newloc); 577 | } else { 578 | //alert(historyHash[historyHash.length-1]); 579 | } 580 | setInterval(checkForUrlChange, 50); 581 | } 582 | 583 | 584 | if (browser.firefox || browser.opera) 585 | { 586 | var reg = new RegExp("#" + def + "$"); 587 | if (window.location.toString().match(reg)) { 588 | } else { 589 | var newloc ="#" + def; 590 | window.location.replace(newloc); 591 | } 592 | setInterval(checkForUrlChange, 50); 593 | } 594 | 595 | }, 596 | 597 | /* Set the current browser URL; called from inside BrowserManager to propagate 598 | * the application state out to the container. 599 | */ 600 | setBrowserURL: function(flexAppUrl, objectId) { 601 | if (browser.ie && typeof objectId != "undefined") { 602 | currentObjectId = objectId; 603 | } 604 | //fromIframe = fromIframe || false; 605 | //fromFlex = fromFlex || false; 606 | //alert("setBrowserURL: " + flexAppUrl); 607 | //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; 608 | 609 | var pos = document.location.href.indexOf('#'); 610 | var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; 611 | var newUrl = baseUrl + '#' + flexAppUrl; 612 | 613 | if (document.location.href != newUrl && document.location.href + '#' != newUrl) { 614 | currentHref = newUrl; 615 | addHistoryEntry(baseUrl, newUrl, flexAppUrl); 616 | currentHistoryLength = history.length; 617 | } 618 | }, 619 | 620 | browserURLChange: function(flexAppUrl) { 621 | var objectId = null; 622 | if (browser.ie && currentObjectId != null) { 623 | objectId = currentObjectId; 624 | } 625 | 626 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 627 | var pl = getPlayers(); 628 | for (var i = 0; i < pl.length; i++) { 629 | try { 630 | pl[i].browserURLChange(flexAppUrl); 631 | } catch(e) { } 632 | } 633 | } else { 634 | try { 635 | getPlayer(objectId).browserURLChange(flexAppUrl); 636 | } catch(e) { } 637 | } 638 | 639 | currentObjectId = null; 640 | }, 641 | getUserAgent: function() { 642 | return navigator.userAgent; 643 | }, 644 | getPlatform: function() { 645 | return navigator.platform; 646 | } 647 | 648 | } 649 | 650 | })(); 651 | 652 | // Initialization 653 | 654 | // Automated unit testing and other diagnostics 655 | 656 | function setURL(url) 657 | { 658 | document.location.href = url; 659 | } 660 | 661 | function backButton() 662 | { 663 | history.back(); 664 | } 665 | 666 | function forwardButton() 667 | { 668 | history.forward(); 669 | } 670 | 671 | function goForwardOrBackInHistory(step) 672 | { 673 | history.go(step); 674 | } 675 | 676 | //BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); 677 | (function(i) { 678 | var u =navigator.userAgent;var e=/*@cc_on!@*/false; 679 | var st = setTimeout; 680 | if(/webkit/i.test(u)){ 681 | st(function(){ 682 | var dr=document.readyState; 683 | if(dr=="loaded"||dr=="complete"){i()} 684 | else{st(arguments.callee,10);}},10); 685 | } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ 686 | document.addEventListener("DOMContentLoaded",i,false); 687 | } else if(e){ 688 | (function(){ 689 | var t=document.createElement('doc:rdy'); 690 | try{t.doScroll('left'); 691 | i();t=null; 692 | }catch(e){st(arguments.callee,0);}})(); 693 | } else{ 694 | window.onload=i; 695 | } 696 | })( function() {BrowserHistory.initialize();} ); 697 | -------------------------------------------------------------------------------- /flex/html-template/history/historyFrame.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 43 | Hidden frame for Browser History support. 44 | 45 | 46 | -------------------------------------------------------------------------------- /flex/html-template/index.template.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 29 | 30 | ${title} 31 | 32 | 33 | 39 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 77 | 78 | 79 | 83 |
84 |

85 | To view this page ensure that Adobe Flash Player version 86 | ${version_major}.${version_minor}.${version_revision} or greater is installed. 87 |

88 | 93 |
94 | 95 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /flex/html-template/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab 2 | 4 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /flex/src/Tool.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liurui on 15/7/18. 3 | */ 4 | package { 5 | import components.Node; 6 | 7 | import mx.utils.UIDUtil; 8 | 9 | public class Tool { 10 | 11 | public function Tool() { 12 | } 13 | 14 | public static function isOverHit(node:Node):Boolean { 15 | var x:Number = node.mouseX; 16 | var y:Number = node.mouseY; 17 | 18 | if (x > -Node.xOverFlow && x < Node.SIDE_LENGTH + Node.xOverFlow && y > -Node.yOverFlow && y < Node.SIDE_LENGTH + Node.yOverFlow) 19 | return true; 20 | else 21 | return false; 22 | 23 | 24 | } 25 | 26 | public static function createUID():String { 27 | var uid:String = UIDUtil.createUID(); 28 | uid = uid.replace(/-/g, ''); 29 | return uid; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /flex/src/canvas/MainCanvas.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 11 | = 0; i--) { 113 | var n = getElementAt(i); 114 | if (n is Node) { 115 | 116 | } else { 117 | removeElement(n) 118 | } 119 | } 120 | 121 | edges.forEach(function (d) { 122 | 123 | //l.path.data = 124 | var p:Array = d.points; 125 | 126 | var i = 0; 127 | p.forEach(function (pd) { 128 | if (i < p.length - 1) { 129 | 130 | var x1 = pd.x + Node.SIDE_LENGTH / 2, x2 = p[i + 1].x + Node.SIDE_LENGTH / 2, 131 | y1 = pd.y + Node.SIDE_LENGTH / 2, y2 = p[i + 1].y + Node.SIDE_LENGTH / 2; 132 | 133 | var l:Line = new Line(); 134 | l.xFrom = x1; 135 | l.yFrom = y1; 136 | 137 | l.xTo = x2; 138 | l.yTo = y2; 139 | 140 | addElement(l); 141 | 142 | if (i == p.length - 2) { 143 | 144 | var a:Graphic; 145 | if (x2 > x1) { 146 | a = new ArrowRight(); 147 | a.x = x2; 148 | a.y = y2; 149 | a.rotation = Math.atan((y2 - y1) / (x2 - x1)) / Math.PI * 180; 150 | 151 | } else { 152 | a = new ArrowLeft(); 153 | a.x = x2; 154 | a.y = y2; 155 | a.rotation = Math.atan((y2 - y1) / (x2 - x1)) / Math.PI * 180; 156 | } 157 | addElement(a) 158 | 159 | } 160 | } 161 | 162 | 163 | i++; 164 | }) 165 | 166 | }) 167 | } 168 | 169 | /** 170 | * 拖拽进入,接收拖拽 171 | * @param e 172 | */ 173 | private function dragEnterHandler(e:DragEvent):void { 174 | 175 | var drag:DragSource = e.dragSource; 176 | if (drag.hasFormat('isOut') || drag.hasFormat('isIn')) { 177 | DragManager.acceptDragDrop(IUIComponent(e.target)); 178 | } 179 | } 180 | 181 | 182 | /** 183 | * 拖拽在界面上移动,判断拖拽命中节点 184 | * @param event 185 | */ 186 | private function dragOverHandler(event:DragEvent):void { 187 | if (event.dragSource.hasFormat("isIn")) { 188 | var from:Node = event.dragSource.dataForFormat('isIn') as Node; 189 | 190 | //var dragLine:Line = new Line(); 191 | dragLine.visible = true; 192 | 193 | dragLine.xFrom = from.x + from.width / 2; 194 | dragLine.yFrom = from.y + from.height / 2; 195 | 196 | 197 | dragLine.xTo = event.localX; 198 | dragLine.yTo = event.localY; 199 | 200 | 201 | trace(dragLine.xFrom + " ," + dragLine.yFrom + " to " + dragLine.xTo + "," + dragLine.yTo) 202 | addElement(dragLine); 203 | var hitNode:Node; 204 | 205 | for each(var node:Node in nodeList) { 206 | if (Tool.isOverHit(node)) { 207 | hitNode = node; 208 | break; 209 | } 210 | } 211 | 212 | if (hitNode != from) { 213 | DragManager.showFeedback(DragManager.LINK); 214 | } else { 215 | DragManager.showFeedback(DragManager.NONE); 216 | } 217 | 218 | 219 | } 220 | 221 | } 222 | 223 | 224 | /** 225 | * 拖拽结束,放置 226 | * @param event 227 | */ 228 | private function dragDropHandler(event:DragEvent):void { 229 | if (event.dragSource.hasFormat("isOut")) { 230 | var hitNode:Node; 231 | 232 | for each(var node:Node in nodeList) { 233 | if (Tool.isOverHit(node)) { 234 | hitNode = node; 235 | break; 236 | } 237 | } 238 | 239 | if (hitNode) { 240 | var id = Tool.createUID(); 241 | addNode(id, {label: id.substr(0, 5)}, false) 242 | addEdge(hitNode.id, id) 243 | } 244 | } else if (event.dragSource.hasFormat("isIn")) { 245 | dragLine.visible = false; 246 | 247 | var hitNode:Node; 248 | 249 | for each(var node:Node in nodeList) { 250 | if (Tool.isOverHit(node)) { 251 | hitNode = node; 252 | break; 253 | } 254 | } 255 | 256 | if (hitNode) { 257 | var from:Node = event.dragSource.dataForFormat('isIn') as Node; 258 | var to:Node = hitNode; 259 | 260 | addEdge(from.id, to.id); 261 | } 262 | } 263 | } 264 | 265 | private function creationCompleteHandler(event:FlexEvent):void { 266 | dragLine = new Line(); 267 | addElement(dragLine); 268 | } 269 | ]]> 270 | 271 | -------------------------------------------------------------------------------- /flex/src/canvas/NullDragProxy.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /flex/src/components/ArrowLeft.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /flex/src/components/ArrowRight.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /flex/src/components/Line.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /flex/src/components/Node.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 56 | 57 | -------------------------------------------------------------------------------- /flex/src/components/NodeDragProxy.mxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /web/Main.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 29 | 30 | Main 31 | 32 | 33 | 39 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 77 | 78 | 79 | 83 |
84 |

85 | To view this page ensure that Adobe Flash Player version 86 | 16.0.0 or greater is installed. 87 |

88 | 93 |
94 | 95 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /web/Main.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruis/workflowcanvas/fce2572b1584c39a94554b125c4b3ca054a65aac/web/Main.swf -------------------------------------------------------------------------------- /web/expressInstall.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruis/workflowcanvas/fce2572b1584c39a94554b125c4b3ca054a65aac/web/expressInstall.swf -------------------------------------------------------------------------------- /web/history/history.css: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * contributor license agreements. See the NOTICE file distributed with 5 | * this work for additional information regarding copyright ownership. 6 | * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * (the "License"); you may not use this file except in compliance with 8 | * the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | */ 19 | /* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */ 20 | 21 | #ie_historyFrame { width: 0px; height: 0px; display:none } 22 | #firefox_anchorDiv { width: 0px; height: 0px; display:none } 23 | #safari_formDiv { width: 0px; height: 0px; display:none } 24 | #safari_rememberDiv { width: 0px; height: 0px; display:none } 25 | -------------------------------------------------------------------------------- /web/history/history.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one or more 4 | * contributor license agreements. See the NOTICE file distributed with 5 | * this work for additional information regarding copyright ownership. 6 | * The ASF licenses this file to You under the Apache License, Version 2.0 7 | * (the "License"); you may not use this file except in compliance with 8 | * the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | */ 19 | BrowserHistoryUtils = { 20 | addEvent: function(elm, evType, fn, useCapture) { 21 | useCapture = useCapture || false; 22 | if (elm.addEventListener) { 23 | elm.addEventListener(evType, fn, useCapture); 24 | return true; 25 | } 26 | else if (elm.attachEvent) { 27 | var r = elm.attachEvent('on' + evType, fn); 28 | return r; 29 | } 30 | else { 31 | elm['on' + evType] = fn; 32 | } 33 | } 34 | } 35 | 36 | BrowserHistory = (function() { 37 | // type of browser 38 | var browser = { 39 | ie: false, 40 | ie8: false, 41 | firefox: false, 42 | safari: false, 43 | opera: false, 44 | version: -1 45 | }; 46 | 47 | // Default app state URL to use when no fragment ID present 48 | var defaultHash = ''; 49 | 50 | // Last-known app state URL 51 | var currentHref = document.location.href; 52 | 53 | // Initial URL (used only by IE) 54 | var initialHref = document.location.href; 55 | 56 | // Initial URL (used only by IE) 57 | var initialHash = document.location.hash; 58 | 59 | // History frame source URL prefix (used only by IE) 60 | var historyFrameSourcePrefix = 'history/historyFrame.html?'; 61 | 62 | // History maintenance (used only by Safari) 63 | var currentHistoryLength = -1; 64 | 65 | // Flag to denote the existence of onhashchange 66 | var browserHasHashChange = false; 67 | 68 | var historyHash = []; 69 | 70 | var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash); 71 | 72 | var backStack = []; 73 | var forwardStack = []; 74 | 75 | var currentObjectId = null; 76 | 77 | //UserAgent detection 78 | var useragent = navigator.userAgent.toLowerCase(); 79 | 80 | if (useragent.indexOf("opera") != -1) { 81 | browser.opera = true; 82 | } else if (useragent.indexOf("msie") != -1) { 83 | browser.ie = true; 84 | browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4)); 85 | if (browser.version == 8) 86 | { 87 | browser.ie = false; 88 | browser.ie8 = true; 89 | } 90 | } else if (useragent.indexOf("safari") != -1) { 91 | browser.safari = true; 92 | browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7)); 93 | } else if (useragent.indexOf("gecko") != -1) { 94 | browser.firefox = true; 95 | } 96 | 97 | if (browser.ie == true && browser.version == 7) { 98 | window["_ie_firstload"] = false; 99 | } 100 | 101 | function hashChangeHandler() 102 | { 103 | currentHref = document.location.href; 104 | var flexAppUrl = getHash(); 105 | //ADR: to fix multiple 106 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 107 | var pl = getPlayers(); 108 | for (var i = 0; i < pl.length; i++) { 109 | pl[i].browserURLChange(flexAppUrl); 110 | } 111 | } else { 112 | getPlayer().browserURLChange(flexAppUrl); 113 | } 114 | } 115 | 116 | // Accessor functions for obtaining specific elements of the page. 117 | function getHistoryFrame() 118 | { 119 | return document.getElementById('ie_historyFrame'); 120 | } 121 | 122 | function getFormElement() 123 | { 124 | return document.getElementById('safari_formDiv'); 125 | } 126 | 127 | function getRememberElement() 128 | { 129 | return document.getElementById("safari_remember_field"); 130 | } 131 | 132 | // Get the Flash player object for performing ExternalInterface callbacks. 133 | // Updated for changes to SWFObject2. 134 | function getPlayer(id) { 135 | var i; 136 | 137 | if (id && document.getElementById(id)) { 138 | var r = document.getElementById(id); 139 | if (typeof r.SetVariable != "undefined") { 140 | return r; 141 | } 142 | else { 143 | var o = r.getElementsByTagName("object"); 144 | var e = r.getElementsByTagName("embed"); 145 | for (i = 0; i < o.length; i++) { 146 | if (typeof o[i].browserURLChange != "undefined") 147 | return o[i]; 148 | } 149 | for (i = 0; i < e.length; i++) { 150 | if (typeof e[i].browserURLChange != "undefined") 151 | return e[i]; 152 | } 153 | } 154 | } 155 | else { 156 | var o = document.getElementsByTagName("object"); 157 | var e = document.getElementsByTagName("embed"); 158 | for (i = 0; i < e.length; i++) { 159 | if (typeof e[i].browserURLChange != "undefined") 160 | { 161 | return e[i]; 162 | } 163 | } 164 | for (i = 0; i < o.length; i++) { 165 | if (typeof o[i].browserURLChange != "undefined") 166 | { 167 | return o[i]; 168 | } 169 | } 170 | } 171 | return undefined; 172 | } 173 | 174 | function getPlayers() { 175 | var i; 176 | var players = []; 177 | if (players.length == 0) { 178 | var tmp = document.getElementsByTagName('object'); 179 | for (i = 0; i < tmp.length; i++) 180 | { 181 | if (typeof tmp[i].browserURLChange != "undefined") 182 | players.push(tmp[i]); 183 | } 184 | } 185 | if (players.length == 0 || players[0].object == null) { 186 | var tmp = document.getElementsByTagName('embed'); 187 | for (i = 0; i < tmp.length; i++) 188 | { 189 | if (typeof tmp[i].browserURLChange != "undefined") 190 | players.push(tmp[i]); 191 | } 192 | } 193 | return players; 194 | } 195 | 196 | function getIframeHash() { 197 | var doc = getHistoryFrame().contentWindow.document; 198 | var hash = String(doc.location.search); 199 | if (hash.length == 1 && hash.charAt(0) == "?") { 200 | hash = ""; 201 | } 202 | else if (hash.length >= 2 && hash.charAt(0) == "?") { 203 | hash = hash.substring(1); 204 | } 205 | return hash; 206 | } 207 | 208 | /* Get the current location hash excluding the '#' symbol. */ 209 | function getHash() { 210 | // It would be nice if we could use document.location.hash here, 211 | // but it's faulty sometimes. 212 | var idx = document.location.href.indexOf('#'); 213 | return (idx >= 0) ? document.location.href.substr(idx+1) : ''; 214 | } 215 | 216 | /* Get the current location hash excluding the '#' symbol. */ 217 | function setHash(hash) { 218 | // It would be nice if we could use document.location.hash here, 219 | // but it's faulty sometimes. 220 | if (hash == '') hash = '#' 221 | document.location.hash = hash; 222 | } 223 | 224 | function createState(baseUrl, newUrl, flexAppUrl) { 225 | return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; 226 | } 227 | 228 | /* Add a history entry to the browser. 229 | * baseUrl: the portion of the location prior to the '#' 230 | * newUrl: the entire new URL, including '#' and following fragment 231 | * flexAppUrl: the portion of the location following the '#' only 232 | */ 233 | function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { 234 | 235 | //delete all the history entries 236 | forwardStack = []; 237 | 238 | if (browser.ie) { 239 | //Check to see if we are being asked to do a navigate for the first 240 | //history entry, and if so ignore, because it's coming from the creation 241 | //of the history iframe 242 | if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { 243 | currentHref = initialHref; 244 | return; 245 | } 246 | if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { 247 | newUrl = baseUrl + '#' + defaultHash; 248 | flexAppUrl = defaultHash; 249 | } else { 250 | // for IE, tell the history frame to go somewhere without a '#' 251 | // in order to get this entry into the browser history. 252 | getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; 253 | } 254 | setHash(flexAppUrl); 255 | } else { 256 | 257 | //ADR 258 | if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { 259 | initialState = createState(baseUrl, newUrl, flexAppUrl); 260 | } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { 261 | backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); 262 | } 263 | 264 | if (browser.safari && !browserHasHashChange) { 265 | // for Safari, submit a form whose action points to the desired URL 266 | if (browser.version <= 419.3) { 267 | var file = window.location.pathname.toString(); 268 | file = file.substring(file.lastIndexOf("/")+1); 269 | getFormElement().innerHTML = '
'; 270 | //get the current elements and add them to the form 271 | var qs = window.location.search.substring(1); 272 | var qs_arr = qs.split("&"); 273 | for (var i = 0; i < qs_arr.length; i++) { 274 | var tmp = qs_arr[i].split("="); 275 | var elem = document.createElement("input"); 276 | elem.type = "hidden"; 277 | elem.name = tmp[0]; 278 | elem.value = tmp[1]; 279 | document.forms.historyForm.appendChild(elem); 280 | } 281 | document.forms.historyForm.submit(); 282 | } else { 283 | top.location.hash = flexAppUrl; 284 | } 285 | // We also have to maintain the history by hand for Safari 286 | historyHash[history.length] = flexAppUrl; 287 | _storeStates(); 288 | } else { 289 | // Otherwise, just tell the browser to go there 290 | setHash(flexAppUrl); 291 | } 292 | } 293 | backStack.push(createState(baseUrl, newUrl, flexAppUrl)); 294 | } 295 | 296 | function _storeStates() { 297 | if (browser.safari) { 298 | getRememberElement().value = historyHash.join(","); 299 | } 300 | } 301 | 302 | function handleBackButton() { 303 | //The "current" page is always at the top of the history stack. 304 | var current = backStack.pop(); 305 | if (!current) { return; } 306 | var last = backStack[backStack.length - 1]; 307 | if (!last && backStack.length == 0){ 308 | last = initialState; 309 | } 310 | forwardStack.push(current); 311 | } 312 | 313 | function handleForwardButton() { 314 | //summary: private method. Do not call this directly. 315 | 316 | var last = forwardStack.pop(); 317 | if (!last) { return; } 318 | backStack.push(last); 319 | } 320 | 321 | function handleArbitraryUrl() { 322 | //delete all the history entries 323 | forwardStack = []; 324 | } 325 | 326 | /* Called periodically to poll to see if we need to detect navigation that has occurred */ 327 | function checkForUrlChange() { 328 | 329 | if (browser.ie) { 330 | if (currentHref != document.location.href && currentHref + '#' != document.location.href) { 331 | //This occurs when the user has navigated to a specific URL 332 | //within the app, and didn't use browser back/forward 333 | //IE seems to have a bug where it stops updating the URL it 334 | //shows the end-user at this point, but programatically it 335 | //appears to be correct. Do a full app reload to get around 336 | //this issue. 337 | if (browser.version < 7) { 338 | currentHref = document.location.href; 339 | document.location.reload(); 340 | } else { 341 | if (getHash() != getIframeHash()) { 342 | // this.iframe.src = this.blankURL + hash; 343 | var sourceToSet = historyFrameSourcePrefix + getHash(); 344 | getHistoryFrame().src = sourceToSet; 345 | currentHref = document.location.href; 346 | } 347 | } 348 | } 349 | } 350 | 351 | if (browser.safari && !browserHasHashChange) { 352 | // For Safari, we have to check to see if history.length changed. 353 | if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { 354 | //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); 355 | var flexAppUrl = getHash(); 356 | if (browser.version < 528.16 /* Anything earlier than Safari 4.0 */) 357 | { 358 | // If it did change and we're running Safari 3.x or earlier, 359 | // then we have to look the old state up in our hand-maintained 360 | // array since document.location.hash won't have changed, 361 | // then call back into BrowserManager. 362 | currentHistoryLength = history.length; 363 | flexAppUrl = historyHash[currentHistoryLength]; 364 | } 365 | 366 | //ADR: to fix multiple 367 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 368 | var pl = getPlayers(); 369 | for (var i = 0; i < pl.length; i++) { 370 | pl[i].browserURLChange(flexAppUrl); 371 | } 372 | } else { 373 | getPlayer().browserURLChange(flexAppUrl); 374 | } 375 | _storeStates(); 376 | } 377 | } 378 | if (browser.firefox && !browserHasHashChange) { 379 | if (currentHref != document.location.href) { 380 | var bsl = backStack.length; 381 | 382 | var urlActions = { 383 | back: false, 384 | forward: false, 385 | set: false 386 | } 387 | 388 | if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { 389 | urlActions.back = true; 390 | // FIXME: could this ever be a forward button? 391 | // we can't clear it because we still need to check for forwards. Ugg. 392 | // clearInterval(this.locationTimer); 393 | handleBackButton(); 394 | } 395 | 396 | // first check to see if we could have gone forward. We always halt on 397 | // a no-hash item. 398 | if (forwardStack.length > 0) { 399 | if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { 400 | urlActions.forward = true; 401 | handleForwardButton(); 402 | } 403 | } 404 | 405 | // ok, that didn't work, try someplace back in the history stack 406 | if ((bsl >= 2) && (backStack[bsl - 2])) { 407 | if (backStack[bsl - 2].flexAppUrl == getHash()) { 408 | urlActions.back = true; 409 | handleBackButton(); 410 | } 411 | } 412 | 413 | if (!urlActions.back && !urlActions.forward) { 414 | var foundInStacks = { 415 | back: -1, 416 | forward: -1 417 | } 418 | 419 | for (var i = 0; i < backStack.length; i++) { 420 | if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { 421 | arbitraryUrl = true; 422 | foundInStacks.back = i; 423 | } 424 | } 425 | for (var i = 0; i < forwardStack.length; i++) { 426 | if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { 427 | arbitraryUrl = true; 428 | foundInStacks.forward = i; 429 | } 430 | } 431 | handleArbitraryUrl(); 432 | } 433 | 434 | // Firefox changed; do a callback into BrowserManager to tell it. 435 | currentHref = document.location.href; 436 | var flexAppUrl = getHash(); 437 | //ADR: to fix multiple 438 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 439 | var pl = getPlayers(); 440 | for (var i = 0; i < pl.length; i++) { 441 | pl[i].browserURLChange(flexAppUrl); 442 | } 443 | } else { 444 | getPlayer().browserURLChange(flexAppUrl); 445 | } 446 | } 447 | } 448 | } 449 | 450 | var _initialize = function () { 451 | 452 | browserHasHashChange = ("onhashchange" in document.body); 453 | 454 | if (browser.ie) 455 | { 456 | var scripts = document.getElementsByTagName('script'); 457 | for (var i = 0, s; s = scripts[i]; i++) { 458 | if (s.src.indexOf("history.js") > -1) { 459 | var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); 460 | } 461 | } 462 | historyFrameSourcePrefix = iframe_location + "?"; 463 | var src = historyFrameSourcePrefix; 464 | 465 | var iframe = document.createElement("iframe"); 466 | iframe.id = 'ie_historyFrame'; 467 | iframe.name = 'ie_historyFrame'; 468 | iframe.src = 'javascript:false;'; 469 | 470 | try { 471 | document.body.appendChild(iframe); 472 | } catch(e) { 473 | setTimeout(function() { 474 | document.body.appendChild(iframe); 475 | }, 0); 476 | } 477 | } 478 | 479 | if (browser.safari && !browserHasHashChange) 480 | { 481 | var rememberDiv = document.createElement("div"); 482 | rememberDiv.id = 'safari_rememberDiv'; 483 | document.body.appendChild(rememberDiv); 484 | rememberDiv.innerHTML = ''; 485 | 486 | var formDiv = document.createElement("div"); 487 | formDiv.id = 'safari_formDiv'; 488 | document.body.appendChild(formDiv); 489 | 490 | var reloader_content = document.createElement('div'); 491 | reloader_content.id = 'safarireloader'; 492 | var scripts = document.getElementsByTagName('script'); 493 | for (var i = 0, s; s = scripts[i]; i++) { 494 | if (s.src.indexOf("history.js") > -1) { 495 | html = (new String(s.src)).replace(".js", ".html"); 496 | } 497 | } 498 | reloader_content.innerHTML = ''; 499 | document.body.appendChild(reloader_content); 500 | reloader_content.style.position = 'absolute'; 501 | reloader_content.style.left = reloader_content.style.top = '-9999px'; 502 | iframe = reloader_content.getElementsByTagName('iframe')[0]; 503 | 504 | if (document.getElementById("safari_remember_field").value != "" ) { 505 | historyHash = document.getElementById("safari_remember_field").value.split(","); 506 | } 507 | } 508 | 509 | if (browserHasHashChange) 510 | document.body.onhashchange = hashChangeHandler; 511 | } 512 | 513 | return { 514 | historyHash: historyHash, 515 | backStack: function() { return backStack; }, 516 | forwardStack: function() { return forwardStack }, 517 | getPlayer: getPlayer, 518 | initialize: function(src) { 519 | _initialize(src); 520 | }, 521 | setURL: function(url) { 522 | document.location.href = url; 523 | }, 524 | getURL: function() { 525 | return document.location.href; 526 | }, 527 | getTitle: function() { 528 | return document.title; 529 | }, 530 | setTitle: function(title) { 531 | try { 532 | backStack[backStack.length - 1].title = title; 533 | } catch(e) { } 534 | //if on safari, set the title to be the empty string. 535 | if (browser.safari) { 536 | if (title == "") { 537 | try { 538 | var tmp = window.location.href.toString(); 539 | title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); 540 | } catch(e) { 541 | title = ""; 542 | } 543 | } 544 | } 545 | document.title = title; 546 | }, 547 | setDefaultURL: function(def) 548 | { 549 | defaultHash = def; 550 | def = getHash(); 551 | //trailing ? is important else an extra frame gets added to the history 552 | //when navigating back to the first page. Alternatively could check 553 | //in history frame navigation to compare # and ?. 554 | if (browser.ie) 555 | { 556 | window['_ie_firstload'] = true; 557 | var sourceToSet = historyFrameSourcePrefix + def; 558 | var func = function() { 559 | getHistoryFrame().src = sourceToSet; 560 | window.location.replace("#" + def); 561 | setInterval(checkForUrlChange, 50); 562 | } 563 | try { 564 | func(); 565 | } catch(e) { 566 | window.setTimeout(function() { func(); }, 0); 567 | } 568 | } 569 | 570 | if (browser.safari) 571 | { 572 | currentHistoryLength = history.length; 573 | if (historyHash.length == 0) { 574 | historyHash[currentHistoryLength] = def; 575 | var newloc = "#" + def; 576 | window.location.replace(newloc); 577 | } else { 578 | //alert(historyHash[historyHash.length-1]); 579 | } 580 | setInterval(checkForUrlChange, 50); 581 | } 582 | 583 | 584 | if (browser.firefox || browser.opera) 585 | { 586 | var reg = new RegExp("#" + def + "$"); 587 | if (window.location.toString().match(reg)) { 588 | } else { 589 | var newloc ="#" + def; 590 | window.location.replace(newloc); 591 | } 592 | setInterval(checkForUrlChange, 50); 593 | } 594 | 595 | }, 596 | 597 | /* Set the current browser URL; called from inside BrowserManager to propagate 598 | * the application state out to the container. 599 | */ 600 | setBrowserURL: function(flexAppUrl, objectId) { 601 | if (browser.ie && typeof objectId != "undefined") { 602 | currentObjectId = objectId; 603 | } 604 | //fromIframe = fromIframe || false; 605 | //fromFlex = fromFlex || false; 606 | //alert("setBrowserURL: " + flexAppUrl); 607 | //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; 608 | 609 | var pos = document.location.href.indexOf('#'); 610 | var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; 611 | var newUrl = baseUrl + '#' + flexAppUrl; 612 | 613 | if (document.location.href != newUrl && document.location.href + '#' != newUrl) { 614 | currentHref = newUrl; 615 | addHistoryEntry(baseUrl, newUrl, flexAppUrl); 616 | currentHistoryLength = history.length; 617 | } 618 | }, 619 | 620 | browserURLChange: function(flexAppUrl) { 621 | var objectId = null; 622 | if (browser.ie && currentObjectId != null) { 623 | objectId = currentObjectId; 624 | } 625 | 626 | if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { 627 | var pl = getPlayers(); 628 | for (var i = 0; i < pl.length; i++) { 629 | try { 630 | pl[i].browserURLChange(flexAppUrl); 631 | } catch(e) { } 632 | } 633 | } else { 634 | try { 635 | getPlayer(objectId).browserURLChange(flexAppUrl); 636 | } catch(e) { } 637 | } 638 | 639 | currentObjectId = null; 640 | }, 641 | getUserAgent: function() { 642 | return navigator.userAgent; 643 | }, 644 | getPlatform: function() { 645 | return navigator.platform; 646 | } 647 | 648 | } 649 | 650 | })(); 651 | 652 | // Initialization 653 | 654 | // Automated unit testing and other diagnostics 655 | 656 | function setURL(url) 657 | { 658 | document.location.href = url; 659 | } 660 | 661 | function backButton() 662 | { 663 | history.back(); 664 | } 665 | 666 | function forwardButton() 667 | { 668 | history.forward(); 669 | } 670 | 671 | function goForwardOrBackInHistory(step) 672 | { 673 | history.go(step); 674 | } 675 | 676 | //BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); 677 | (function(i) { 678 | var u =navigator.userAgent;var e=/*@cc_on!@*/false; 679 | var st = setTimeout; 680 | if(/webkit/i.test(u)){ 681 | st(function(){ 682 | var dr=document.readyState; 683 | if(dr=="loaded"||dr=="complete"){i()} 684 | else{st(arguments.callee,10);}},10); 685 | } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ 686 | document.addEventListener("DOMContentLoaded",i,false); 687 | } else if(e){ 688 | (function(){ 689 | var t=document.createElement('doc:rdy'); 690 | try{t.doScroll('left'); 691 | i();t=null; 692 | }catch(e){st(arguments.callee,0);}})(); 693 | } else{ 694 | window.onload=i; 695 | } 696 | })( function() {BrowserHistory.initialize();} ); 697 | -------------------------------------------------------------------------------- /web/history/historyFrame.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 43 | Hidden frame for Browser History support. 44 | 45 | 46 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 17 | 19 | 20 | 21 | 30 | 31 | Main 32 | 33 | 34 | 40 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 92 | 93 | 94 | 95 | 99 |
100 |

101 | To view this page ensure that Adobe Flash Player version 102 | 16.0.0 or greater is installed. 103 |

104 | 109 |
110 | 111 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /web/script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liurui on 15/8/14. 3 | */ 4 | var g = new dagre.graphlib.Graph(); 5 | 6 | // Set an object for the graph label 7 | 8 | var graph = {}; 9 | graph.rankdir = "LR"; 10 | graph.ranksep = 120; 11 | graph.marginy = 50; 12 | g.setGraph(graph); 13 | 14 | // Default to assigning a new object as a label for each new edge. 15 | g.setDefaultEdgeLabel(function () { 16 | return {}; 17 | }); 18 | 19 | function setNode(key, obj) { 20 | g.setNode(key, obj) 21 | } 22 | 23 | function setEdge(a, b, o) { 24 | g.setEdge(a, b, o); 25 | } 26 | 27 | function layoutNode() { 28 | dagre.layout(g); 29 | } 30 | 31 | function getNodes() { 32 | return g.nodes().map(function (v) { 33 | var r = g.node(v) 34 | r.id = v 35 | return r 36 | }) 37 | } 38 | 39 | function getEdges() { 40 | return g.edges().map(function (v) { 41 | return g.edge(v) 42 | }) 43 | 44 | //return g.edges() 45 | } 46 | 47 | var _value; 48 | function setInt(value) { 49 | if (value == null) 50 | _value = 0; 51 | else 52 | _value = value; 53 | 54 | 55 | _value = value == null ? 0 : value; 56 | 57 | _value = value||0; 58 | } -------------------------------------------------------------------------------- /web/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /web/wf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aruis/workflowcanvas/fce2572b1584c39a94554b125c4b3ca054a65aac/web/wf.gif --------------------------------------------------------------------------------