otsdaq_utilities  v2_02_00
SimpleContextMenu.js
1 //=====================================================================================
2 //
3 // Created Nov, 2016
4 // by Ryan Rivera ((rrivera at fnal.gov))
5 //
6 // SimpleContextMenu.js
7 //
8 // Requirements:
9 // 1. paste the following:
10 //
11 // <script type="text/JavaScript" src="/WebPath/js/Globals.js"></script>
12 // <script type="text/JavaScript" src="/WebPath/js/Debug.js"></script>
13 // <script type="text/JavaScript" src="/WebPath/js/DesktopWindowContentCode.js"></script>
14 // <script type="text/JavaScript" src="/WebPath/js/js_lib/SimpleContextMenu.js"></script>
15 //
16 // ...anywhere inside the <head></head> tag of a window content html page
17 // 2. for proper functionality certain handlers are used:
18 // cannot overwrite handlers for window: onfocus, onscroll, onblur, onmousemove
19 // (if you must overwrite, try to call the DesktopContent handlers from your handlers)
20 //
21 // Recommendations:
22 // 1. use Debug to output status and errors, e.g.:
23 // Debug.log("this is my status",Debug.LOW_PRIORITY); //LOW_PRIORITY, MED_PRIORITY, INFO_PRIORITY, WARN_PRIORITY, HIGH_PRIORITY
24 // 2. call window.focus() to bring your window to the front of the Desktop
25 //
26 // The code of Requirement #1 should be inserted in the header of each page that will be
27 // the content of a window in the ots desktop.
28 //
29 // This code handles bringing the window to the front when the content
30 // is clicked or scrolled.
31 //
32 // Example usage: /WebPath/html/SimpleContextMenuTest.html
33 //
34 //=====================================================================================
35 
36 var SimpleContextMenu = SimpleContextMenu || {}; //define SimpleContextMenu namespace
37 
38 if (typeof Debug == 'undefined')
39  alert('ERROR: Debug is undefined! Must include Debug.js before SimpleContextMenu.js');
40 if (typeof Globals == 'undefined')
41  alert('ERROR: Globals is undefined! Must include Globals.js before SimpleContextMenu.js');
42 if (typeof DesktopContent == 'undefined' &&
43  typeof Desktop == 'undefined')
44  alert('ERROR: DesktopContent is undefined! Must include DesktopContent.js before SimpleContextMenu.js');
45 
46 
47 //"public" function list:
48 // SimpleContextMenu.createMenu(menuItems,menuItemHandlers,popupID,topLeftX,topLeftY, primaryColor, secondaryColor)
49 // SimpleContextMenu.createMenuCallAsString(menuItems,menuItemHandlers,popupID,topLeftX,topLeftY, primaryColor, secondaryColor)
50 
51 //"private" function list:
52 // SimpleContextMenu.mouseMoveHandler(event)
53 // SimpleContextMenu.callMenuItemHandler(event,index)
54 // SimpleContextMenu.handleMouseOverMenuItem(event,index)
55 
56 //"private" members:
57 SimpleContextMenu._popUpEl = 0;
58 SimpleContextMenu._menuItemHandlers = [];
59 SimpleContextMenu._primaryColor = "";
60 SimpleContextMenu._secondaryColor = "";
61 
62 //=====================================================================================
63 //SimpleContextMenu.createMenu
64 // if from event, for left and top use, e.g event.pageX-1,event.pageY-1
65 SimpleContextMenu.createMenu = function(menuItems,menuItemHandlers,
66  popupID,topLeftX,topLeftY, primaryColor, secondaryColor) {
67 
68  // Debug.log("Creating SimpleContextMenu...");
69  // Debug.log("menuItems=" + menuItems);
70  // Debug.log("menuItemHandlers=" + menuItemHandlers);
71  // Debug.log("popupID=" + popupID);
72  // Debug.log("topLeftX=" + topLeftX);
73  // Debug.log("topLeftY=" + topLeftY);
74  // Debug.log("primaryColor=" + primaryColor);
75  // Debug.log("secondaryColor=" + secondaryColor);
76 
77  SimpleContextMenu._menuItemHandlers = menuItemHandlers;
78  SimpleContextMenu._primaryColor = primaryColor;
79  SimpleContextMenu._secondaryColor = secondaryColor;
80 
81  var body = document.getElementsByTagName("BODY")[0];
82  var el = SimpleContextMenu._popUpEl;
83  if(el)
84  {
85  Debug.log("Can not create SimpleContextMenu if one already exists",
86  Debug.MED_PRIORITY);
87  return;
88  }
89 
91  //create the element
92  el = document.createElement("div");
93  el.setAttribute("id", popupID);
94  el.style.display = "none";
95  el.onmousemove = function(e){e.cancelBubble = true;};
96  body.appendChild(el); //add element to body of page
97 
98 
100  //add style for error to page HEAD tag
101  var css = "";
102 
103  css += "#clearDiv {" +
104  "clear: both;" +
105  "}\n\n";
106 
107  //error close link style
108  css += "#" + popupID + "" +
109  "{" +
110  "position:absolute;" +
111  "left:" + topLeftX + "px;" +
112  "top:" + topLeftY + "px;" +
113  "z-index: 1000000;" + //one million!
114  "background-color: " + primaryColor + ";" +
115  "border: 1px solid " + secondaryColor + ";" +
116  "padding: 5px;" +
117  "}\n\n";
118  css += "#" + popupID + " div" +
119  "{" +
120  "color: " + secondaryColor + ";" +
121  "-webkit-user-select: none;" +
122  "-moz-user-select: none;" +
123  "user-select: none;" +
124  "}\n\n";
125  css += "#" + popupID + " div:hover" +
126  "{" +
127  //"text-decoration: underline;" +
128  "background-color: " + secondaryColor + ";" +
129  "color: " + primaryColor + ";" +
130  "cursor: pointer;" +
131  "}\n\n";
132 
133  //add style element to HEAD tag
134  var style = document.createElement('style');
135 
136  if (style.styleSheet) {
137  style.styleSheet.cssText = css;
138  } else {
139  style.appendChild(document.createTextNode(css));
140  }
141 
142  document.getElementsByTagName('head')[0].appendChild(style);
143 
144 
146  //add menu items to element
147  var str = "";
148  for(var i=0;i<menuItems.length;++i)
149  {
150  str +=
151  "<div class='SimpleContextMenu-menuItem' " +
152  "id='SimpleContextMenu-menuItem-" + i + "' " +
153  "onmousemove='SimpleContextMenu.handleMouseOverMenuItem(event," + i + ");' " +
154  //"Debug.log(this.style.backgroundColor);" +
155  //"this.style.backgroundColor = \"" + secondaryColor + "\"; " +
156  //"this.style.color = \"" + primaryColor + "\"; ";
157  //"' " +
158  "onmouseup='SimpleContextMenu.callMenuItemHandler(event," + i + ");' " +
159  ">" +
160  menuItems[i] +
161  "</div>";
162  str += "<div id='clearDiv'></div>";
163  }
164 
165  el.innerHTML = str;
166  el.style.display = "block";
167 
168  SimpleContextMenu._popUpEl = el;
169 }
170 
171 //=====================================================================================
172 //SimpleContextMenu.createMenuCallAsString
173 // create string version of call to SimpleContextMenu.createMenu(...)
174 // this string can be put into an event handler string
175 // e.g. "onmousedown='" + createTreeLinkContextMenuString(...) + "'"
176 SimpleContextMenu.createMenuCallAsString = function(menuItems,menuItemHandlers,
177  popupID, primaryColor, secondaryColor) {
178 
179  var str = "";
180  str += "SimpleContextMenu.createMenu([";
181 
182  //output item strings
183  for(j=0;j<menuItems.length;++j)
184  {
185  if(j)
186  str += ",";
187  str += "\"" + menuItems[j] + "\"";
188  }
189 
190  str += "]," +//end items and open array for item handlers
191  "[";
192 
193  for(j=0;j<menuItemHandlers.length;++j)
194  {
195  //Debug.log("menuItemHandlers[j]= " + menuItemHandlers[j]);
196  //need to escape all quotes by one more level
197  menuItemHandlers[j] = menuItemHandlers[j].replace(/\\\"/g, "AAAAA");
198  menuItemHandlers[j] = menuItemHandlers[j].replace(/"/g, "\\\"");
199  menuItemHandlers[j] = menuItemHandlers[j].replace(/AAAAA/g, "\\\\\\\"");
200  //Debug.log("menuItemHandlers[j]= " + menuItemHandlers[j]);
201  //Debug.log("this works= " + "Debug.log(\\\"hi\\\");");
202  //THIS WORKS: treeViewHandlerStr_ += "\"" + "Debug.log(\\\"hi\\\");" + "\"";
203  str += "\"" + menuItemHandlers[j] + "\"";
204  if(j != menuItemHandlers.length-1)
205  str += ",";
206  }
207  str += "]" + //end menuItemHandlers array
208  ",\"" + popupID + "\",event.pageX-1,event.pageY-1, " +
209  "\"" + primaryColor +
210  "\", \"" + secondaryColor + "\");";
211 
212  return str;
213 }
214 
215 //=====================================================================================
216 //SimpleContextMenu.mouseMoveHandler
217 // subscribe the mouse move handler to DesktopContent.mouseMoveSubscriber
218 // OR if (typeof DesktopContent == 'undefined' then subscribe to Desktop
219 SimpleContextMenu.mouseMoveHandler = function(e) {
220 
221  //Debug.log("moving " + e.pageX + "-" + e.pageY);
222  if(SimpleContextMenu._popUpEl) //delete popup
223  {
224  Debug.log("Removing SimpleContextMenu");
225  SimpleContextMenu._popUpEl.parentNode.removeChild(SimpleContextMenu._popUpEl);
226  SimpleContextMenu._popUpEl = 0;
227  }
228 }
229 //subscribe the mouse move handler (if desktop content or part of actual desktop)
230 if(typeof DesktopContent == 'undefined')
231  Desktop.mouseMoveSubscriber(SimpleContextMenu.mouseMoveHandler);
232 else
233  DesktopContent.mouseMoveSubscriber(SimpleContextMenu.mouseMoveHandler);
234 
235 
236 //=====================================================================================
237 SimpleContextMenu.callMenuItemHandler = function(event,index) {
238  var handler = SimpleContextMenu._menuItemHandlers[index];
239 
240  Debug.log("Removing SimpleContextMenu");
241  SimpleContextMenu._popUpEl.parentNode.removeChild(SimpleContextMenu._popUpEl);
242  SimpleContextMenu._popUpEl = 0;
243 
244  event.cancelBubble = true;
245  event.preventDefault();
246 
247  //Debug.log("SimpleContextMenu.callMenuItemHandler " + handler);
248  if(handler && (typeof handler) == "string") //if handler supplied as string
249  {
250  Debug.log("evaluateJS = " + handler);
251  eval(handler);
252  return false;
253  }
254  else //assume it is a function
255  {
256  handler(event, index);
257  return false;
258  }
259 }
260 
261 //=====================================================================================
262 //SimpleContextMenu.handleMouseOverMenuItem
263 SimpleContextMenu.handleMouseOverMenuItem = function(event,index) {
264  event.cancelBubble = true;
265 
266  //Debug.log(index);
267  //set colors properly for mouse over
268 
269  var el;
270  for(var i=0;i<SimpleContextMenu._menuItemHandlers.length;++i)
271  {
272  el = document.getElementById("SimpleContextMenu-menuItem-" + i);
273  if(i == index) //hovered one
274  {
275  el.style.backgroundColor = SimpleContextMenu._secondaryColor;
276  el.style.color = SimpleContextMenu._primaryColor;
277  }
278  else
279  {
280  el.style.backgroundColor = SimpleContextMenu._primaryColor;
281  el.style.color = SimpleContextMenu._secondaryColor;
282  }
283  }
284 }
285 
286 
287 
288 
289 
290 
291 
292 
293 
294 
295 
296 
297