Upgraded Rails and RSpec
[monkeycharger.git] / vendor / plugins / rspec / rspec / story_server / prototype / javascripts / application.js
blobd63609600cbe901fd4105db3a2900fd8e949985a
1 var InPlaceEditor = {};
2 InPlaceEditor.Local = Class.create();
3 Object.extend(Object.extend(InPlaceEditor.Local.prototype, Ajax.InPlaceEditor.prototype), {
4   enterHover: function() {},
5   leaveHover: function() {},
6   onComplete: function() {},
7   handleFormSubmission: function(e) {
8     var value = $F(this._controls.editor);
9     RSpec.addStockStep(value);    
10     this.element.innerHTML = value;
11     this.leaveEditMode();
12     if (e) Event.stop(e);
13   }
14 });
16 var RSpec = {
17   stockSteps: function() {
18     return $('stock_steps').childElements().map(function(li){ 
19       return li.innerHTML;
20     }).sort();
21   },
22   
23   addStockStep: function(stockStep) {
24     if(!this.stockSteps().include(stockStep)) {
25       $('stock_steps').appendChild(Builder.node('li', {}, stockStep));
26     }
27   },
28   
29   makeParamEditors: function() {
30     $$('span.param').each(function(span) {
31       span.removeClassName('param');
32       span.addClassName('param_editor');
33       new InPlaceEditor.Local(span, null, {});
34     });
35   },
36   
37   setId: function(e) {
38     if(!this.currentId) this.currentId = 0;
39     this.currentId++;
40     e.id = "id_" + this.currentId;
41   },
42   
43   applyUi: function() {
44     this.setUpTogglers();
45     this.makeParamEditors();
47     var currentId = 0;
48     $$('ul.steps').each(function(ul) {
49       RSpec.setId(ul);
50       var footer = document.createElement("p");
51       var addStepLink = document.createElement("a");
52       addStepLink.href = "#";
53       addStepLink.appendChild(document.createTextNode('Add step'));
54       footer.appendChild(addStepLink);      
55       ul.parentNode.appendChild(footer);
57       Sortable.create(ul, {
58         scroll: window
59       });
61 /*    Disable for now - it messes with the autocomplete's visibility (zIndex galore)  
62       Droppables.add(footer, {
63         hoverclass: 'wastebin',
64         onDrop: function(li, droppable, evt) {
65           li.remove();
66         }
67       });
68 */      
69       Event.observe(addStepLink, 'click', function() {
70         var form = Builder.node('form', {});
71         
72         var li = Builder.node('li', {className: 'new'});
73         var input = Builder.node('input', {}, 'New step here');
74         var autoComplete = Builder.node('div', {className: 'auto_complete'}, '');
76         li.appendChild(form);
77         form.appendChild(input);
78         form.appendChild(autoComplete);
79         ul.appendChild(li);
80         Sortable.destroy(ul);
81         Sortable.create(ul);
83         Event.observe(form, 'submit', function(e) {
84           var value = input.value;
85           Element.remove(this);
86           li.innerHTML = value.gsub(/(\$[a-z]*)/, '<span class="param">#{1}</span>');
87           RSpec.makeParamEditors();
88           if (e) Event.stop(e);
89         });
91         var ac = new Autocompleter.Local(input, autoComplete, RSpec.stockSteps(), {});
92         input.focus();
93       });
94     })
95   },
96   
97   setUpTogglers: function() {
98     $$('dt').each(function(dt) {
99       var dd = dt.parentNode.getElementsByTagName('dd')[0];
100       dt.onclick = function(){
101         dd.toggle();
102       }
103     });
104   }
107 var StoryDom = {
108   narrativeText: function(s) {
109     return s.split(/\n/m).map(function(line){
110       if(line == "" || line.match(/^\s+$/) ) {
111         return null;
112       } else {
113         return "  " + (line.gsub(/^\s+/, '').gsub(/<br \/>/, "\n").gsub(/<br>/, "\n"));
114       }
115     }).compact().join("");
116   },
117   
118   stepText: function(s) {
119     return s.gsub(/<span[^>]*>([^<]*)<\/span>/, "#{1}");
120   },
121   
122   scenario: function(dl) {
123     var scenario = '  Scenario: ' + dl.getElementsByTagName('dt')[0].innerHTML + '\n';
124     scenario += $A(dl.getElementsByTagName('li')).map(function(li){
125       return '    ' + StoryDom.stepText(li.innerHTML);
126     }).join("\n") + "\n";
127     return scenario;
128   },
129   
130   story: function() {
131     var dl = $$('dl.story')[0];
132     var story = 'Story: ' + dl.getElementsByTagName('dt')[0].innerHTML + '\n\n';
133     story += this.narrativeText(dl.getElementsByTagName('p')[0].innerHTML) + '\n';
134     story += $A(dl.getElementsByTagName('dl')).map(function(scenarioDl){
135       return StoryDom.scenario(scenarioDl);
136     }).join("\n");
137     return story;
138   },
139   
140   save: function() {
141     new Ajax.Request('stories', {
142       postBody: this.story()
143     });
144   }
147 Event.observe(window, 'load', function() {
148   RSpec.applyUi();