aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/journey/visualizer/fsm.js
blob: d9bcaef9280169037f56b7da20799b63fa2ba028 (plain) (blame)
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
125
126
127
128
129
130
131
132
133
134
function tokenize(input, callback) {
  while(input.length > 0) {
    callback(input.match(/^[\/\.\?]|[^\/\.\?]+/)[0]);
    input = input.replace(/^[\/\.\?]|[^\/\.\?]+/, '');
  }
}

var graph = d3.select("#chart-2 svg");
var svg_edges = {};
var svg_nodes = {};

graph.selectAll("g.edge").each(function() {
  var node  = d3.select(this);
  var index = node.select("title").text().split("->");
  var left  = parseInt(index[0]);
  var right = parseInt(index[1]);

  if(!svg_edges[left]) { svg_edges[left] = {} }
  svg_edges[left][right] = node;
});

graph.selectAll("g.node").each(function() {
  var node  = d3.select(this);
  var index = parseInt(node.select("title").text());
  svg_nodes[index] = node;
});

function reset_graph() {
  for(var key in svg_edges) {
    for(var mkey in svg_edges[key]) {
      var node = svg_edges[key][mkey];
      var path = node.select("path");
      var arrow = node.select("polygon");
      path.style("stroke", "black");
      arrow.style("stroke", "black").style("fill", "black");
    }
  }

  for(var key in svg_nodes) {
    var node = svg_nodes[key];
    node.select('ellipse').style("fill", "white");
    node.select('polygon').style("fill", "white");
  }
  return false;
}

function highlight_edge(from, to) {
  var node = svg_edges[from][to];
  var path = node.select("path");
  var arrow = node.select("polygon");

  path
    .transition().duration(500)
    .style("stroke", "green");

  arrow
    .transition().duration(500)
    .style("stroke", "green").style("fill", "green");
}

function highlight_state(index, color) {
  if(!color) { color = "green"; }

  svg_nodes[index].select('ellipse')
    .style("fill", "white")
    .transition().duration(500)
    .style("fill", color);
}

function highlight_finish(index) {
  svg_nodes[index].select('polygon')
    .style("fill", "while")
    .transition().duration(500)
    .style("fill", "blue");
}

function match(input) {
  reset_graph();
  var table         = tt();
  var states        = [0];
  var regexp_states = table['regexp_states'];
  var string_states = table['string_states'];
  var accepting     = table['accepting'];

  highlight_state(0);

  tokenize(input, function(token) {
    var new_states = [];
    for(var key in states) {
      var state = states[key];

      if(string_states[state] && string_states[state][token]) {
        var new_state = string_states[state][token];
        highlight_edge(state, new_state);
        highlight_state(new_state);
        new_states.push(new_state);
      }

      if(regexp_states[state]) {
        for(var key in regexp_states[state]) {
          var re = new RegExp("^" + key + "$");
          if(re.test(token)) {
            var new_state = regexp_states[state][key];
            highlight_edge(state, new_state);
            highlight_state(new_state);
            new_states.push(new_state);
          }
        }
      }
    }

    if(new_states.length == 0) {
      return;
    }
    states = new_states;
  });

  for(var key in states) {
    var state = states[key];
    if(accepting[state]) {
      for(var mkey in svg_edges[state]) {
        if(!regexp_states[mkey] && !string_states[mkey]) {
          highlight_edge(state, mkey);
          highlight_finish(mkey);
        }
      }
    } else {
      highlight_state(state, "red");
    }
  }

  return false;
}