Project

General

Profile

Defect #960 » context_menu.js

the file (incase the patch does not work) - Mike Duchene, 2008-04-03 03:42

 
1
/* redMine - project management software
2
   Copyright (C) 2006-2008  Jean-Philippe Lang */
3

    
4
var observingContextMenuClick;
5

    
6
ContextMenu = Class.create();
7
ContextMenu.prototype = {
8
	initialize: function (url) {
9
	this.url = url;
10

    
11
	// prevent selection when using Ctrl/Shit key
12
	var tables = $$('table.issues');
13
	for (i=0; i<tables.length; i++) {
14
		tables[i].onselectstart = function () { return false; } // ie
15
		tables[i].onmousedown = function () { return false; } // mozilla
16
	}
17

    
18
	if (!observingContextMenuClick) {
19
		Event.observe(document, 'click', this.Click.bindAsEventListener(this));
20
		Event.observe(document, (window.opera ? 'click' : 'contextmenu'), this.RightClick.bindAsEventListener(this));
21
		observingContextMenuClick = true;
22
	}
23
	
24
	this.unselectAll();
25
	this.lastSelected = null;
26
	},
27
  
28
	RightClick: function(e) {
29
		this.hideMenu();
30
		// do not show the context menu on links
31
		if (Event.findElement(e, 'a') != document) { return; }
32
		// right-click simulated by Alt+Click with Opera
33
		if (window.opera && !e.altKey) { return; }
34
		var tr = Event.findElement(e, 'tr');
35
		if ((tr == document) || !tr.hasClassName('hascontextmenu')) { return; }
36
		Event.stop(e);
37
		if (!this.isSelected(tr)) {
38
			this.unselectAll();
39
			this.addSelection(tr);
40
			this.lastSelected = tr;
41
		}
42
		this.showMenu(e);
43
	},
44

    
45
  Click: function(e) {
46
  	this.hideMenu();
47
  	if (Event.findElement(e, 'a') != document) { return; }
48
    if (window.opera && e.altKey) {	return; }
49
    if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) {      
50
      var tr = Event.findElement(e, 'tr');
51
      if (tr!=document && tr.hasClassName('hascontextmenu')) {
52
        // a row was clicked, check if the click was on checkbox
53
        var box = Event.findElement(e, 'input');
54
        if (box!=document) {
55
          // a checkbox may be clicked
56
          if (box.checked) {
57
            tr.addClassName('context-menu-selection');
58
          } else {
59
            tr.removeClassName('context-menu-selection');
60
          }
61
        } else {
62
          if (e.ctrlKey) {
63
            this.toggleSelection(tr);
64
          } else if (e.shiftKey) {
65
            if (this.lastSelected != null) {
66
              var toggling = false;
67
              var rows = $$('.hascontextmenu');
68
              for (i=0; i<rows.length; i++) {
69
                if (toggling || rows[i]==tr) {
70
                  this.addSelection(rows[i]);
71
                }
72
                if (rows[i]==tr || rows[i]==this.lastSelected) {
73
                  toggling = !toggling;
74
                }
75
              }
76
            } else {
77
              this.addSelection(tr);
78
            }
79
          } else {
80
            this.unselectAll();
81
            this.addSelection(tr);
82
          }
83
          this.lastSelected = tr;
84
        }
85
      } else {
86
        // click is outside the rows
87
        var t = Event.findElement(e, 'a');
88
        if ((t != document) && (Element.hasClassName(t, 'disabled') || Element.hasClassName(t, 'submenu'))) {
89
          Event.stop(e);
90
        }
91
      }
92
    }
93
  },
94
  
95
  showMenu: function(e) {
96
    var mouse_x = Event.pointerX(e);
97
    var mouse_y = Event.pointerY(e);
98
    var render_x = mouse_x;
99
    var render_y = mouse_y;
100
    var dims;
101
    var menu_width;
102
    var menu_height;
103
    var window_width;
104
    var window_height;
105
    var max_width;
106
    var max_height;
107

    
108
    $('context-menu').style['left'] = (render_x + 'px');
109
    $('context-menu').style['top'] = (render_y + 'px');		
110
    Element.update('context-menu', '');
111

    
112
    new Ajax.Updater({success:'context-menu'}, this.url, 
113
      {asynchronous:true,
114
       evalScripts:true,
115
       parameters:Form.serialize(Event.findElement(e, 'form')),
116
       onComplete:function(request){
117
	 dims = $('context-menu').getDimensions();
118
	 menu_width = dims.width;
119
	 menu_height = dims.height;
120

    
121
	 max_width = mouse_x + 2*menu_width;
122
	 max_height = mouse_y + menu_height;
123

    
124
	 var ws = window_size();
125
	 window_width = ws.width;
126
	 window_height = ws.height;
127

    
128
	 if (max_width > window_width) {
129
	   render_x -= menu_width;
130
	 }
131
	 if (max_height > window_height) {
132
	   render_y -= menu_height;
133
	 }
134
	 if (render_x <= 0) render_x = 1;
135
	 if (render_y <= 0) render_y = 1;
136
	 $('context-menu').style['left'] = (render_x + 'px');
137
	 $('context-menu').style['top'] = (render_y + 'px');		
138

    
139
// this code can be used for debugging
140
//	 alert("menu_width=" + menu_width + "\nmenu_height=" + menu_height + "\nmouse_x=" + mouse_x + "\nmouse_y=" + mouse_y +
141
//	 "\nwindow_width=" + window_width + "\nwindow_height=" + window_height + "\nrender_x=" + render_x + "\nrender_y=" + render_y);
142

    
143
         Effect.Appear('context-menu', {duration: 0.20});
144
         if (window.parseStylesheets) { window.parseStylesheets(); } // IE
145
      }})
146
  },
147
  
148
  hideMenu: function() {
149
    Element.hide('context-menu');
150
  },
151
  
152
  addSelection: function(tr) {
153
    tr.addClassName('context-menu-selection');
154
    this.checkSelectionBox(tr, true);
155
  },
156
  
157
  toggleSelection: function(tr) {
158
    if (this.isSelected(tr)) {
159
      this.removeSelection(tr);
160
    } else {
161
      this.addSelection(tr);
162
    }
163
  },
164
  
165
  removeSelection: function(tr) {
166
    tr.removeClassName('context-menu-selection');
167
    this.checkSelectionBox(tr, false);
168
  },
169
  
170
  unselectAll: function() {
171
    var rows = $$('.hascontextmenu');
172
    for (i=0; i<rows.length; i++) {
173
      this.removeSelection(rows[i]);
174
    }
175
  },
176
  
177
  checkSelectionBox: function(tr, checked) {
178
  	var inputs = Element.getElementsBySelector(tr, 'input');
179
  	if (inputs.length > 0) { inputs[0].checked = checked; }
180
  },
181
  
182
  isSelected: function(tr) {
183
    return Element.hasClassName(tr, 'context-menu-selection');
184
  }
185
}
186

    
187
function toggleIssuesSelection(el) {
188
	var boxes = el.getElementsBySelector('input[type=checkbox]');
189
	var all_checked = true;
190
	for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
191
	for (i = 0; i < boxes.length; i++) {
192
		if (all_checked) {
193
			boxes[i].checked = false;
194
			boxes[i].up('tr').removeClassName('context-menu-selection');
195
		} else if (boxes[i].checked == false) {
196
			boxes[i].checked = true;
197
			boxes[i].up('tr').addClassName('context-menu-selection');
198
		}
199
	}
200
}
201

    
202
function window_size() {
203
    var w;
204
    var h;
205
    if (window.innerWidth) {
206
	w = window.innerWidth;
207
	h = window.innerHeight;
208
    } else if (document.documentElement) {
209
	w = document.documentElement.clientWidth;
210
	h = document.documentElement.clientHeight;
211
    } else {
212
	w = document.body.clientWidth;
213
	h = document.body.clientHeight;
214
    }
215
    return {width: w, height: h};
216
}
(2-2/2)