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