##// END OF EJS Templates
Make the issue list context menu work under Mac OSX Leopard (#1485). Tested with FF3.0.1 and Safari 3.0.4 under OSX 10.5.2....
Jean-Philippe Lang -
r1760:954bddbadf9e
parent child
Show More
@@ -1,218 +1,221
1 1 /* redMine - project management software
2 2 Copyright (C) 2006-2008 Jean-Philippe Lang */
3 3
4 4 var observingContextMenuClick;
5 5
6 6 ContextMenu = Class.create();
7 7 ContextMenu.prototype = {
8 8 initialize: function (url) {
9 9 this.url = url;
10 10
11 11 // prevent selection when using Ctrl/Shit key
12 12 var tables = $$('table.issues');
13 13 for (i=0; i<tables.length; i++) {
14 14 tables[i].onselectstart = function () { return false; } // ie
15 15 tables[i].onmousedown = function () { return false; } // mozilla
16 16 }
17 17
18 18 if (!observingContextMenuClick) {
19 19 Event.observe(document, 'click', this.Click.bindAsEventListener(this));
20 20 Event.observe(document, (window.opera ? 'click' : 'contextmenu'), this.RightClick.bindAsEventListener(this));
21 21 observingContextMenuClick = true;
22 22 }
23 23
24 24 this.unselectAll();
25 25 this.lastSelected = null;
26 26 },
27 27
28 28 RightClick: function(e) {
29 29 this.hideMenu();
30 30 // do not show the context menu on links
31 31 if (Event.findElement(e, 'a') != document && Event.findElement(e, 'a') != undefined) { return; }
32 32 // right-click simulated by Alt+Click with Opera
33 33 if (window.opera && !e.altKey) { return; }
34 34 var tr = Event.findElement(e, 'tr');
35 35 if (tr == document || tr == undefined || !tr.hasClassName('hascontextmenu')) { return; }
36 36 Event.stop(e);
37 37 if (!this.isSelected(tr)) {
38 38 this.unselectAll();
39 39 this.addSelection(tr);
40 40 this.lastSelected = tr;
41 41 }
42 42 this.showMenu(e);
43 43 },
44 44
45 45 Click: function(e) {
46 46 this.hideMenu();
47 47 if (Event.findElement(e, 'a') != document && Event.findElement(e, 'a') != undefined ) { return; }
48 48 if (window.opera && e.altKey) { return; }
49 49 if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) {
50 50 var tr = Event.findElement(e, 'tr');
51 51 if (tr!=document && tr.hasClassName('hascontextmenu')) {
52 52 // a row was clicked, check if the click was on checkbox
53 53 var box = Event.findElement(e, 'input');
54 54 if (box!=document && box!=undefined) {
55 55 // a checkbox may be clicked
56 56 if (box.checked) {
57 57 tr.addClassName('context-menu-selection');
58 58 } else {
59 59 tr.removeClassName('context-menu-selection');
60 60 }
61 61 } else {
62 62 if (e.ctrlKey) {
63 63 this.toggleSelection(tr);
64 64 } else if (e.shiftKey) {
65 65 if (this.lastSelected != null) {
66 66 var toggling = false;
67 67 var rows = $$('.hascontextmenu');
68 68 for (i=0; i<rows.length; i++) {
69 69 if (toggling || rows[i]==tr) {
70 70 this.addSelection(rows[i]);
71 71 }
72 72 if (rows[i]==tr || rows[i]==this.lastSelected) {
73 73 toggling = !toggling;
74 74 }
75 75 }
76 76 } else {
77 77 this.addSelection(tr);
78 78 }
79 79 } else {
80 80 this.unselectAll();
81 81 this.addSelection(tr);
82 82 }
83 83 this.lastSelected = tr;
84 84 }
85 85 } else {
86 86 // click is outside the rows
87 87 var t = Event.findElement(e, 'a');
88 88 if ((t != document) && (Element.hasClassName(t, 'disabled') || Element.hasClassName(t, 'submenu'))) {
89 89 Event.stop(e);
90 90 }
91 91 }
92 92 }
93 else{
94 this.RightClick(e);
95 }
93 96 },
94 97
95 98 showMenu: function(e) {
96 99 var mouse_x = Event.pointerX(e);
97 100 var mouse_y = Event.pointerY(e);
98 101 var render_x = mouse_x;
99 102 var render_y = mouse_y;
100 103 var dims;
101 104 var menu_width;
102 105 var menu_height;
103 106 var window_width;
104 107 var window_height;
105 108 var max_width;
106 109 var max_height;
107 110
108 111 $('context-menu').style['left'] = (render_x + 'px');
109 112 $('context-menu').style['top'] = (render_y + 'px');
110 113 Element.update('context-menu', '');
111 114
112 115 new Ajax.Updater({success:'context-menu'}, this.url,
113 116 {asynchronous:true,
114 117 evalScripts:true,
115 118 parameters:Form.serialize(Event.findElement(e, 'form')),
116 119 onComplete:function(request){
117 120 dims = $('context-menu').getDimensions();
118 121 menu_width = dims.width;
119 122 menu_height = dims.height;
120 123 max_width = mouse_x + 2*menu_width;
121 124 max_height = mouse_y + menu_height;
122 125
123 126 var ws = window_size();
124 127 window_width = ws.width;
125 128 window_height = ws.height;
126 129
127 130 /* display the menu above and/or to the left of the click if needed */
128 131 if (max_width > window_width) {
129 132 render_x -= menu_width;
130 133 $('context-menu').addClassName('reverse-x');
131 134 } else {
132 135 $('context-menu').removeClassName('reverse-x');
133 136 }
134 137 if (max_height > window_height) {
135 138 render_y -= menu_height;
136 139 $('context-menu').addClassName('reverse-y');
137 140 } else {
138 141 $('context-menu').removeClassName('reverse-y');
139 142 }
140 143 if (render_x <= 0) render_x = 1;
141 144 if (render_y <= 0) render_y = 1;
142 145 $('context-menu').style['left'] = (render_x + 'px');
143 146 $('context-menu').style['top'] = (render_y + 'px');
144 147
145 148 Effect.Appear('context-menu', {duration: 0.20});
146 149 if (window.parseStylesheets) { window.parseStylesheets(); } // IE
147 150 }})
148 151 },
149 152
150 153 hideMenu: function() {
151 154 Element.hide('context-menu');
152 155 },
153 156
154 157 addSelection: function(tr) {
155 158 tr.addClassName('context-menu-selection');
156 159 this.checkSelectionBox(tr, true);
157 160 },
158 161
159 162 toggleSelection: function(tr) {
160 163 if (this.isSelected(tr)) {
161 164 this.removeSelection(tr);
162 165 } else {
163 166 this.addSelection(tr);
164 167 }
165 168 },
166 169
167 170 removeSelection: function(tr) {
168 171 tr.removeClassName('context-menu-selection');
169 172 this.checkSelectionBox(tr, false);
170 173 },
171 174
172 175 unselectAll: function() {
173 176 var rows = $$('.hascontextmenu');
174 177 for (i=0; i<rows.length; i++) {
175 178 this.removeSelection(rows[i]);
176 179 }
177 180 },
178 181
179 182 checkSelectionBox: function(tr, checked) {
180 183 var inputs = Element.getElementsBySelector(tr, 'input');
181 184 if (inputs.length > 0) { inputs[0].checked = checked; }
182 185 },
183 186
184 187 isSelected: function(tr) {
185 188 return Element.hasClassName(tr, 'context-menu-selection');
186 189 }
187 190 }
188 191
189 192 function toggleIssuesSelection(el) {
190 193 var boxes = el.getElementsBySelector('input[type=checkbox]');
191 194 var all_checked = true;
192 195 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
193 196 for (i = 0; i < boxes.length; i++) {
194 197 if (all_checked) {
195 198 boxes[i].checked = false;
196 199 boxes[i].up('tr').removeClassName('context-menu-selection');
197 200 } else if (boxes[i].checked == false) {
198 201 boxes[i].checked = true;
199 202 boxes[i].up('tr').addClassName('context-menu-selection');
200 203 }
201 204 }
202 205 }
203 206
204 207 function window_size() {
205 208 var w;
206 209 var h;
207 210 if (window.innerWidth) {
208 211 w = window.innerWidth;
209 212 h = window.innerHeight;
210 213 } else if (document.documentElement) {
211 214 w = document.documentElement.clientWidth;
212 215 h = document.documentElement.clientHeight;
213 216 } else {
214 217 w = document.body.clientWidth;
215 218 h = document.body.clientHeight;
216 219 }
217 220 return {width: w, height: h};
218 221 }
General Comments 0
You need to be logged in to leave comments. Login now