ruote-kit 2.2.0.3 → 2.3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG.txt +28 -1
  2. data/CREDITS.txt +8 -2
  3. data/LICENSE.txt +1 -1
  4. data/Rakefile +21 -9
  5. data/lib/ruote-kit.rb +13 -4
  6. data/lib/ruote-kit/core_ext.rb +15 -0
  7. data/lib/ruote-kit/helpers/json_helpers.rb +22 -7
  8. data/lib/ruote-kit/helpers/link_helpers.rb +9 -7
  9. data/lib/ruote-kit/helpers/pagination_helpers.rb +1 -2
  10. data/lib/ruote-kit/helpers/render_helpers.rb +1 -1
  11. data/lib/ruote-kit/public/_ruote/images/favicon.png +0 -0
  12. data/lib/ruote-kit/public/_ruote/images/{ruote_buttons.png → ruote-buttons.png} +0 -0
  13. data/lib/ruote-kit/public/_ruote/images/ruote.png +0 -0
  14. data/lib/ruote-kit/public/_ruote/javascripts/foolbox-all.min.js +3 -0
  15. data/lib/ruote-kit/public/_ruote/javascripts/jquery-1.9.1.min.js +5 -0
  16. data/lib/ruote-kit/public/_ruote/javascripts/rk.js +68 -17
  17. data/lib/ruote-kit/public/_ruote/javascripts/ruote-fluo-all.min.js +3 -0
  18. data/lib/ruote-kit/public/_ruote/stylesheets/rk.css +82 -12
  19. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-buttons.png +0 -0
  20. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-fluo-editor.css +9 -6
  21. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-fluo.css +62 -0
  22. data/lib/ruote-kit/resources/errors.rb +8 -3
  23. data/lib/ruote-kit/resources/expressions.rb +38 -35
  24. data/lib/ruote-kit/resources/participants.rb +1 -1
  25. data/lib/ruote-kit/resources/processes.rb +61 -4
  26. data/lib/ruote-kit/resources/workitems.rb +4 -4
  27. data/lib/ruote-kit/version.rb +1 -1
  28. data/lib/ruote-kit/views/_pagination.html.haml +2 -2
  29. data/lib/ruote-kit/views/_tree_editor.html.haml +63 -30
  30. data/lib/ruote-kit/views/error.html.haml +50 -9
  31. data/lib/ruote-kit/views/errors.html.haml +1 -1
  32. data/lib/ruote-kit/views/expression.html.haml +83 -33
  33. data/lib/ruote-kit/views/expressions.html.haml +23 -8
  34. data/lib/ruote-kit/views/http_error.html.haml +9 -2
  35. data/lib/ruote-kit/views/layout.html.haml +14 -13
  36. data/lib/ruote-kit/views/process.html.haml +75 -20
  37. data/lib/ruote-kit/views/processes.html.haml +9 -3
  38. data/lib/ruote-kit/views/processes_new.html.haml +19 -2
  39. data/lib/ruote-kit/views/schedules.html.haml +2 -2
  40. data/lib/ruote-kit/views/workitem.html.haml +17 -6
  41. data/ruote-kit.gemspec +9 -7
  42. data/spec/cases/orphan_workitem_spec.rb +141 -0
  43. data/spec/core_ext_spec.rb +19 -0
  44. data/spec/resources/errors_spec.rb +182 -156
  45. data/spec/resources/expressions_spec.rb +497 -379
  46. data/spec/resources/index_spec.rb +5 -5
  47. data/spec/resources/participants_spec.rb +64 -75
  48. data/spec/resources/processes_spec.rb +396 -277
  49. data/spec/resources/schedules_spec.rb +92 -76
  50. data/spec/resources/workitems_spec.rb +352 -343
  51. data/spec/ruote-kit_configure_spec.rb +41 -13
  52. data/spec/spec_helper.rb +6 -8
  53. data/spec/support/link_helper.rb +11 -0
  54. data/spec/webapp_helpers_spec.rb +29 -23
  55. metadata +161 -180
  56. data/README.rdoc +0 -313
  57. data/lib/ruote-kit/public/_ruote/images/favicon.ico +0 -0
  58. data/lib/ruote-kit/public/_ruote/javascripts/jquery-1.4.2.min.js +0 -154
  59. data/lib/ruote-kit/public/_ruote/javascripts/ruote-fluo-editor.js +0 -548
  60. data/lib/ruote-kit/public/_ruote/javascripts/ruote-fluo.js +0 -1118
@@ -1,1118 +0,0 @@
1
-
2
- /*
3
- * Ruote - open source ruby workflow engine
4
- * (c) 2005-2010 jmettraux@gmail.com
5
- *
6
- * Ruote is freely distributable under the terms of the MIT license.
7
- * For details, see the ruote web site: http://ruote.rubyforge.org
8
- *
9
- * Made in Japan
10
- *
11
- * John Mettraux
12
- * Juan-Pedro Paredes
13
- */
14
-
15
- //function dinspect (o) {
16
- // var s = "[\n";
17
- // for (var k in o) {
18
- // s += ("" + k + ": " + o[k]);
19
- // s += ",\n";
20
- // }
21
- // s += "]";
22
- // return s;
23
- //}
24
-
25
- var FluoConstants = {
26
-
27
- WHITE: 'rgb(255, 255, 255)',
28
- HIGHLIGHT: 'rgb(220, 220, 220)',
29
- LINE_HEIGHT: 20,
30
- MIN_ACTIVITY_WIDTH: 110,
31
- FONT: '12px Helvetica Neue'
32
- }
33
-
34
- var FluoCanvas = function () {
35
-
36
- //
37
- // draws centered text
38
- //
39
- function drawText (c, text, bwidth, bheight, symbolFuncName) {
40
-
41
- var SW = 17; // symbol width
42
-
43
- c.save();
44
-
45
- if (c.canvas.horizontal == true) {
46
- c.translate(bwidth/2, bheight/2);
47
- c.rotate(Math.PI/2);
48
- }
49
- var w1 = c.measure(text);
50
- var w0 = 0;
51
- if (symbolFuncName) w0 = SW;
52
- var w = w0 + w1;
53
- c.translate(-(w/2), 17);
54
- if (symbolFuncName) {
55
- c.translate(0, -4);
56
- FluoCanvas[symbolFuncName](c, SW);
57
- c.translate(0, 4);
58
- }
59
- c.translate(w0, 0);
60
- c.write(text);
61
- c.translate(+(w/2-w0), -17);
62
-
63
- c.restore();
64
- }
65
-
66
- function drawArrow (c, length) {
67
- var w = 3;
68
- c.beginPath();
69
- c.moveTo(0, 0);
70
- c.lineTo(0, length);
71
- c.stroke();
72
- c.beginPath();
73
- c.moveTo(0, length);
74
- c.lineTo(-w, length-w*2);
75
- c.lineTo(w, length-w*2);
76
- c.lineTo(0, length);
77
- c.fill();
78
- }
79
-
80
- function drawVerticalLine (c, x, height) {
81
- c.beginPath();
82
- c.moveTo(x, 0);
83
- c.lineTo(x, height);
84
- c.stroke();
85
- }
86
-
87
- function drawRoundedRect (c, width, height, radius) {
88
- var w2 = width / 2;
89
- c.beginPath();
90
- c.moveTo(0, 0);
91
- c.lineTo(w2 - radius, 0);
92
- c.quadraticCurveTo(w2, 0, w2, radius);
93
- c.lineTo(w2, height - radius);
94
- c.quadraticCurveTo(w2, height, w2 - radius, height);
95
- c.lineTo(-w2 + radius, height);
96
- c.quadraticCurveTo(-w2, height, -w2, height - radius);
97
- c.lineTo(-w2, radius);
98
- c.quadraticCurveTo(-w2, 0, -w2 + radius, 0);
99
- c.lineTo(0, 0);
100
- c.stroke();
101
- }
102
-
103
- function drawQuadraticPath (c, x, y, radius) {
104
- var xradius = radius;
105
- if (x < 0) xradius = -radius;
106
- var yradius = radius;
107
- if (y < 0) yradius = -radius;
108
- c.beginPath();
109
- c.moveTo(0, 0);
110
- c.lineTo(x - xradius, 0);
111
- c.quadraticCurveTo(x, 0, x, yradius);
112
- c.lineTo(x, y);
113
- c.stroke();
114
- }
115
-
116
- function drawDiamond (c, height) {
117
- var h = height / 2;
118
- for (var i = 0; i < 2; i++) {
119
- c.beginPath();
120
- c.moveTo(0, 0);
121
- c.lineTo(h, h);
122
- c.lineTo(0, height);
123
- c.lineTo(-h, h);
124
- c.lineTo(0, 0);
125
- if (i == 0) {
126
- c.save();
127
- c.fillStyle = FluoConstants.WHITE;
128
- c.fill();
129
- c.restore();
130
- }
131
- else {
132
- c.stroke();
133
- }
134
- }
135
- }
136
-
137
- function drawThickCircle (c, height) {
138
- c.save();
139
- c.beginPath();
140
- c.lineWidth = 1.4;
141
- c.fillStyle = FluoConstants.WHITE;
142
- c.arc(0, 0, height / 2 - 1, 0, Math.PI * 2, true);
143
- c.arc(0, 0, height / 2 - 2.3, 0, Math.PI * 2, true);
144
- c.stroke();
145
- c.restore();
146
- }
147
-
148
- function drawDoubleCircle (c, height, arrow) {
149
- c.save();
150
- c.beginPath();
151
- c.lineWidth = 0.5;
152
- c.fillStyle = FluoConstants.WHITE;
153
- c.arc(0, 0, height / 2, 0, Math.PI * 2, true);
154
- c.arc(0, 0, height / 2 - 2.3, 0, Math.PI * 2, true);
155
- c.stroke();
156
- c.restore();
157
- if (arrow) {
158
- c.save();
159
- c.translate(height/2, 0);
160
- c.rotate(-Math.PI/2);
161
- drawArrow(c, 8);
162
- c.restore();
163
- }
164
- }
165
-
166
- function drawError (c, height, sym) { // the flash
167
- if (sym) drawThickCircle(c, height);
168
- else drawDoubleCircle(c, height, true);
169
- var h = height / 2 * 0.8;
170
- var o = Math.cos(Math.PI / 4) * h;
171
- var h2 = h / 2 * 0.5;
172
- var d = h2 * 0.7;
173
- c.beginPath();
174
- c.moveTo(o, -o);
175
- c.lineTo(h2 + d, h2 + d);
176
- c.lineTo(-h2, -h2 + d);
177
- c.lineTo(-o, o);
178
- c.lineTo(-h2 - d, -h2 - d);
179
- c.lineTo(h2, h2 - d);
180
- c.lineTo(o, -o);
181
- c.fill();
182
- }
183
- function drawErrorSymbol (c, height) {
184
- drawError(c, height, true);
185
- }
186
-
187
- function drawCancel (c, height) { // the 'dame'
188
- drawDoubleCircle(c, height, true);
189
- var h = height / 5;
190
- c.beginPath();
191
- c.lineWidth = 2;
192
- c.moveTo(h, h);
193
- c.lineTo(-h, -h);
194
- c.moveTo(-h, h);
195
- c.lineTo(h, -h);
196
- c.stroke();
197
- }
198
-
199
- function pointOnCircle (angle, radius) {
200
- return [ Math.cos(angle) * radius, Math.sin(angle) * radius ];
201
- }
202
- function lineInCircle (c, angle, farRadius, closeRadius) {
203
- var far = pointOnCircle(angle, farRadius);
204
- var close = pointOnCircle(angle, closeRadius);
205
- c.moveTo(far[0], far[1]); c.lineTo(close[0], close[1]);
206
- }
207
-
208
- function drawWaitSymbol (c, height) { // the 'clock'
209
- drawDoubleCircle(c, height, false);
210
- c.save();
211
- c.beginPath();
212
- c.lineWidth = 0.5;
213
- var radius = height / 2 - 4.3;
214
- c.arc(0, 0, radius, 0, Math.PI * 2, true);
215
- for (var i = 0; i < 12; i++) {
216
- lineInCircle(c, Math.PI / 6 * i, radius, radius - 2);
217
- }
218
- lineInCircle(c, Math.PI / 6 * 9.5, radius - 1, 0); // minutes
219
- lineInCircle(c, Math.PI / 6 * 0, radius - 3, 0); // hours
220
- c.stroke();
221
- c.restore();
222
- }
223
-
224
- function drawParaDiamond (c, height) {
225
- drawDiamond(c, height);
226
- c.save();
227
- c.lineWidth = 2.5;
228
- var l = height / 4;
229
- c.beginPath();
230
- c.moveTo(0, l); c.lineTo(0, l * 3);
231
- c.moveTo(-l, l * 2); c.lineTo(l, l * 2);
232
- c.stroke();
233
- c.restore();
234
- }
235
-
236
- function drawCrossInABox (c, h) {
237
- c.save();
238
- c.beginPath();
239
- c.moveTo(-6, h);
240
- c.lineTo(-6, h - 12);
241
- c.lineTo(6, h - 12);
242
- c.lineTo(6, h);
243
- c.moveTo(0, h - 10);
244
- c.lineTo(0, h - 2);
245
- c.moveTo(-4, h - 6);
246
- c.lineTo(4, h - 6);
247
- c.stroke();
248
- c.restore();
249
- }
250
-
251
- function drawLoopSymbol (c, h) {
252
- var r = 5;
253
- c.save();
254
- c.lineWidth = 0.9;
255
- c.translate(0, h - r - 4);
256
- c.beginPath();
257
- var a = Math.PI / 2;
258
- c.arc(0, 0, r, a - 0.5, a, true);
259
- var l = r * 0.8;
260
- c.moveTo(0, r + 1);
261
- c.lineTo(-l, r + 1);
262
- c.moveTo(0, r + 1);
263
- c.lineTo(0, r - l);
264
- c.stroke();
265
- c.restore();
266
- }
267
-
268
- function drawParaSymbol (c, h) {
269
- c.save();
270
- c.translate(0, h - 10);
271
- c.lineWidth = 1.5;
272
- c.beginPath();
273
- c.moveTo(-2, 0); c.lineTo(-2, 8);
274
- c.moveTo(2, 0); c.lineTo(2, 8);
275
- c.stroke();
276
- c.restore();
277
- }
278
-
279
- return {
280
- drawText: drawText,
281
- drawArrow: drawArrow,
282
- drawVerticalLine: drawVerticalLine,
283
- drawRoundedRect: drawRoundedRect,
284
- drawQuadraticPath: drawQuadraticPath,
285
- drawDiamond: drawDiamond,
286
- drawParaDiamond: drawParaDiamond,
287
- drawError: drawError,
288
- drawCancel: drawCancel,
289
- drawCrossInABox: drawCrossInABox,
290
- drawLoopSymbol: drawLoopSymbol,
291
- drawParaSymbol: drawParaSymbol,
292
- draw_error_symbol: drawErrorSymbol,
293
- draw_sleep_symbol: drawWaitSymbol,
294
- draw_wait_symbol: drawWaitSymbol
295
- };
296
- }();
297
-
298
- var Fluo = function () {
299
-
300
- //
301
- // MISC METHODS
302
-
303
- function childrenMax (c, exp, funcname) {
304
- var children = getChildren(c, exp);
305
- var max = 0;
306
- for (var i = 0; i < children.length; i++) {
307
- var val = Fluo[funcname](c, children[i]);
308
- if (val > max) max = val;
309
- }
310
- return max;
311
- }
312
-
313
- function childrenSum (c, exp, funcname) {
314
- var children = getChildren(c, exp);
315
- var sum = 0;
316
- for (var i = 0; i < children.length; i++) {
317
- sum += Fluo[funcname](c, children[i]);
318
- }
319
- return sum;
320
- }
321
-
322
- function attributeMaxWidth (c, exp, title) {
323
- var max = 0;
324
- if (title) max = c.measure(title);
325
- for (var attname in exp[1]) {
326
- var text = '' + attname + ': ' + JSON.stringify(exp[1][attname]);
327
- var l = c.measure(text);
328
- //if (attname.match(/^on[-\_](error|cancel)$/)) l += 30;
329
- if (l > max) max = l;
330
- }
331
- return max;
332
- }
333
-
334
- // returns the list of attribute names (sorted)
335
- //
336
- function attributeNames (exp) {
337
- var an = [];
338
- for (var k in exp[1]) { an.push(k); }
339
- return an.sort();
340
- }
341
-
342
- function attributeCount (exp) {
343
- //var l = attributeNames(exp).length;
344
- //var ct = strchild && childText(exp);
345
- //return l + (ct ? 1 : 0);
346
- return attributeNames(exp).length;
347
- }
348
-
349
- function carriageReturn (c) {
350
- if (c.canvas.horizontal == true) {
351
- c.translate(-FluoConstants.LINE_HEIGHT, 0);
352
- }
353
- else c.translate(0, FluoConstants.LINE_HEIGHT);
354
- }
355
-
356
- function drawAttributes (c, exp, expname, namePlus, width, height) {
357
-
358
- if (expname) {
359
- FluoCanvas.drawText(c, exp[0], width, height);
360
- carriageReturn(c);
361
- }
362
-
363
- var attname;
364
- var attnames = attributeNames(exp, expname);
365
-
366
- while (attname = attnames.shift()) {
367
-
368
- var v = JSON.stringify(exp[1][attname]);
369
-
370
- if (attname.match(/^on[-\_]error$/)) {
371
- FluoCanvas.drawText(c, v, width, height, 'drawError');
372
- carriageReturn(c);
373
- }
374
- else if (attname.match(/^on[-\_]cancel$/)) {
375
- FluoCanvas.drawText(c, v, width, height, 'drawCancel');
376
- carriageReturn(c);
377
- }
378
- else {
379
- var t = attname;
380
- if (v != 'null') t = t + ': ' + v;
381
- FluoCanvas.drawText(c, t, width, height);
382
- carriageReturn(c);
383
- }
384
- }
385
- }
386
-
387
- //
388
- // the methods (and fields) shared by all handler are here
389
- //
390
- var Handler = {};
391
- Handler.getHeight = function (c, exp) {
392
- if (c.canvas.horizontal == true) return this.getRealWidth(c, exp);
393
- return this.getRealHeight(c, exp);
394
- };
395
- Handler.getWidth = function (c, exp) {
396
- if (c.canvas.horizontal == true) return this.getRealHeight(c, exp);
397
- return this.getRealWidth(c, exp);
398
- };
399
-
400
- //
401
- // creates a new Handler (a copy of Handler), if the parentHandler is
402
- // given, will spawn a copy of it instead of a copy of Handler.
403
- // (dead simple inheritance).
404
- //
405
- function newHandler (parentHandler) {
406
- if ( ! parentHandler) parentHandler = Handler;
407
- var result = {};
408
- for (var k in parentHandler) result[k] = parentHandler[k];
409
- for (var k in parentHandler) result['super_'+k] = parentHandler[k];
410
- return result;
411
- }
412
-
413
- function getChildren (c, exp) {
414
- var cs = exp[2];
415
- if ( ! c.canvas.hideMinor) return cs;
416
- if (exp.majorChildren) return exp.majorChildren;
417
- var r = [];
418
- for (var i = 0; i < cs.length; i++) {
419
- var c = cs[i];
420
- if (MINORS.indexOf(c[0]) < 0) r.push(c);
421
- }
422
- exp.majorChildren = r; // caching the result
423
- return r;
424
- }
425
-
426
- //
427
- // EXPRESSION HANDLERS
428
-
429
- var GenericHandler = newHandler();
430
- GenericHandler.adjust = function (exp) {
431
- //var ct = childText(exp);
432
- //if (ct) exp[0] = exp[0] + ' ' + ct;
433
- }
434
- GenericHandler.render = function (c, exp) {
435
- var width = this.getWidth(c, exp);
436
- var height = this.getHeight(c, exp);
437
- FluoCanvas.drawRoundedRect(c, width, height, 8);
438
- c.save();
439
- drawAttributes(c, exp, true, false, width, height);
440
- c.restore();
441
- };
442
- GenericHandler.getRealHeight = function (c, exp) {
443
- return 7 + (1 + attributeCount(exp)) * FluoConstants.LINE_HEIGHT;
444
- };
445
- GenericHandler.getRealWidth = function (c, exp) {
446
- return Math.max(10 + attributeMaxWidth(c, exp, exp[0]), FluoConstants.MIN_ACTIVITY_WIDTH);
447
- };
448
-
449
- var AttributeOnlyHandler = newHandler();
450
- AttributeOnlyHandler.adjust = function (exp) {
451
- //var ct = childText(exp);
452
- //if (ct) exp[0] = exp[0] + ' ' + ct;
453
- }
454
- AttributeOnlyHandler.render = function (c, exp) {
455
- var width = this.getWidth(c, exp);
456
- var height = this.getHeight(c, exp);
457
- c.save();
458
- drawAttributes(c, exp, false, false, width, height);
459
- c.restore();
460
- };
461
- AttributeOnlyHandler.getRealHeight = function (c, exp) {
462
- return 7 + attributeCount(exp) * FluoConstants.LINE_HEIGHT;
463
- };
464
- AttributeOnlyHandler.getRealWidth = function (c, exp) {
465
- return attributeMaxWidth(c, exp, exp[0]);
466
- };
467
-
468
- var SubprocessHandler = newHandler(GenericHandler);
469
- SubprocessHandler.adjust = function (exp) {
470
- if (exp[2].length == 1) exp[1]['ref'] = exp[2][0];
471
- }
472
- SubprocessHandler.render = function (c, exp) {
473
- var width = this.getWidth(c, exp);
474
- var height = this.getHeight(c, exp);
475
- FluoCanvas.drawRoundedRect(c, width, height, 8);
476
- c.save();
477
- drawAttributes(c, exp, true, false, width, height);
478
- c.restore();
479
- FluoCanvas.drawCrossInABox(c, height);
480
- };
481
- SubprocessHandler.getRealHeight = function (c, exp) {
482
- return 12 + 7 + (1 + attributeCount(exp)) * FluoConstants.LINE_HEIGHT;
483
- };
484
-
485
-
486
- // TODO : fix rotated mode
487
- //
488
- var GenericWithChildrenHandler = newHandler();
489
- GenericWithChildrenHandler.render = function (c, exp) {
490
- var width = this.getWidth(c, exp);
491
- var height = this.getHeight(c, exp);
492
- var attWidth = attributeMaxWidth(c, exp, exp[0]) + 7;
493
- var attHeight = attributeCount(exp) * FluoConstants.LINE_HEIGHT;
494
- var children = getChildren(c, exp);
495
- if (c.canvas.horizontal == true) {
496
- var w = attWidth;
497
- attWidth = attHeight;
498
- attHeight = w;
499
- }
500
- if ((c.canvas.noOuterBorder != true) || (exp.expid != "0")) {
501
- FluoCanvas.drawRoundedRect(c, width, height, 8);
502
- }
503
- c.save();
504
- c.translate(-width/2 + attWidth/2 + 5 , 7);
505
- if (c.canvas.horizontal == true) c.translate(attHeight/2, 0);
506
- drawAttributes(c, exp, true, false, attWidth, attHeight);
507
- c.restore();
508
- c.save();
509
- c.translate(width/2 - childrenMax(c, exp, 'getWidth')/2 - 7, 8);
510
- for (var i = 0; i < children.length; i++) {
511
- var child = children[i];
512
- renderExp(c, child);
513
- c.translate(0, Fluo.getHeight(c, child));
514
- if (this.drawArrow && i < children.length -1) FluoCanvas.drawArrow(c, 10);
515
- c.translate(0, 10);
516
- }
517
- c.restore();
518
- };
519
- GenericWithChildrenHandler.drawArrow = false;
520
- GenericWithChildrenHandler.getHeight = function (c, exp) {
521
- var rightHeight =
522
- (getChildren(c, exp).length + 1) * 9 + childrenSum(c, exp, 'getHeight');
523
- var leftHeight =
524
- GenericHandler.getHeight(c, exp);
525
- return (rightHeight > leftHeight) ? rightHeight : leftHeight;
526
- };
527
- GenericWithChildrenHandler.getWidth = function (c, exp) {
528
- return(
529
- attributeMaxWidth(c, exp, exp[0]) +
530
- 28 +
531
- childrenMax(c, exp, 'getWidth'));
532
- };
533
-
534
- var LoopHandler = newHandler(GenericWithChildrenHandler);
535
- LoopHandler.drawArrow = true;
536
- LoopHandler.render = function (c, exp) {
537
- this.super_render(c, exp);
538
- FluoCanvas.drawLoopSymbol(c, this.getHeight(c, exp));
539
- }
540
- LoopHandler.getHeight = function (c, exp) {
541
- return 12 + this.super_getHeight(c, exp);
542
- }
543
-
544
- var ConcurrentIteratorHandler = newHandler(GenericWithChildrenHandler);
545
- ConcurrentIteratorHandler.render = function (c, exp) {
546
- this.super_render(c, exp);
547
- FluoCanvas.drawParaSymbol(c, this.getHeight(c, exp));
548
- }
549
- ConcurrentIteratorHandler.getHeight = function (c, exp) {
550
- return 12 + this.super_getHeight(c, exp);
551
- }
552
-
553
-
554
- // TODO : fix in rotated mode
555
- //
556
- var TextHandler = newHandler();
557
- TextHandler.render = function (c, exp) {
558
- var h = getHeight(c, exp);
559
- var w = getWidth(c, exp);
560
- FluoCanvas.drawText(c, this.getText(exp), h, w);
561
- };
562
- TextHandler.getText = function (exp) {
563
- var t = exp[0];
564
- //var ct = childText(exp); if (ct) t += (' ' + ct);
565
- for (var attname in exp[1]) {
566
- var v = exp[1][attname];
567
- t += (' ' + attname + ': "' + v + '"');
568
- }
569
- return t;
570
- };
571
- TextHandler.getRealHeight = function (c, exp) {
572
- return FluoConstants.LINE_HEIGHT;
573
- };
574
- TextHandler.getRealWidth = function (c, exp) {
575
- return c.measure(this.getText(exp));
576
- };
577
-
578
- // TODO : fix rotated mode
579
- //
580
- var SymbolHandler = newHandler();
581
- SymbolHandler.SYMBOL_HEIGHT = 22;
582
- SymbolHandler.render = function (c, exp) {
583
- var w = this.getWidth(c, exp);
584
- var h = this.getHeight(c, exp);
585
- c.save();
586
- if (c.canvas.horizontal == true) {
587
- c.translate(w/2, h/2);
588
- c.rotate(-Math.PI/2);
589
- }
590
- c.translate(0, 12);
591
- FluoCanvas['draw_'+exp[0]+'_symbol'](c, SymbolHandler.SYMBOL_HEIGHT);
592
- c.translate(0, 12);
593
- drawAttributes(c, exp, false, true, this.getWidth(c, exp), this.getHeight(c, exp));
594
- c.restore();
595
- };
596
- SymbolHandler.getRealHeight = function (c, exp) {
597
- return attributeCount(exp) * FluoConstants.LINE_HEIGHT + SymbolHandler.SYMBOL_HEIGHT;
598
- };
599
- SymbolHandler.getRealWidth = function (c, exp) {
600
- return attributeMaxWidth(c, exp, exp[0]);
601
- };
602
-
603
- var StringHandler = newHandler(TextHandler);
604
- StringHandler.getText = function (exp) {
605
- return exp;
606
- };
607
-
608
- var VerticalHandler = newHandler();
609
- VerticalHandler.adjust = function (exp) {
610
- //if (attributeCount(exp) > 0) exp[2].unshift([ '_atts_', exp[1], [] ]);
611
- }
612
- VerticalHandler.render = function (c, exp) {
613
- c.save();
614
- var children = getChildren(c, exp);
615
- for (var i = 0; i < children.length; i++) {
616
- var child = children[i];
617
- renderExp(c, child);
618
- c.translate(0, Fluo.getHeight(c, child));
619
- if (i < children.length - 1) {
620
- FluoCanvas.drawArrow(c, 14);
621
- c.translate(0, 14);
622
- }
623
- }
624
- c.restore();
625
- };
626
- VerticalHandler.getHeight = function (c, exp) {
627
- return (getChildren(c, exp).length - 1) * 14 + childrenSum(c, exp, 'getHeight');
628
- };
629
- VerticalHandler.getWidth = function (c, exp) {
630
- return childrenMax(c, exp, 'getWidth');
631
- };
632
-
633
- var HorizontalHandler = newHandler();
634
- HorizontalHandler.render = function (c, exp) {
635
- var children = getChildren(c, exp);
636
- var dist = this.computeDistribution(c, exp);
637
- var childrenHeight = this.getChildrenHeight(c, exp);
638
- this.renderHeader(c, exp, dist);
639
- c.save();
640
- c.translate(0, this.getHeaderHeight(c, exp));
641
- for (var i=0; i < children.length; i++) {
642
- var child = children[i];
643
- c.save();
644
- c.translate(dist[i], 0);
645
- this.renderChild(c, child, childrenHeight);
646
- c.restore();
647
- }
648
- c.restore();
649
- this.renderFooter(c, exp, dist, childrenHeight);
650
- };
651
- HorizontalHandler.getHeaderHeight = function (c, exp) {
652
- if (c.canvas.horizontal == true) return 23 + attributeMaxWidth(c, exp);
653
- return 23 + attributeCount(exp) * FluoConstants.LINE_HEIGHT;
654
- };
655
- HorizontalHandler.getChildrenHeight = function (c, exp) {
656
- return childrenMax(c, exp, 'getHeight');
657
- };
658
- HorizontalHandler.getHeight = function (c, exp) {
659
- return this.getHeaderHeight(c, exp) + this.getChildrenHeight(c, exp) + 10;
660
- };
661
- HorizontalHandler.getWidth = function (c, exp) {
662
- return (getChildren(c, exp).length - 1) * 3 + childrenSum(c, exp, 'getWidth');
663
- //return Math.max(
664
- // attributeMaxWidth(c, exp),
665
- // (getChildren(c, exp).length - 1) * 3 + childrenSum(c, exp, 'getWidth'));
666
- };
667
- HorizontalHandler.computeDistribution = function (c, exp) {
668
- var children = getChildren(c, exp);
669
- var totalWidth = this.getWidth(c, exp);
670
- var offset = -totalWidth/2;
671
- var dist = new Array(children.length);
672
- for (var i = 0; i < children.length; i++) {
673
- var cWidth = Fluo.getWidth(c, children[i]);
674
- dist[i] = offset + cWidth / 2;
675
- offset += (cWidth + 3);
676
- }
677
- return dist;
678
- };
679
- HorizontalHandler.renderHeader = function (c, exp, distribution) {
680
- var hheight = this.getHeaderHeight(c, exp) - 10;
681
- c.save();
682
- c.translate(0, 10);
683
- FluoCanvas.drawQuadraticPath(
684
- c, distribution[0], hheight, 8);
685
- FluoCanvas.drawQuadraticPath(
686
- c, distribution[distribution.length-1], hheight, 8);
687
- for (var i = 1; i < distribution.length - 1; i++) {
688
- FluoCanvas.drawVerticalLine(c, distribution[i], hheight);
689
- }
690
- c.restore();
691
- this.renderHeaderSymbol(c);
692
- this.renderHeaderLabel(c, exp);
693
- };
694
- HorizontalHandler.renderHeaderSymbol = function (c) {
695
- FluoCanvas.drawDiamond(c, FluoConstants.LINE_HEIGHT);
696
- };
697
- HorizontalHandler.renderHeaderLabel = function (c, exp) {
698
- var width = attributeMaxWidth(c, exp);
699
- var height = attributeCount(exp) * FluoConstants.LINE_HEIGHT;
700
- if (c.canvas.horizontal == true) {
701
- var w = width;
702
- width = height;
703
- height = w;
704
- }
705
- c.save();
706
- c.translate(0, FluoConstants.LINE_HEIGHT);
707
- c.save();
708
- c.fillStyle = FluoConstants.WHITE;
709
- c.fillRect(-width/2, 0, width, height);
710
- c.restore();
711
- drawAttributes(c, exp, false, false, width, height);
712
- c.restore();
713
- };
714
- HorizontalHandler.renderChild = function (c, exp, childrenHeight) {
715
- var cheight = Fluo.getHeight(c, exp);
716
- renderExp(c, exp);
717
- c.beginPath();
718
- c.moveTo(0, cheight); c.lineTo(0, childrenHeight);
719
- c.stroke();
720
- };
721
- HorizontalHandler.renderFooter = function (c, exp, distribution) {
722
- var childrenHeight = this.getChildrenHeight(c, exp);
723
- c.save();
724
- c.translate(
725
- 0, this.getHeaderHeight(c, exp) + this.getChildrenHeight(c, exp) + 10);
726
- if (distribution.length == 1) {
727
- FluoCanvas.drawVerticalLine(c, distribution[0], -10);
728
- }
729
- else {
730
- FluoCanvas.drawQuadraticPath(
731
- c, distribution[0], -10, 8);
732
- FluoCanvas.drawQuadraticPath(
733
- c, distribution[distribution.length-1], -10, 8);
734
- for (var i = 1; i < distribution.length - 1; i++) {
735
- FluoCanvas.drawVerticalLine(c, distribution[i], -10);
736
- }
737
- }
738
- c.restore();
739
- };
740
- HorizontalHandler.renderFooterDiamond = function (c) {
741
- };
742
-
743
- var ConcurrenceHandler = newHandler(HorizontalHandler);
744
- ConcurrenceHandler.renderHeaderSymbol = function (c) {
745
- FluoCanvas.drawParaDiamond(c, 20);
746
- };
747
-
748
- function hasNoCondition (attributes) {
749
- if (attributes['test']) return false;
750
- if (attributes['not']) return false;
751
- for (k in attributes) {
752
- if (attributes[k] == null) return false;
753
- }
754
- return true;
755
- }
756
-
757
- var IfHandler = newHandler(HorizontalHandler);
758
- IfHandler.adjust = function (exp) {
759
- //
760
- // all the crazy legwork to adapt to the 'if' expression
761
- //
762
- if (hasNoCondition(exp[1])) {
763
- // ok, steal first exp
764
- var cond = exp[2].shift();
765
- if (cond) {
766
- exp[1] = cond[1];
767
- exp[1]['condition'] = cond[0];
768
- }
769
- }
770
- for (var i = 0; i < 2 - exp[2].length; i++) exp[2].push([ '_', {}, [] ]);
771
- // adding ghost expressions
772
- };
773
-
774
- //
775
- // used for empty else clause
776
- //
777
- var GhostHandler = newHandler();
778
- GhostHandler.render = function (c, exp) {
779
- };
780
- GhostHandler.getHeight = function (c, exp) {
781
- return 0;
782
- };
783
- GhostHandler.getWidth = function (c, exp) {
784
- return 35;
785
- };
786
-
787
- var HANDLERS = {
788
-
789
- //'participant': ParticipantHandler
790
-
791
- 'sequence': VerticalHandler,
792
- 'concurrence': ConcurrenceHandler,
793
- 'if': IfHandler,
794
- 'set': TextHandler,
795
- 'unset': TextHandler,
796
- 'sleep': SymbolHandler,
797
- 'wait': SymbolHandler,
798
- 'error': SymbolHandler,
799
- 'subprocess': SubprocessHandler,
800
- 'loop': LoopHandler,
801
- 'repeat': LoopHandler,
802
- 'cursor': LoopHandler,
803
- 'concurrent-iterator': ConcurrentIteratorHandler,
804
-
805
- 'rewind': TextHandler,
806
- 'continue': TextHandler,
807
- 'back': TextHandler,
808
- 'break': TextHandler,
809
- 'stop': TextHandler,
810
- 'cancel': TextHandler,
811
- 'skip': TextHandler,
812
- 'jump': TextHandler,
813
- // 'commands'
814
-
815
- //'_atts_': AttributeOnlyHandler,
816
- '_': GhostHandler
817
- };
818
-
819
- var MINORS = [ 'set', 'set-fields', 'unset', 'description' ];
820
-
821
- var DEFINERS = [ 'process-definition', 'workflow-definition', 'define' ];
822
-
823
- function identifyExpressions (exp, expid) {
824
- if (exp.expid) return; // identify only once
825
- if ( ! expid) expid = '0';
826
- exp.expid = expid;
827
- if ((typeof exp) == 'string') return;
828
- for (var i = 0; i < exp[2].length; i++) {
829
- identifyExpressions(exp[2][i], expid + '_' + i);
830
- }
831
- }
832
-
833
- function setOption (context, options, optname, defval) {
834
- var v = options[optname];
835
- if (v) {
836
- context.canvas[optname] = v;
837
- }
838
- else if (optname in options) { // v is null
839
- context.canvas[optname] = null;
840
- }
841
- else if (defval && ! (context.canvas[optname])) {
842
- context.canvas[optname] = defval;
843
- }
844
- }
845
-
846
- function renderFlow (context, flow, options) {
847
-
848
- if ( ! options) options = {};
849
-
850
- identifyExpressions(flow);
851
-
852
- context = resolveContext(context);
853
- neutralizeContext(context);
854
-
855
- context.canvas.flow = flow;
856
-
857
- setOption(context, options, 'workitems', []);
858
- setOption(context, options, 'highlight');
859
- setOption(context, options, 'hideMinor');
860
- setOption(context, options, 'horizontal');
861
-
862
- context.save();
863
-
864
- if (context.canvas.horizontal == true) {
865
- context.translate(0, flow.width + 2);
866
- context.rotate(-Math.PI/2);
867
- }
868
-
869
- context.mozTextStyle = FluoConstants.FONT;
870
- context.font = FluoConstants.FONT;
871
-
872
- var fs = context.fillStyle;
873
- context.fillStyle = FluoConstants.WHITE;
874
- context.fillRect(0, 0, context.canvas.width, context.canvas.height);
875
- context.fillStyle = fs;
876
-
877
- var w = getWidth(context, flow);
878
- context.translate(w/2 + 1, 1); // aligning left
879
-
880
- renderExp(context, flow);
881
-
882
- context.restore();
883
-
884
- getWidth(context, flow);
885
- getHeight(context, flow);
886
- }
887
-
888
- function highlight (c, highlight) {
889
- canvas = resolveCanvas(c);
890
- renderFlow(canvas, canvas.flow, { 'highlight': highlight });
891
- }
892
-
893
- function drawWorkitem (c, exp) {
894
- var ww = c.measure('wi');
895
- c.save();
896
- if (c.canvas.horizontal == true) {
897
- c.rotate(Math.PI/2);
898
- c.translate(5, -14);
899
- }
900
- else {
901
- c.translate(49, 2);
902
- }
903
- c.fillStyle = '#F4D850';
904
- c.moveTo(0, 0);
905
- c.beginPath();
906
- c.arc(0, 0, 10, Math.PI, 0, false);
907
- c.lineTo(0, 20);
908
- c.lineTo(-10, 0);
909
- c.fill();
910
- c.fillStyle = 'black';
911
- c.moveTo(0, 0);
912
- c.beginPath();
913
- c.arc(0, 0, 10, Math.PI, 0, false);
914
- c.lineTo(0, 20);
915
- c.lineTo(-10, 0);
916
- c.stroke();
917
- c.translate(-ww/2, 3);
918
- c.write('wi');
919
- c.restore();
920
- }
921
-
922
- function renderExp (c, exp) {
923
-
924
- var handler = getHandler(c, exp);
925
-
926
- if (handler.adjust && ! exp.adjusted) {
927
- handler.adjust(exp);
928
- exp.adjusted = true;
929
- }
930
-
931
- if (c.canvas.highlight && exp.expid == c.canvas.highlight) { // highlight
932
- var w = getWidth(c, exp);
933
- var h = getHeight(c, exp);
934
- var t = 7;
935
- c.save();
936
- c.fillStyle = FluoConstants.HIGHLIGHT;
937
- c.fillRect(-w/2, 0, w, h);
938
- c.fillStyle = FluoConstants.WHITE;
939
- c.fillRect(-w/2 + t, 0 + t , w - 2 * t, h - 2 * t);
940
- c.restore();
941
- }
942
-
943
- handler.render(c, exp);
944
-
945
- if (c.canvas.workitems.indexOf(exp.expid) > -1) { // workitem
946
- drawWorkitem(c, exp);
947
- }
948
- }
949
-
950
- /*
951
- function clear (c) {
952
- c = resolveContext(c);
953
- c.clearRect(0, 0, c.canvas.width, c.canvas.height);
954
- }
955
- */
956
-
957
- function resolveCanvas (c) {
958
- if (c.getContext != null) return c;
959
- if (c.canvas != null) return c.canvas;
960
- return document.getElementById(c);
961
- }
962
-
963
- function resolveContext (c) {
964
- if (c.translate != null) return c;
965
- return resolveCanvas(c).getContext('2d');
966
- }
967
-
968
- // replaces the canvas element with a new, cropped, one
969
- //
970
- function crop (canvas) {
971
-
972
- canvas = resolveCanvas(canvas);
973
- var nc = document.createElement("canvas");
974
-
975
- nc.id = canvas.id;
976
-
977
- var w = canvas.flow.width + 2;
978
- var h = canvas.flow.height + 2;
979
-
980
- if (canvas.horizontal == true) {
981
- var x = w; w = h; h = x;
982
- }
983
-
984
- nc.setAttribute('width', w);
985
- nc.setAttribute('height', h);
986
-
987
- nc.hideMinor = canvas.hideMinor;
988
- nc.horizontal = canvas.horizontal;
989
- nc.workitems = canvas.workitems;
990
- nc.noOuterBorder = canvas.noOuterBorder;
991
-
992
- renderFlow(nc, canvas.flow);
993
- canvas.parentNode.replaceChild(nc, canvas);
994
- }
995
-
996
- // For example :
997
- //
998
- // Fluo.resize('fluo', 0.5)
999
- //
1000
- function resize (canvas, factor) {
1001
-
1002
- canvas = resolveCanvas(canvas);
1003
- var w = canvas.width;
1004
- var h = canvas.height;
1005
- canvas.style.width = '' + (w * factor) + 'px';
1006
- canvas.style.height = '' + (h * factor) + 'px';
1007
- }
1008
-
1009
- // For example :
1010
- //
1011
- // Fluo.resizeForMaxWidth('fluo', 200)
1012
- //
1013
- function resizeForMaxWidth (canvas, maxWidth) {
1014
-
1015
- canvas = resolveCanvas(canvas);
1016
- var w = canvas.width;
1017
-
1018
- if (w < maxWidth) return;
1019
-
1020
- resize(canvas, maxWidth / w);
1021
- }
1022
-
1023
- function neutralizeContext (c) {
1024
- if (window.navigator.userAgent.match(/Firefox/)) {
1025
- c.write = function (t) {
1026
- this.mozDrawText(t);
1027
- }
1028
- c.measure = function (t) {
1029
- return this.mozMeasureText(t);
1030
- }
1031
- }
1032
- else { // Safari 4
1033
- c.write = function (t) {
1034
- this.fillText(t, 0, 0);
1035
- }
1036
- c.measure = function (t) {
1037
- return this.measureText(t).width;
1038
- return t.length * 5;
1039
- }
1040
- }
1041
- }
1042
-
1043
- function isSubprocessName (exp, name) {
1044
- if ((typeof exp) == 'string') return false;
1045
- if (DEFINERS.indexOf(exp[0]) > -1 && exp[1]['name'] == name) return true;
1046
- for (var i = 0; i < exp[2].length; i++) {
1047
- if (isSubprocessName(exp[2][i], name)) return true;
1048
- }
1049
- return false;
1050
- }
1051
-
1052
- // returns the raw height of an expression (caches it too)
1053
- //
1054
- function getHeight (c, exp) {
1055
- if ((typeof exp) == 'string') return getHandler(c, exp).getHeight(c, exp);
1056
- if (exp.height) return exp.height;
1057
- var h = getHandler(c, exp);
1058
- if (h.adjust && ! exp.adjusted) { h.adjust(exp); exp.adjusted = true; }
1059
- exp.height = h.getHeight(c, exp);
1060
- return exp.height;
1061
- }
1062
-
1063
- // return the raw width of an expression
1064
- //
1065
- function getWidth (c, exp) {
1066
- if ((typeof exp) == 'string') return getHandler(c, exp).getWidth(c, exp);
1067
- if (exp.width) return exp.width;
1068
- var h = getHandler(c, exp);
1069
- if (h.adjust && ! exp.adjusted) { h.adjust(exp); exp.adjusted = true; }
1070
- exp.width = h.getWidth(c, exp);
1071
- return exp.width;
1072
- }
1073
-
1074
- function getHandler (c, exp) {
1075
- if ((typeof exp) == 'string') return StringHandler;
1076
- var h = HANDLERS[exp[0]];
1077
- if (h) return h;
1078
- //if (childText(exp)) return GenericHandler;
1079
- if (exp[2].length > 0) return GenericWithChildrenHandler;
1080
- if (isSubprocessName(c.canvas.flow, exp[0])) return SubprocessHandler;
1081
- return GenericHandler;
1082
- }
1083
-
1084
- function clearDimCache (exp) {
1085
- if ((typeof exp) == 'string') return;
1086
- exp.width = null;
1087
- exp.height = null;
1088
- for (var i = 0; i < exp[2].length; i++) clearDimCache(exp[2][i]);
1089
- }
1090
-
1091
- function toggleMinor (canvas) {
1092
- canvas = resolveCanvas(canvas);
1093
- canvas.hideMinor = ! canvas.hideMinor;
1094
- clearDimCache(canvas.flow);
1095
- renderFlow(canvas, canvas.flow);
1096
- }
1097
-
1098
- function toggleVertical (canvas) {
1099
- canvas = resolveCanvas(canvas);
1100
- canvas.horizontal = ! canvas.horizontal;
1101
- clearDimCache(canvas.flow);
1102
- renderFlow(canvas, canvas.flow);
1103
- }
1104
-
1105
- return {
1106
- HANDLERS: HANDLERS,
1107
- MINORS: MINORS,
1108
- renderFlow: renderFlow,
1109
- highlight: highlight,
1110
- getHeight: getHeight,
1111
- getWidth: getWidth,
1112
- crop: crop,
1113
- resize: resize,
1114
- resizeForMaxWidth: resizeForMaxWidth,
1115
- toggleMinor: toggleMinor,
1116
- toggleVertical: toggleVertical
1117
- };
1118
- }();