##// END OF EJS Templates
Changes auto_complete calls to GET requests....
Jean-Philippe Lang -
r8010:d75bc5774f1e
parent child
Show More
@@ -1,211 +1,211
1 1 ActionController::Routing::Routes.draw do |map|
2 2 # Add your own custom routes here.
3 3 # The priority is based upon order of creation: first created -> highest priority.
4 4
5 5 # Here's a sample route:
6 6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 7 # Keep in mind you can assign values other than :controller and :action
8 8
9 9 map.home '', :controller => 'welcome'
10 10
11 11 map.signin 'login', :controller => 'account', :action => 'login'
12 12 map.signout 'logout', :controller => 'account', :action => 'logout'
13 13
14 14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
15 15 map.connect 'help/:ctrl/:page', :controller => 'help'
16 16
17 17 map.time_entries_context_menu '/time_entries/context_menu',
18 18 :controller => 'context_menus', :action => 'time_entries'
19 19
20 20 map.resources :time_entries, :controller => 'timelog', :collection => {:report => :get, :bulk_edit => :get, :bulk_update => :post}
21 21
22 22 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
23 23 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
24 24 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
25 25
26 26 map.with_options :controller => 'messages' do |messages_routes|
27 27 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
28 28 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
29 29 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
30 30 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
31 31 end
32 32 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
33 33 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
34 34 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
35 35 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
36 36 end
37 37 end
38 38
39 39 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
40 40 map.resources :queries, :except => [:show]
41 41
42 42 # Misc issue routes. TODO: move into resources
43 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
43 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues', :conditions => { :method => :get }
44 44 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
45 45 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
46 46 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
47 47 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
48 48 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
49 49 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
50 50 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
51 51
52 52 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
53 53 gantts_routes.connect '/projects/:project_id/issues/gantt'
54 54 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
55 55 gantts_routes.connect '/issues/gantt.:format'
56 56 end
57 57
58 58 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
59 59 calendars_routes.connect '/projects/:project_id/issues/calendar'
60 60 calendars_routes.connect '/issues/calendar'
61 61 end
62 62
63 63 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
64 64 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
65 65 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
66 66 end
67 67
68 68 map.resources :issues do |issues|
69 69 issues.resources :time_entries, :controller => 'timelog', :collection => {:report => :get}
70 70 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
71 71 end
72 72
73 73 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
74 74
75 75 map.with_options :controller => 'users' do |users|
76 76 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
77 77
78 78 users.with_options :conditions => {:method => :post} do |user_actions|
79 79 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
80 80 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
81 81 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
82 82 end
83 83 end
84 84
85 85 map.resources :users, :member => {
86 86 :edit_membership => :post,
87 87 :destroy_membership => :post
88 88 }
89 89
90 90 # For nice "roadmap" in the url for the index action
91 91 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
92 92
93 93 map.all_news 'news', :controller => 'news', :action => 'index'
94 94 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
95 95 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
96 96 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
97 97 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
98 98
99 99 map.resources :projects, :member => {
100 100 :copy => [:get, :post],
101 101 :settings => :get,
102 102 :modules => :post,
103 103 :archive => :post,
104 104 :unarchive => :post
105 105 } do |project|
106 106 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
107 107 project.resources :issues, :only => [:index, :new, :create] do |issues|
108 108 issues.resources :time_entries, :controller => 'timelog', :collection => {:report => :get}
109 109 end
110 110 project.resources :files, :only => [:index, :new, :create]
111 111 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
112 112 project.resources :news, :shallow => true
113 113 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id', :collection => {:report => :get}
114 114 project.resources :queries, :only => [:new, :create]
115 115 project.resources :issue_categories, :shallow => true
116 116 project.resources :documents, :shallow => true, :member => {:add_attachment => :post}
117 117 project.resources :boards
118 118
119 119 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
120 120 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
121 121 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
122 122 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
123 123 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
124 124 project.resources :wiki, :except => [:new, :create], :member => {
125 125 :rename => [:get, :post],
126 126 :history => :get,
127 127 :preview => :any,
128 128 :protect => :post,
129 129 :add_attachment => :post
130 130 }, :collection => {
131 131 :export => :get,
132 132 :date_index => :get
133 133 }
134 134
135 135 end
136 136
137 137 # Destroy uses a get request to prompt the user before the actual DELETE request
138 138 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
139 139
140 140 # TODO: port to be part of the resources route(s)
141 141 map.with_options :controller => 'projects' do |project_mapper|
142 142 project_mapper.with_options :conditions => {:method => :get} do |project_views|
143 143 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
144 144 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
145 145 end
146 146 end
147 147
148 148 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
149 149 activity.connect 'projects/:id/activity'
150 150 activity.connect 'projects/:id/activity.:format'
151 151 activity.connect 'activity', :id => nil
152 152 activity.connect 'activity.:format', :id => nil
153 153 end
154 154
155 155 map.with_options :controller => 'repositories' do |repositories|
156 156 repositories.with_options :conditions => {:method => :get} do |repository_views|
157 157 repository_views.connect 'projects/:id/repository', :action => 'show'
158 158 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
159 159 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
160 160 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
161 161 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
162 162 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
163 163 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
164 164 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
165 165 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
166 166 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
167 167 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
168 168 # TODO: why the following route is required?
169 169 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
170 170 repository_views.connect 'projects/:id/repository/:action/*path'
171 171 end
172 172
173 173 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
174 174 end
175 175
176 176 map.resources :attachments, :only => [:show, :destroy]
177 177 # additional routes for having the file name at the end of url
178 178 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
179 179 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
180 180
181 181 map.resources :groups, :member => {:autocomplete_for_user => :get}
182 182 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
183 183 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
184 184
185 185 map.resources :trackers, :except => :show
186 186 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
187 187
188 188 #left old routes at the bottom for backwards compat
189 189 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
190 190 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
191 191 map.connect 'projects/:project_id/news/:action', :controller => 'news'
192 192 map.with_options :controller => 'repositories' do |omap|
193 193 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
194 194 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
195 195 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
196 196 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
197 197 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
198 198 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
199 199 end
200 200
201 201 map.with_options :controller => 'sys' do |sys|
202 202 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
203 203 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
204 204 end
205 205
206 206 # Install the default route as the lowest priority.
207 207 map.connect ':controller/:action/:id'
208 208 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
209 209 # Used for OpenID
210 210 map.root :controller => 'account', :action => 'login'
211 211 end
@@ -1,415 +1,417
1 1 /* redMine - project management software
2 2 Copyright (C) 2006-2008 Jean-Philippe Lang */
3 3
4 4 function checkAll (id, checked) {
5 5 var els = Element.descendants(id);
6 6 for (var i = 0; i < els.length; i++) {
7 7 if (els[i].disabled==false) {
8 8 els[i].checked = checked;
9 9 }
10 10 }
11 11 }
12 12
13 13 function toggleCheckboxesBySelector(selector) {
14 14 boxes = $$(selector);
15 15 var all_checked = true;
16 16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
17 17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
18 18 }
19 19
20 20 function setCheckboxesBySelector(checked, selector) {
21 21 var boxes = $$(selector);
22 22 boxes.each(function(ele) {
23 23 ele.checked = checked;
24 24 });
25 25 }
26 26
27 27 function showAndScrollTo(id, focus) {
28 28 Element.show(id);
29 29 if (focus!=null) { Form.Element.focus(focus); }
30 30 Element.scrollTo(id);
31 31 }
32 32
33 33 function toggleRowGroup(el) {
34 34 var tr = Element.up(el, 'tr');
35 35 var n = Element.next(tr);
36 36 tr.toggleClassName('open');
37 37 while (n != undefined && !n.hasClassName('group')) {
38 38 Element.toggle(n);
39 39 n = Element.next(n);
40 40 }
41 41 }
42 42
43 43 function collapseAllRowGroups(el) {
44 44 var tbody = Element.up(el, 'tbody');
45 45 tbody.childElements('tr').each(function(tr) {
46 46 if (tr.hasClassName('group')) {
47 47 tr.removeClassName('open');
48 48 } else {
49 49 tr.hide();
50 50 }
51 51 })
52 52 }
53 53
54 54 function expandAllRowGroups(el) {
55 55 var tbody = Element.up(el, 'tbody');
56 56 tbody.childElements('tr').each(function(tr) {
57 57 if (tr.hasClassName('group')) {
58 58 tr.addClassName('open');
59 59 } else {
60 60 tr.show();
61 61 }
62 62 })
63 63 }
64 64
65 65 function toggleAllRowGroups(el) {
66 66 var tr = Element.up(el, 'tr');
67 67 if (tr.hasClassName('open')) {
68 68 collapseAllRowGroups(el);
69 69 } else {
70 70 expandAllRowGroups(el);
71 71 }
72 72 }
73 73
74 74 function toggleFieldset(el) {
75 75 var fieldset = Element.up(el, 'fieldset');
76 76 fieldset.toggleClassName('collapsed');
77 77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
78 78 }
79 79
80 80 function hideFieldset(el) {
81 81 var fieldset = Element.up(el, 'fieldset');
82 82 fieldset.toggleClassName('collapsed');
83 83 fieldset.down('div').hide();
84 84 }
85 85
86 86 var fileFieldCount = 1;
87 87
88 88 function addFileField() {
89 89 var fields = $('attachments_fields');
90 90 if (fields.childElements().length >= 10) return false;
91 91 fileFieldCount++;
92 92 var s = document.createElement("span");
93 93 s.update(fields.down('span').innerHTML);
94 94 s.down('input.file').name = "attachments[" + fileFieldCount + "][file]";
95 95 s.down('input.description').name = "attachments[" + fileFieldCount + "][description]";
96 96 fields.appendChild(s);
97 97 }
98 98
99 99 function removeFileField(el) {
100 100 var fields = $('attachments_fields');
101 101 var s = Element.up(el, 'span');
102 102 if (fields.childElements().length > 1) {
103 103 s.remove();
104 104 } else {
105 105 s.update(s.innerHTML);
106 106 }
107 107 }
108 108
109 109 function checkFileSize(el, maxSize, message) {
110 110 var files = el.files;
111 111 if (files) {
112 112 for (var i=0; i<files.length; i++) {
113 113 if (files[i].size > maxSize) {
114 114 alert(message);
115 115 el.value = "";
116 116 }
117 117 }
118 118 }
119 119 }
120 120
121 121 function showTab(name) {
122 122 var f = $$('div#content .tab-content');
123 123 for(var i=0; i<f.length; i++){
124 124 Element.hide(f[i]);
125 125 }
126 126 var f = $$('div.tabs a');
127 127 for(var i=0; i<f.length; i++){
128 128 Element.removeClassName(f[i], "selected");
129 129 }
130 130 Element.show('tab-content-' + name);
131 131 Element.addClassName('tab-' + name, "selected");
132 132 return false;
133 133 }
134 134
135 135 function moveTabRight(el) {
136 136 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
137 137 var tabsWidth = 0;
138 138 var i;
139 139 for (i=0; i<lis.length; i++) {
140 140 if (lis[i].visible()) {
141 141 tabsWidth += lis[i].getWidth() + 6;
142 142 }
143 143 }
144 144 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
145 145 return;
146 146 }
147 147 i=0;
148 148 while (i<lis.length && !lis[i].visible()) {
149 149 i++;
150 150 }
151 151 lis[i].hide();
152 152 }
153 153
154 154 function moveTabLeft(el) {
155 155 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
156 156 var i = 0;
157 157 while (i<lis.length && !lis[i].visible()) {
158 158 i++;
159 159 }
160 160 if (i>0) {
161 161 lis[i-1].show();
162 162 }
163 163 }
164 164
165 165 function displayTabsButtons() {
166 166 var lis;
167 167 var tabsWidth = 0;
168 168 var i;
169 169 $$('div.tabs').each(function(el) {
170 170 lis = el.down('ul').childElements();
171 171 for (i=0; i<lis.length; i++) {
172 172 if (lis[i].visible()) {
173 173 tabsWidth += lis[i].getWidth() + 6;
174 174 }
175 175 }
176 176 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
177 177 el.down('div.tabs-buttons').hide();
178 178 } else {
179 179 el.down('div.tabs-buttons').show();
180 180 }
181 181 });
182 182 }
183 183
184 184 function setPredecessorFieldsVisibility() {
185 185 relationType = $('relation_relation_type');
186 186 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
187 187 Element.show('predecessor_fields');
188 188 } else {
189 189 Element.hide('predecessor_fields');
190 190 }
191 191 }
192 192
193 193 function promptToRemote(text, param, url) {
194 194 value = prompt(text + ':');
195 195 if (value) {
196 196 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
197 197 return false;
198 198 }
199 199 }
200 200
201 201 function showModal(id, width) {
202 202 el = $(id);
203 203 if (el == undefined || el.visible()) {return;}
204 204 var h = $$('body')[0].getHeight();
205 205 var d = document.createElement("div");
206 206 d.id = 'modalbg';
207 207 $('main').appendChild(d);
208 208 $('modalbg').setStyle({ width: '100%', height: h + 'px' });
209 209 $('modalbg').show();
210 210
211 211 var pageWidth = document.viewport.getWidth();
212 212 el.setStyle({'width': width});
213 213 el.setStyle({'left': (((pageWidth - el.getWidth())/2 *100) / pageWidth) + '%'});
214 214 el.addClassName('modal');
215 215 el.show();
216 216
217 217 var submit = el.down("input[type=submit]");
218 218 if (submit) {
219 219 submit.focus();
220 220 }
221 221 }
222 222
223 223 function hideModal(el) {
224 224 var modal = Element.up(el, 'div.modal');
225 225 if (modal) {
226 226 modal.hide();
227 227 }
228 228 var bg = $('modalbg');
229 229 if (bg) {
230 230 bg.remove();
231 231 }
232 232 }
233 233
234 234 function collapseScmEntry(id) {
235 235 var els = document.getElementsByClassName(id, 'browser');
236 236 for (var i = 0; i < els.length; i++) {
237 237 if (els[i].hasClassName('open')) {
238 238 collapseScmEntry(els[i].id);
239 239 }
240 240 Element.hide(els[i]);
241 241 }
242 242 $(id).removeClassName('open');
243 243 }
244 244
245 245 function expandScmEntry(id) {
246 246 var els = document.getElementsByClassName(id, 'browser');
247 247 for (var i = 0; i < els.length; i++) {
248 248 Element.show(els[i]);
249 249 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
250 250 expandScmEntry(els[i].id);
251 251 }
252 252 }
253 253 $(id).addClassName('open');
254 254 }
255 255
256 256 function scmEntryClick(id) {
257 257 el = $(id);
258 258 if (el.hasClassName('open')) {
259 259 collapseScmEntry(id);
260 260 el.addClassName('collapsed');
261 261 return false;
262 262 } else if (el.hasClassName('loaded')) {
263 263 expandScmEntry(id);
264 264 el.removeClassName('collapsed');
265 265 return false;
266 266 }
267 267 if (el.hasClassName('loading')) {
268 268 return false;
269 269 }
270 270 el.addClassName('loading');
271 271 return true;
272 272 }
273 273
274 274 function scmEntryLoaded(id) {
275 275 Element.addClassName(id, 'open');
276 276 Element.addClassName(id, 'loaded');
277 277 Element.removeClassName(id, 'loading');
278 278 }
279 279
280 280 function randomKey(size) {
281 281 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
282 282 var key = '';
283 283 for (i = 0; i < size; i++) {
284 284 key += chars[Math.floor(Math.random() * chars.length)];
285 285 }
286 286 return key;
287 287 }
288 288
289 289 function observeParentIssueField(url) {
290 290 new Ajax.Autocompleter('issue_parent_issue_id',
291 291 'parent_issue_candidates',
292 292 url,
293 293 { minChars: 3,
294 294 frequency: 0.5,
295 295 paramName: 'q',
296 method: 'get',
296 297 updateElement: function(value) {
297 298 document.getElementById('issue_parent_issue_id').value = value.id;
298 299 }});
299 300 }
300 301
301 302 function observeRelatedIssueField(url) {
302 303 new Ajax.Autocompleter('relation_issue_to_id',
303 304 'related_issue_candidates',
304 305 url,
305 306 { minChars: 3,
306 307 frequency: 0.5,
307 308 paramName: 'q',
309 method: 'get',
308 310 updateElement: function(value) {
309 311 document.getElementById('relation_issue_to_id').value = value.id;
310 312 },
311 313 parameters: 'scope=all'
312 314 });
313 315 }
314 316
315 317 function setVisible(id, visible) {
316 318 var el = $(id);
317 319 if (el) {if (visible) {el.show();} else {el.hide();}}
318 320 }
319 321
320 322 function observeProjectModules() {
321 323 var f = function() {
322 324 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
323 325 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
324 326 setVisible('project_trackers', c);
325 327 setVisible('project_issue_custom_fields', c);
326 328 };
327 329
328 330 Event.observe(window, 'load', f);
329 331 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
330 332 }
331 333
332 334 /*
333 335 * Class used to warn user when leaving a page with unsaved textarea
334 336 * Author: mathias.fischer@berlinonline.de
335 337 */
336 338
337 339 var WarnLeavingUnsaved = Class.create({
338 340 observedForms: false,
339 341 observedElements: false,
340 342 changedForms: false,
341 343 message: null,
342 344
343 345 initialize: function(message){
344 346 this.observedForms = $$('form');
345 347 this.observedElements = $$('textarea');
346 348 this.message = message;
347 349
348 350 this.observedElements.each(this.observeChange.bind(this));
349 351 this.observedForms.each(this.submitAction.bind(this));
350 352
351 353 window.onbeforeunload = this.unload.bind(this);
352 354 },
353 355
354 356 unload: function(){
355 357 this.observedElements.each(function(el) {el.blur();})
356 358 if(this.changedForms)
357 359 return this.message;
358 360 },
359 361
360 362 setChanged: function(){
361 363 this.changedForms = true;
362 364 },
363 365
364 366 setUnchanged: function(){
365 367 this.changedForms = false;
366 368 },
367 369
368 370 observeChange: function(element){
369 371 element.observe('change',this.setChanged.bindAsEventListener(this));
370 372 },
371 373
372 374 submitAction: function(element){
373 375 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
374 376 }
375 377 });
376 378
377 379 /*
378 380 * 1 - registers a callback which copies the csrf token into the
379 381 * X-CSRF-Token header with each ajax request. Necessary to
380 382 * work with rails applications which have fixed
381 383 * CVE-2011-0447
382 384 * 2 - shows and hides ajax indicator
383 385 */
384 386 Ajax.Responders.register({
385 387 onCreate: function(request){
386 388 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
387 389
388 390 if (csrf_meta_tag) {
389 391 var header = 'X-CSRF-Token',
390 392 token = csrf_meta_tag.readAttribute('content');
391 393
392 394 if (!request.options.requestHeaders) {
393 395 request.options.requestHeaders = {};
394 396 }
395 397 request.options.requestHeaders[header] = token;
396 398 }
397 399
398 400 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
399 401 Element.show('ajax-indicator');
400 402 }
401 403 },
402 404 onComplete: function(){
403 405 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
404 406 Element.hide('ajax-indicator');
405 407 }
406 408 }
407 409 });
408 410
409 411 function hideOnLoad() {
410 412 $$('.hol').each(function(el) {
411 413 el.hide();
412 414 });
413 415 }
414 416
415 417 Event.observe(window, 'load', hideOnLoad);
General Comments 0
You need to be logged in to leave comments. Login now