otsdaq_utilities  v2_05_02_indev
DesktopContent.js
1 //=====================================================================================
2 //
3 // Created Jan, 2013
4 // by Ryan Rivera ((rrivera at fnal.gov))
5 //
6 // DesktopContent.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/DesktopContent.js"></script>
14 //
15 // ...anywhere inside the <head></head> tag of a window content html page
16 // 2. for proper functionality certain handlers are used:
17 // cannot overwrite handlers for window: onfocus, onscroll, onblur, onmousemove
18 // (if you must overwrite, try to call the DesktopContent handlers from your handlers)
19 //
20 // 3. When all functionality is available init() be called in your page, if defined.
21 //
22 // Recommendations:
23 // 1. use Debug to output status and errors, e.g.:
24 // Debug.log("this is my status",Debug.LOW_PRIORITY); //LOW_PRIORITY, MED_PRIORITY, HIGH_PRIORITY
25 // 2. call window.focus() to bring your window to the front of the Desktop
26 //
27 // The code of Requirement #1 should be inserted in the header of each page that will be
28 // the content of a window in the ots desktop.
29 //
30 // This code handles bringing the window to the front when the content
31 // is clicked or scrolled.
32 //
33 // This code also handles server requests and response handlers for the content code:
34 // -DesktopContent.XMLHttpRequest(requestURL, data, returnHandler <optional>,
35 // reqParam <optional>, progressHandler <optional>, callHandlerOnErr <optional>,
36 // doNotShowLoadingOverlay <optional>, targetSupervisor <optional>, ignoreSystemBlock <optional>,
37 // doNotOfferSequenceChange <optional>)
38 //
39 // ... here is an example request:
40 //
41 // DesktopContent.XMLHttpRequest("Request?" +
42 //
43 // //get data
44 // "RequestType=exportFEMacro" +
45 // "&MacroName=" + macroName +
46 // "&PluginName=" + targetFEPluginName,
47 //
48 // //post data
49 // "MacroSequence=" + macroSequence +
50 // "&MacroNotes=" + encodeURIComponent(macroNotes),
51 //
52 // //request handler
53 // function(req)
54 // {
55 // //..do something on successful response
56 // Debug.log("Success!",Debug.INFO_PRIORITY);
57 // }, //end request handler
58 // 0 /*reqParam*/, 0 /*progressHandler*/, false /*callHandlerOnErr*/,
59 // false /*doNotShowLoadingOverlay*/); //end XMLHttpRequest() call
60 //
61 // ... after a server request, returnHandler is called with response in req and reqParam if user defined
62 // ... here is a returnHandler declaration example:
63 //
64 // function returnHandler(req,reqParam,errStr)
65 // {
66 // if(errStr != "") return; //error occured!
67 //
68 // var err = DesktopContent.getXMLValue(req,"Error"); //example application level error
69 // if(err)
70 // {
71 // Debug.log(err,Debug.HIGH_PRIORITY); //log error and create pop-up error box
72 // return;
73 // }
74 //
75 // if(reqParam = 0)
76 // { //... do something }
77 // else if(reqParam = 1)
78 // { //... do something else}
79 // else
80 // { //... do something else}
81 //
82 // //..do more things
83 //
84 // }
85 //
86 // -DesktopContent.getXMLValue(req, name)
87 // ... to get string value from XML server response. field name is needed.
88 //
89 // ... or to get array of elements by tag name
90 // var els = req.responseXML.getElementsByTagName(name);
91 // for(var i=0;i<els.length;++i)
92 // Debug.log(els[i].getAttribute("value"));
93 //
94 //
95 // Additional Functionality:
96 // DesktopContent.popUpVerification(prompt, func [optional], val [optional], bgColor [optional],
97 // textColor [optional], borderColor [optional], getUserInput [optional],
98 // dialogWidth [optional], cancelFunc [optional], yesButtonText [optional])
99 // DesktopContent.tooltip(uid,tip)
100 // DesktopContent.getWindowWidth()
101 // DesktopContent.getWindowHeight()
102 // DesktopContent.getWindowScrollLeft()
103 // DesktopContent.getWindowScrollTop()
104 // DesktopContent.getMouseX()
105 // DesktopContent.getMouseY()
106 // DesktopContent.getDefaultWindowColor() // returns "rgb(#,#,#)"
107 // DesktopContent.getDefaultDashboardColor()// returns "rgb(#,#,#)"
108 // DesktopContent.getDefaultDesktopColor() // returns "rgb(#,#,#)"
109 // DesktopContent.getUsername()
110 // DesktopContent.openNewWindow(name,subname,windowPath,unique,completeHandler)
111 // DesktopContent.openNewBrowserTab(name,subname,windowPath,unique,completeHandler)
112 // DesktopContent.addDesktopIcon(iconName)
113 //
114 //=====================================================================================
115 
116 var DesktopContent = DesktopContent || {}; //define Desktop namespace
117 
118 if (typeof Debug == 'undefined')
119  alert('ERROR: Debug is undefined! Must include Debug.js before DesktopContent.js');
120 if (typeof Globals == 'undefined')
121  alert('ERROR: Globals is undefined! Must include Globals.js before DesktopContent.js');
122 
123 
124 //"public" function list:
125 // DesktopContent.XMLHttpRequest(requestURL, data, returnHandler, reqParam, progressHandler, callHandlerOnErr, doNotShowLoadingOverlay, targetSupervisor, ignoreSystemBlock)
126 // DesktopContent.getXMLValue(req, name)
127 // DesktopContent.getXMLNode(req, name)
128 // DesktopContent.getXMLDataNode(req)
129 // DesktopContent.getXMLAttributeValue(req, name, attribute)
130 // DesktopContent.getXMLChildren(req, nodeName)
131 // DesktopContent.getXMLRequestErrors(req)
132 // DesktopContent.systemBlackout(doBlackout)
133 // DesktopContent.popUpVerification(prompt, func, val, bgColor, textColor, borderColor, getUserInput, dialogWidth, cancelFunc)
134 // DesktopContent.setPopUpPosition(el,w,h,padding,border,margin,doNotResize,offsetUp)
135 // DesktopContent.tooltip(uid,tip)
136 // DesktopContent.setWindowTooltip(tip)
137 // DesktopContent.getWindowWidth()
138 // DesktopContent.getWindowHeight()
139 // DesktopContent.getWindowScrollLeft()
140 // DesktopContent.getWindowScrollTop()
141 // DesktopContent.getBodyWidth()
142 // DesktopContent.getBodyHeight()
143 // DesktopContent.getMouseX()
144 // DesktopContent.getMouseY()
145 // DesktopContent.getDefaultWindowColor()
146 // DesktopContent.getDefaultDashboardColor()
147 // DesktopContent.getDefaultDesktopColor()
148 // DesktopContent.getUsername()
149 // DesktopContent.openNewWindow(name,subname,windowPath,unique,completeHandler)
150 // DesktopContent.mouseMoveSubscriber(newHandler)
151 // DesktopContent.openNewBrowserTab(name,subname,windowPath,unique,completeHandler)
152 // DesktopContent.addDesktopIcon(iconName)
153 // DesktopContent.getParameter(index, name)
154 // DesktopContent.getDesktopParameter(index, name)
155 // DesktopContent.getDesktopWindowTitle()
156 // DesktopContent.showLoading()
157 // DesktopContent.hideLoading()
158 
159 //"private" function list:
160 // DesktopContent.init()
161 // DesktopContent.handleFocus(e)
162 // DesktopContent.handleBlur(e)
163 // DesktopContent.handleScroll(e)
164 // DesktopContent.mouseMove(mouseEvent)
166 // DesktopContent.clearPopUpVerification(func)
167 // DesktopContent.parseColor(colorStr)
168 // DesktopContent.tooltipSetAlwaysShow(srcFunc,srcFile,srcId,neverShow,temporarySilence)
169 // DesktopContent.tooltipConditionString(str);
170 
171 DesktopContent._theWindowId = -1;
172 
173 DesktopContent._isFocused = false;
174 DesktopContent._theWindow;
175 DesktopContent._theDesktopWindow;
176 //DesktopContent._myDesktopFrame ;
177 
178 
179 
180 
181 
182 
183 //DesktopContent._zMailbox = 0;
184 //DesktopContent._mouseOverXmailbox;
185 //DesktopContent._mouseOverYmailbox;
186 DesktopContent._updateMouseOverMailboxTimer = 0;
187 DesktopContent._windowMouseX = -1;
188 DesktopContent._windowMouseY = -1;
189 
190 DesktopContent._serverOrigin = "";
191 DesktopContent._localOrigin = "";
192 DesktopContent._serverUrnLid = 0;
193 DesktopContent._localUrnLid = 0;
194 
195 DesktopContent._cookieCodeMailbox = 0;
196 DesktopContent._updateTimeMailbox = 0;
197 DesktopContent._lastCookieCode = 0;
198 DesktopContent._lastCookieTime = 0;
199 DesktopContent._updateCookieCodeTimer = 0;
200 
201 DesktopContent._needToLoginMailbox = false;
202 //DesktopContent._openWindowMailbox = 0;
203 DesktopContent._blockSystemCheckMailbox = false;
204 DesktopContent._windowColorPostbox;
205 DesktopContent._dashboardColorPostbox;
206 DesktopContent._desktopColor;
207 
208 DesktopContent._verifyPopUp = 0;
209 DesktopContent._verifyPopUpId = "DesktopContent-verifyPopUp";
210 
211 
212 DesktopContent._sequence = 0;
213 
214 DesktopContent._mouseMoveSubscribers = [];
215 DesktopContent._pageInitCalled = false;
216 
217 //=====================================================================================
218 //initialize content's place in the world
219 // caution when using "window" anywhere outside this function because
220 // desktop window can be at different levels depending on page depth (page may be inside frame)
221 // use instead DesktopContent._theWindow
222 DesktopContent.init = function()
223 {
224  if(typeof Desktop !== 'undefined') return; //skip if Desktop exists (only using for tooltip), DesktopContent._theWindow will be undefined
225 
226  var tmpCnt = 0;
227  DesktopContent._theWindow = self;
228  while(tmpCnt++ < 5 && DesktopContent._theWindow && //while can not find the top window frame in the desktop
229  DesktopContent._theWindow.window.name.search("DesktopWindowFrame") < 0)
230  DesktopContent._theWindow = DesktopContent._theWindow.parent;
231 
232  DesktopContent._theWindow = DesktopContent._theWindow.window;
233  DesktopContent._theDesktopWindow = DesktopContent._theWindow.parent.window;
234  //DesktopContent._myDesktopFrame = DesktopContent._theWindow.parent.document.getElementById(DesktopContent._theWindow.name);
235 
236 
237 // try
238 // {
239 // --- DesktopContent._myDesktopFrame = DesktopContent._theWindow.parent.document.getElementById(DesktopContent._theWindow.name);
240 // --- DesktopContent._zMailbox = DesktopContent._theWindow.parent.document.getElementById("Desktop-windowZmailbox");
241 // --- DesktopContent._mouseOverXmailbox = DesktopContent._theWindow.parent.document.getElementById("Desktop-mouseOverXmailbox");
242 // --- DesktopContent._mouseOverYmailbox = DesktopContent._theWindow.parent.document.getElementById("Desktop-mouseOverYmailbox");
243 //
244 // DesktopContent._cookieCodeMailbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-cookieCodeMailbox");
245 // DesktopContent._updateTimeMailbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-updateTimeMailbox");
246 // DesktopContent._needToLoginMailbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-needToLoginMailbox");
247 // DesktopContent._openWindowMailbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-openWindowMailbox");
248 // DesktopContent._blockSystemCheckMailbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-blockSystemCheckMailbox");
249 //
250 // DesktopContent._windowColorPostbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-windowColorPostbox");
251 // DesktopContent._dashboardColorPostbox = DesktopContent._theWindow.parent.document.getElementById("DesktopContent-dashboardColorPostbox");
252 //
253 //
254 // if(DesktopContent._theWindow.parent.document.body)
255 // DesktopContent._desktopColor = DesktopContent._theWindow.parent.document.body.style.backgroundColor;
256 // }
257 // catch(e)
258 // {
259 // Debug.log("Ignoring window mailbox error during init(): " + e);
260 // }
261 
262  window.onfocus = DesktopContent.handleFocus;
263  window.onmousedown = DesktopContent.handleFocus;
264  window.onscroll = DesktopContent.handleScroll;
265  window.onblur = DesktopContent.handleBlur;
266  window.onmousemove = DesktopContent.mouseMove; //setup mouse move handler
267  window.focus();
268  DesktopContent._theWindow.focus(); //before this fix, full screen in new tab would not give window focus
269 
270 
271 // try
272 // {
273 // DesktopContent._serverUrnLid = DesktopContent.getDesktopWindowParameter(0,"urn");//((DesktopContent._theWindow.parent.window.location.search.substr(1)).split('='))[1];
274 // if(typeof DesktopContent._serverUrnLid == 'undefined')
275 // Debug.log("ERROR -- Gateway Supervisor Application URN-LID not found!"); //,Debug.HIGH_PRIORITY);
276 // Debug.log("Gateway Supervisor Application URN-LID #" + DesktopContent._serverUrnLid);
277 // DesktopContent._serverOrigin = DesktopContent._theWindow.parent.window.location.origin;
278 // Debug.log("Gateway Supervisor Application Origin = " + DesktopContent._serverOrigin);
279 // }
280 // catch(e)
281 // {
282 // Debug.log("Ignoring Gateway extract error during init(): " + e);
283 //
284 // DesktopContent._serverUrnLid = 200;
285 // DesktopContent._serverOrigin = "http://correlator2.fnal.gov:2015";
286 //
287 //
288 // }
289 
290 
291  //can always get local server info from URL
292  Debug.log("Window URL " + window.location.href);
293  DesktopContent._localUrnLid = DesktopContent.getParameter(0,"urn");
294  if(typeof DesktopContent._localUrnLid == 'undefined')
295  DesktopContent._localUrnLid = 0;
296  DesktopContent._localOrigin = window.location.origin;
297 
298  Debug.log("Local Application URN-LID #" + DesktopContent._localUrnLid);
299  Debug.log("Local Application Origin = " + DesktopContent._localOrigin);
300 
301  //get Wizard sequence (if in Wizard mode)
302  try
303  {
304  DesktopContent._sequence = DesktopContent.getDesktopParameter(0,"code");
305  if(!DesktopContent._sequence || DesktopContent._sequence == "")
306  DesktopContent._sequence = 0; //normal desktop mode
307  else
308  Debug.log("In Wizard Mode with Sequence=" + DesktopContent._sequence);
309  }
310  catch(e)
311  {
312  Debug.log("Could not find wiz mode sequence. Assuming normal mode.");
313  DesktopContent._sequence = 0; //normal desktop mode
314  }
315 
316 
317  // DesktopContent._theWindow.parent.window.postMessage(
318  // {
319  // "req": "getsome"
320  // }, "*");
321 
322  //create message request listener for messages from desktop, to overcome same-origin policy
323  //The first message is initiated by the Desktop once the window frame has been loaded.
324  DesktopContent._theWindow.addEventListener('message', event => {
325 
326  console.log("Child event.data",event.data);
327 
328 
329  if(!event.data.windowId)
330  {
331  Debug.log("Illegal message received!");
332  return;
333  }
334 
335  if(!event.data.request)
336  {
337  if(DesktopContent._pageInitCalled) return;
338  DesktopContent._pageInitCalled = true;
339 
340  Debug.log("First message from Gateway Desktop received!");
341 
342  DesktopContent._theWindowId = event.data.windowId;
343  DesktopContent._serverUrnLid = event.data.gatewayURN;
344  DesktopContent._serverOrigin = event.data.gatewayOrigin;
345 
346  DesktopContent._dashboardColorPostbox = event.data.dashboardColor;
347  DesktopContent._desktopColor = event.data.desktopColor;
348  DesktopContent._windowColorPostbox = event.data.windowFrameColor;
349 
350 
351  if(event.data.cookieCode)
352  {
353  DesktopContent._cookieCodeMailbox = event.data.cookieCode;
354 
355  //========
356  function localUpdateCookieCode()
357  {
358  window.clearTimeout(DesktopContent._updateCookieCodeTimer);
359 
360  Debug.log("localUpdateCookieCode");
361  var deltaTime = parseInt((new Date()).getTime()) - //in ms
362  parseInt(DesktopContent._updateTimeMailbox);
363  if(deltaTime > 30)
364  {
365  Debug.log("Requesting updated cooking code from desktop");
366 
367  DesktopContent._theDesktopWindow.postMessage(
368  {
369  "windowId": DesktopContent._theWindowId,
370  "request": "getCookieCode"
371  },"*");
372  }
373  else
374  Debug.log("No need to update deltaTime=" + deltaTime);
375 
376  DesktopContent._updateCookieCodeTimer = window.setTimeout(
377  localUpdateCookieCode,30*1000 /*ms*/);
378  } //end localUpdateCookieCode()
379 
380  //from now on check for a new cookie code every 30 seconds
381  localUpdateCookieCode();
382  }
383  else if(!DesktopContent._sequence)
384  Debug.log("No cookie code and no sequence!");
385 
386  Debug.log("The Desktop Window ID = " + DesktopContent._theWindowId);
387  Debug.log("Gateway Supervisor Application URN-LID #" + DesktopContent._serverUrnLid);
388  Debug.log("Gateway Supervisor Application Origin = " + DesktopContent._serverOrigin);
389 
390  if(init)
391  {
392  Debug.log("Calling page init!");
393  init(); //call pages init!
394  }
395 
396  // DesktopContent._theWindow.parent.window.postMessage(
397  // {
398  // "windowId": (event.data.windowId|0),
399  // "req": "childWindowRequest"
400  // }, "*");
401  }
402  else
403  {
404 
405  Debug.log("Request or Response!");
406 
407  if(DesktopContent._theWindowId != event.data.windowId)
408  {
409  Debug.med("Impossible desktop message violation! Notify admins. May happen if users click around during window refresh?");
410  return;
411  }
412 
413  switch(event.data.request)
414  {
415  case "getCookieCode" + "Response":
416  DesktopContent._cookieCodeMailbox = event.data.cookieCode;
417  console.log("getCookieCode" + "Response");
418  break;
419  case "loginNotify":
420  DesktopContent._needToLoginMailbox = false;
421  console.log("loginNotify",DesktopContent._needToLoginMailbox);
422  break;
423  case "startNeedingMouseXY":
424  DesktopContent._desktopNeedsMouseXY = true;
425  console.log("_desktopNeedsMouseXY", DesktopContent._desktopNeedsMouseXY);
426  break;
427  case "stopNeedingMouseXY":
428  DesktopContent._desktopNeedsMouseXY = false;
429  console.log("_desktopNeedsMouseXY", DesktopContent._desktopNeedsMouseXY);
430  break;
431  default:
432  Debug.log("Illegal response received from Desktop! Notify admins", Debug.HIGH_PRIORITY);
433  return;
434  }
435 
436  }
437  });
438 
439 } //end DesktopContent.init()
440 
441 //=====================================================================================
442 //DesktopContent.getParameter ~
443 // returns the value of the url GET parameter specified by index
444 // if using name, then (mostly) ignore index
445 // Note: in normal mode the first two params are only separated by = (no &'s) for historical reasons
446 DesktopContent.getParameter = function(index,name)
447 {
448  // Debug.log(window.location)
449  var params = (window.location.search.substr(1)).split('&');
450  var spliti, vs;
451  //if name given, make it the priority
452  if(name)
453  {
454  for(index=0;index<params.length;++index)
455  {
456  spliti = params[index].indexOf('=');
457  if(spliti < 0) continue; //poorly formed parameter?
458  vs = [params[index].substr(0,spliti),params[index].substr(spliti+1)];
459  if(decodeURIComponent(vs[0]) == name)
460  return decodeURIComponent(vs[1]);
461  }
462  return; //return undefined .. name not found
463  }
464 
465  //using index
466  if(index >= params.length) return; //return undefined
467 
468  spliti = params[index].indexOf('=');
469  if(spliti < 0) return; //return undefined
470  vs = [params[index].substr(0,spliti),params[index].substr(spliti+1)];
471  return decodeURIComponent(vs[1]); //return value
472 } //end DesktopContent.getParameter()
473 
474 //=====================================================================================
475 //DesktopContent.getDesktopParameter ~
476 // returns the value of the url GET parameter specified by index of the Desktop url
477 // if using name, then (mostly) ignore index
478 DesktopContent.getDesktopParameter = function(index, name)
479 {
480  try{
481  // Debug.log(window.location)
482 
483  var win = DesktopContent._theWindow;
484  if(!win) //for parameter directly from desktop code
485  win = window.parent.window;
486  else
487  win = win.parent.parent.window;
488  var params = (win.location.search.substr(1)).split('&');
489  if(index >= params.length) return; //return undefined
490  var spliti, vs;
491  //if name given, make it the priority
492  if(name)
493  {
494  for(var index=0;index<params.length;++index)
495  {
496  spliti = params[index].indexOf('=');
497  if(spliti < 0) continue; //poorly formed parameter?
498  vs = [params[index].substr(0,spliti),params[index].substr(spliti+1)];
499  if(vs[0] == name)
500  return decodeURIComponent(vs[1]);
501  }
502  return; //return undefined .. name not found
503  }
504 
505  spliti = params[index].indexOf('=');
506  if(spliti < 0) return; //return undefined
507  vs = [params[index].substr(0,spliti),params[index].substr(spliti+1)];
508  return decodeURIComponent(vs[1]); //return value
509  }
510  catch(e)
511  {
512  Debug.log("Ignoring get desktop parameter error :" + e);
513  return;
514  }
515 } //end DesktopContent.getDesktopParameter()
516 
517 //=====================================================================================
518 //DesktopContent.getDesktopWindowParameter ~
519 // returns the value of the url GET parameter specified by index of the Window frame url
520 // if using name, then (mostly) ignore index
521 DesktopContent.getDesktopWindowParameter = function(index, name)
522 {
523  // Debug.log(window.location)
524 
525  var win = DesktopContent._theWindow;
526  if(!win) //for parameter directly from desktop code
527  win = window;
528  else
529  win = win.parent.window;
530 
531  //fix/standardize search string
532  var searchStr = win.location.search.substr(1);
533  var i = searchStr.indexOf("=securityType");
534  if(i > 0) searchStr = searchStr.substr(0,i) + '&' + searchStr.substr(i+1);
535 
536  var params = ((searchStr)).split('&');
537  if(index >= params.length) return; //return undefined
538  var spliti, vs;
539  //if name given, make it the priority
540  if(name)
541  {
542  for(var index=0;index<params.length;++index)
543  {
544  spliti = params[index].indexOf('=');
545  if(spliti < 0) continue; //poorly formed parameter?
546  vs = [params[index].substr(0,spliti),params[index].substr(spliti+1)];
547  if(vs[0] == name)
548  return decodeURIComponent(vs[1]);
549  }
550  return; //return undefined .. name not found
551  }
552 
553  spliti = params[index].indexOf('=');
554  if(spliti < 0) return; //return undefined
555  vs = [params[index].substr(0,spliti),params[index].substr(spliti+1)];
556  return decodeURIComponent(vs[1]); //return value
557 } //end DesktopContent.getDesktopWindowParameter()
558 
559 //=====================================================================================
560 //DesktopContent.handleFocus ~
561 DesktopContent.handleFocus = function(e)
562 { //access z-index mailbox on desktop, increment by 1 and set parent's z-index
563 
564  if(DesktopContent._theWindowId < 0) return; //only happen if not part of desktop, or before init
565 
566  Debug.log("Focus DesktopContent._isFocused " + DesktopContent._isFocused);
567  DesktopContent._isFocused = true;
568 
569  //make this window the desktop foreground window
570  DesktopContent._theDesktopWindow.postMessage(
571  {
572  "windowId": DesktopContent._theWindowId,
573  "request": "makeForeWindow"
574  },"*");
575 
576 // DesktopContent._myDesktopFrame.parentNode.parentNode.style.zIndex = DesktopContent._zMailbox.innerHTML;
577 // DesktopContent._zMailbox.innerHTML = parseInt(DesktopContent._zMailbox.innerHTML) + 1;
578  return true;
579 }
580 DesktopContent.handleBlur = function(e)
581 {
582  //Debug.log("Blur DesktopContent._isFocused " + DesktopContent._isFocused);
583  DesktopContent._isFocused = false;
584 }
585 DesktopContent.handleScroll = function(e)
586 {
587  //Debug.log("Scroll DesktopContent._isFocused" + DesktopContent._isFocused);
588  window.focus();
589 }
590 DesktopContent.mouseMove = function(mouseEvent,onlyDesktopFunction)
591 {
592  //console.log("desktop move",DesktopContent._mouseMoveSubscribers.length);
593  //Debug.log("Move DesktopContent._isFocused=" + DesktopContent._isFocused);
594 
595  //call each subscriber
596  for(var i=0; !onlyDesktopFunction && i<DesktopContent._mouseMoveSubscribers.length; ++i)
597  DesktopContent._mouseMoveSubscribers[i](mouseEvent);
598 
599  if(!DesktopContent._theWindow) return; //only happens if not part of desktop
600 
601  DesktopContent._windowMouseX = parseInt(mouseEvent.clientX);
602  DesktopContent._windowMouseY = parseInt(mouseEvent.clientY);
603 
604  if(DesktopContent._desktopNeedsMouseXY)
605  localUpdateMouseOverMailbox();
606 
607 // window.clearTimeout(DesktopContent._updateMouseOverMailboxTimer);
608 // DesktopContent._updateMouseOverMailboxTimer = //avoid updating mailbox too often
609 // window.setTimeout(localUpdateMouseOverMailbox,500);
610  return;
611 
612  //==================
613  //This is used by desktop for resizing the Dashboard and other Windows
614  // while mouse is in this window
615  function localUpdateMouseOverMailbox()
616  {
617  console.log("Update desktop mouse");//,DesktopContent._mouseOverXmailbox,DesktopContent._mouseOverYmailbox);
618 
619  DesktopContent._theDesktopWindow.postMessage(
620  {
621  "windowId": DesktopContent._theWindowId,
622  "request": "updateMouseoverXY",
623  "x": DesktopContent._windowMouseX,
624  "y": DesktopContent._windowMouseY
625  },"*");
626 
627 
628 // DesktopContent._mouseOverXmailbox.innerHTML = parseInt(DesktopContent._myDesktopFrame.parentNode.parentNode.offsetLeft) +
629 // parseInt(DesktopContent._myDesktopFrame.offsetLeft) + DesktopContent._windowMouseX;
630 // DesktopContent._mouseOverYmailbox.innerHTML = parseInt(DesktopContent._myDesktopFrame.parentNode.parentNode.offsetTop) +
631 // parseInt(DesktopContent._myDesktopFrame.offsetTop) + DesktopContent._windowMouseY;
632  } //end localUpdateMouseOverMailbox()
633 
634 
635 } //end DesktopContent.mouseMove()
636 
637 //=====================================================================================
638 DesktopContent.mouseMoveSubscriber = function(newHandler)
639 {
640  DesktopContent._mouseMoveSubscribers.push(newHandler);
641 } //end DesktopContent.mouseMoveSubscriber()
642 
643 
644 DesktopContent.init(); //initialize handlers
645 
646 
647 //=====================================================================================
648 // XML request helpers
649 //=====================================================================================
650 
651 //used by DesktopContent.XMLHttpRequest to reject multiple calls to same handler
652 //(this is a result of bad error handling in the desktop window page.. so this is meant to inform the developer to fix the issue)
653 DesktopContent._arrayOfFailedHandlers = new Array();
654 
655 //=====================================================================================
656 //=====================================================================================
657 //Loading pop up helpers
658 DesktopContent._loadBox = 0;
659 DesktopContent._loadBoxId = "DesktopContent-load-box";
660 DesktopContent._loadBoxTimer = 0;
661 DesktopContent._loadBoxRequestStack = 0; //load box is not removed until back to 0
662 
663 //=====================================================================================
664 //DesktopContent.showLoading
665 // Pass nextFunction to launch something immediately after showing load box
666 // with hideLoading() called after the function
667 DesktopContent.showLoading = function(nextFunction)
668 {
669 
670  localDoIt();
671  if(nextFunction)
672  {
673  window.setTimeout(function()
674  {
675  nextFunction();
676  DesktopContent.hideLoading();
677  },10);
678  }
679  return;
680 
682  function localDoIt()
683  {
684  //Debug.log("DesktopContent.showLoading " + DesktopContent._loadBoxRequestStack);
685 
686  if(DesktopContent._loadBoxRequestStack++) //box should still be open, add to stack
687  return;
688 
689  //check if DesktopContent._loadBox has been set
690  if(!DesktopContent._loadBox)
691  {
692  //check if there is already an error box with same id and share
693  var el = document.getElementById(DesktopContent._loadBoxId);
694  if(!el) //element doesn't already exist, so we need to create the element
695  {
696  var body = document.getElementsByTagName("BODY")[0];
697  if(!body) //maybe page not loaded yet.. so wait to report
698  {
699  //try again in 1 second
700  window.setTimeout(function() { Debug.errorPop(err,severity)}, 1000);
701  return;
702  }
703 
704  //create the element
705  el = document.createElement("div");
706  el.setAttribute("id", DesktopContent._loadBoxId);
707  el.style.display = "none";
708  var str = "";
709 
710  str += "<table height='100%' width='100%'><td id='" +
711  DesktopContent._loadBoxId + "-td'>Loading...</td></table>";
712  el.innerHTML = str;
713  body.appendChild(el); //add element to body of page
714 
715 
716  //add style for loading to page HEAD tag
717  var css = "";
718 
719 
720  //load box style
721  css += "#" + DesktopContent._loadBoxId +
722  "{" +
723  "position: absolute; display: none; border: 2px solid gray;" +
724  "background-color: rgba(0,0,0,0.8); overflow-y: auto;" +
725  "overflow-x: auto; padding: 5px; -moz-border-radius: 2px;" +
726  "-webkit-border-radius: 2px; border-radius: 2px;" +
727  "font-size: 18px; z-index: 2147483647;" + //max 32 bit number z-index
728  "color: white; " +
729  "font-family: 'Comfortaa', arial; text-align: left;" +
730  "left: 8px; top: 8px; margin-right: 8px; height:400px; " +
731  "}\n\n";
732  css += "#" + DesktopContent._loadBoxId + " table" +
733  "{" +
734  "background-color: rgba(0,0,0,0.8);" +
735  "border: 0;" +
736  "}\n\n";
737 
738  //load box text style
739  // css += "#" + DesktopContent._loadBoxId + "-td" +
740  // "{" +
741  // "color: white; font-size: 18px;" +
742  // "font-family: 'Comfortaa', arial;" +
743  // "text-align: center;" +
744  // "}\n\n";
745 
746  //add style element to HEAD tag
747  var style = document.createElement('style');
748 
749  if (style.styleSheet) {
750  style.styleSheet.cssText = css;
751  } else {
752  style.appendChild(document.createTextNode(css));
753  }
754 
755  document.getElementsByTagName('head')[0].appendChild(style);
756  }
757  DesktopContent._loadBox = el;
758  }
759 
760  //have load popup element now, so display it at center of page
761 
762  var W = 100;
763  var H = 60;
764 
765  var WW,WH; //window width and height
766  //get width and height properly
767  if(typeof DesktopContent != 'undefined') //define width using DesktopContent
768  {
769  WW = DesktopContent.getWindowWidth();
770  WH = DesktopContent.getWindowHeight();
771  }
772  else if(typeof Desktop != 'undefined' && Desktop.desktop) //define width using Desktop
773  {
774  WW = DesktopContent.getDesktopWidth();
775  WH = DesktopContent.getDesktopHeight();
776  }
777 
778  var X = DesktopContent.getWindowScrollLeft() + (WW - W - 4)/2; //for 2px borders
779  var Y = DesktopContent.getWindowScrollTop() + (WH - H -4)/2; //for 2px borders
780 
781  //show the load box whereever the current scroll is
782  DesktopContent._loadBox.style.left = (X) + "px";
783  DesktopContent._loadBox.style.top = (Y) + "px";
784  DesktopContent._loadBox.style.width = (W) + "px";
785  DesktopContent._loadBox.style.height = (H) + "px";
786 
787  DesktopContent._loadBox.style.display = "block";
788 
789  //===================
790  //setup Loading.. animation
791  var loadBoxStr = "..";
792  var el = document.getElementById(DesktopContent._loadBoxId + "-td");
793  el.innerHTML = "Loading" + loadBoxStr;
794 
796  var loadBoxAnimationFunction = function() {
797  if(loadBoxStr.length > 3) loadBoxStr = "";
798  else
799  loadBoxStr += ".";
800  el.innerHTML = "Loading" + loadBoxStr;
801  }; //end loadBoxAnimationFunction
802 
803  window.clearInterval(DesktopContent._loadBoxTimer);
804  DesktopContent._loadBoxTimer = window.setInterval(loadBoxAnimationFunction, 300);
805  } //end localDoIt()
806 } //end showLoading()
807 //=====================================================================================
808 DesktopContent._loadBoxHideTimer = 0;
809 DesktopContent.hideLoading = function()
810 {
811  window.setTimeout(localHideLoadBox, 300);
812 
814  function localHideLoadBox()
815  {
816  if(--DesktopContent._loadBoxRequestStack) //subtract from stack, but dont hide if stack remains
817  return;
818 
819  window.clearInterval(DesktopContent._loadBoxTimer); //kill loading animation
820  //Debug.log("DesktopContent.hideLoading");
821  document.getElementById(DesktopContent._loadBoxId).style.display = "none";
822 
823  } //end localHideLoadBox
824 
825 } //end hideLoading()
826 
827 //=====================================================================================
828 //DesktopContent.XMLHttpRequest
829 // forms request properly for ots server, POSTs data
830 // and when request is returned, returnHandler is called with
831 // req result on success, if failure (e.g. due to bad url) called with 0 and
832 // error description in errStr.
833 //
834 // For proper request need: urnLid, cookieCode
835 //
836 // Handler always receives standard xml response if server is ok:
837 // <ROOT>
838 // <HEADER><CookieCode value=''/></HEADER>
839 // <DATA> ... </DATA>
840 // </ROOT>
841 //
842 // Where CookieCode and DisplayName can change upon every server response
843 //
844 // reqParam is used to give the returnHandler an index to route responses to.
845 // progressHandler can be given to receive progress updates (e.g. for file uploads)
846 // callHandlerOnErr can be set to true to have handler called with errStr parameter
847 // otherwise, handler will not be called on error.
848 //
849 // Use ignoreSystemBlock if request is expected to meet a down server (like restarting xdaq)
850 // Use doNotOfferSequenceChange for requests that might fail based on permissions (like code editor switch to read only).
851 //
852 DesktopContent.XMLHttpRequest = function(requestURL, data, returnHandler,
853  reqParam, progressHandler, callHandlerOnErr, doNotShowLoadingOverlay,
854  targetSupervisor, ignoreSystemBlock, doNotOfferSequenceChange)
855 {
856 
857  // Sequence is used as an alternative approach to cookieCode (e.g. ots Config Wizard).
858  var sequence = DesktopContent._sequence;
859  var errStr = "";
860  var req;
861 
862  var callerLocation = "";
863  try
864  {
865  callerLocation = (new Error).stack.split("\n")[2];
866  var tmpCallerLocation = callerLocation.slice(0,callerLocation.indexOf(' ('));
867  callerLocation = callerLocation.slice(tmpCallerLocation.length+2,
868  callerLocation.length-1);
869  }
870  catch(e) {} //ignore error
871 
872 
873 
874  if((!ignoreSystemBlock && DesktopContent._blockSystemCheckMailbox) //we expect the system to be down during system block
875  || DesktopContent._needToLoginMailbox)
876  {
877  //check if already marked the mailbox.. and do nothing because we know something is wrong
878 
879  errStr = "The system appears to be down.";
880  errStr += " (Try reconnecting/reloading the page, or alert ots admins if problem persists.)";
881 
882  if(!callHandlerOnErr)
883  Debug.log("Error: " + errStr,Debug.HIGH_PRIORITY);
884 
885  req = 0; //force to 0 to indicate error
886  var found = false;
887  if(DesktopContent._arrayOfFailedHandlers.length < 2) //only give pop up behavior for first 2 failures (then go quiet)
888  {
889  for(var rh in DesktopContent._arrayOfFailedHandlers)
890  if(DesktopContent._arrayOfFailedHandlers[rh] == returnHandler)
891  {
892  errStr = "Blocking multiple error responses to same handler. \nRecurring error should be handled by returnHandler: " + returnHandler;
893 
894  if(!callHandlerOnErr)
895  Debug.log(errStr.substr(0,200) + "...",Debug.HIGH_PRIORITY);
896 
897  found = true; break;
898  }
899  }
900  else
901  {
902  errStr = "Quiet Mode. Blocking multiple error responses to ALL handlers. \nRecurring error should be handled by returnHandler:" + returnHandler;
903  Debug.log(errStr.substr(0,200) + "...",Debug.HIGH_PRIORITY);
904  found = true;
905  }
906 
907  if(!found && !callHandlerOnErr)
908  DesktopContent._arrayOfFailedHandlers.push(returnHandler);
909 
910  //only call return handler once
911  if(returnHandler && !found && callHandlerOnErr)
912  returnHandler(req, reqParam, errStr);
913  return;
914  }
915 
916  req = new XMLHttpRequest();
917 
918  if(progressHandler) req.upload.addEventListener("progress", progressHandler, false); //add progress listener if defined
919 
920  //set timeout to detect infinite loops or long waits
921  var timeoutTimer;
922  var timeoutFunction = function()
923  {
924  Debug.log("It has been 60 seconds.. still waiting for a response. " +
925  "Is there an infinite loop occuring at the server? " +
926  "Or is this just a really long request..",
927  Debug.HIGH_PRIORITY);
928  timeoutTimer = window.setTimeout(timeoutFunction, 60000);
929  }
930  timeoutTimer = window.setTimeout(timeoutFunction, 60000);
931 
932  //setup response handler
933  req.onreadystatechange = function() {
934  //Debug.log(req.readyState + " " + req.status);
935  if (req.readyState==4)
936  { //when readyState=4 return complete, status=200 for success, status=400 for fail
937  window.clearTimeout(timeoutTimer);
938 
939  if(!doNotShowLoadingOverlay)
940  DesktopContent.hideLoading();
941 
942  if(req.status==200)
943  {
944  //Debug.log("Request Response Text " + req.responseText + " ---\nXML " + req.responseXML,Debug.LOW_PRIORITY);
945 
946  DesktopContent._lastCookieTime = parseInt((new Date()).getTime()); //in ms
947 
948  //check if failed due to cookieCode and go to login prompt
949  if(req.responseText == Globals.REQ_NO_PERMISSION_RESPONSE)
950  {
951  errStr = "Request failed due to insufficient account permissions.";
952 
953  if(!doNotOfferSequenceChange && DesktopContent._sequence)
954  {
955  Debug.log("In wiz mode, attempting to fix access code on the fly...");
956 
957  DesktopContent.popUpVerification(
958  /*prompt*/ errStr + "<br><br>Please enter a valid access code: ",
959  /*func*/
960  function(newSequence)
961  {
962  DesktopContent._sequence = newSequence.trim();
963  Debug.log("Resulting sequence code: " + DesktopContent._sequence);
964 
965  if(DesktopContent._sequence)
966  {
967  Debug.log("Retrying request with new access code...");
968  DesktopContent.XMLHttpRequest(requestURL, data, returnHandler,
969  reqParam, progressHandler, callHandlerOnErr, doNotShowLoadingOverlay,
970  targetSupervisor, ignoreSystemBlock);
971  return;
972  }
973 
974  DesktopContent._sequence = "a"; //set so retry is possible
975 
976  }, /*val*/ undefined,
977  /*bgColor*/ undefined,
978  /*textColor*/ undefined,
979  /*borderColor*/ undefined,
980  /*getUserInput*/ true,
981  /*dialogWidth*/ undefined,
982  /*cancelFunc*/ undefined,
983  /*yesButtonText*/ "Retry",
984  /*noAutoComplete*/ true);
985 
986  return;
987  }
988  //return;
989  }
990  else if(req.responseText == Globals.REQ_USER_LOCKOUT_RESPONSE)
991  {
992  errStr = "Request failed because another user has locked ots. Put your mouse over the lock icon at the top of the dashboard to see who.";
993  //return;
994  }
995  else if(req.responseText == Globals.REQ_NO_LOGIN_RESPONSE)
996  {
997  errStr = "Login has expired.";
998 
999  if(ignoreSystemBlock || !DesktopContent._blockSystemCheckMailbox) //make sure system is alive
1000  {
1001  DesktopContent._needToLoginMailbox = true; //force to login screen on server failure
1002  if(DesktopContent._theDesktopWindow)
1003  DesktopContent._theDesktopWindow.postMessage(
1004  {
1005  "windowId": DesktopContent._theWindowId,
1006  "request": "needToLogin"
1007  },"*");
1008  //return;
1009  }
1010  }
1011  else if(req.responseText == Globals.REQ_LOCK_REQUIRED_RESPONSE)
1012  {
1013  errStr = "Request failed because the request requires the user to lockout the system. Please take over the lock in the Settings area to proceed.";
1014  }
1015  else if(!sequence)
1016  {
1017 
1018  if(!req.responseXML) //invalid XML received
1019  {
1020  errStr = "Request response is invalid XML!";
1021  //return;
1022  }
1023  else
1024  {
1025  //handle cookie code mailbox
1026  DesktopContent._lastCookieCode = DesktopContent.getXMLValue(req,'CookieCode');
1027  if (typeof DesktopContent._lastCookieCode == 'undefined')
1028  { //clear req, server failed
1029  errStr = "Request Failed - Missing Cookie in Response.";
1030 
1031  if(ignoreSystemBlock || !DesktopContent._blockSystemCheckMailbox) //make sure system is alive
1032  {
1033  DesktopContent._needToLoginMailbox = true; //force to login screen on server failure
1034  if(DesktopContent._theDesktopWindow)
1035  DesktopContent._theDesktopWindow.postMessage(
1036  {
1037  "windowId": DesktopContent._theWindowId,
1038  "request": "needToLogin"
1039  },"*");
1040  }
1041 
1042  }
1043  else if(DesktopContent._lastCookieCode != "AllowNoUser")
1044  {
1045  //update local cookieCode and post update to desktop
1046  Debug.log("Updating cookie code.");
1047 
1048  var deltaTime = DesktopContent._lastCookieTime - DesktopContent._updateTimeMailbox;
1049  DesktopContent._cookieCodeMailbox = DesktopContent._lastCookieCode;
1050 
1051  if(DesktopContent._theDesktopWindow && deltaTime > 5*1000 /*ms*/)
1052  {
1053  Debug.log("Posting cookie code to desktop.");
1054 
1055  DesktopContent._updateTimeMailbox = DesktopContent._lastCookieTime;
1056  DesktopContent._theDesktopWindow.postMessage(
1057  {
1058  "windowId": DesktopContent._theWindowId,
1059  "request": "updateCookieCode",
1060  "cookieCode": DesktopContent._cookieCodeMailbox,
1061  "cookieCodeTime": DesktopContent._updateTimeMailbox
1062  },"*");
1063  }
1064 
1065 // //check twice to handle race conditions with other content code
1066 // if(DesktopContent._updateTimeMailbox && parseInt(DesktopContent._updateTimeMailbox.innerHTML) < DesktopContent._lastCookieTime) //then current code is newer
1067 // {
1068 // DesktopContent._updateTimeMailbox.innerHTML = DesktopContent._lastCookieTime;
1069 // = ;
1070 //
1071 // //setTimeout(DesktopContent.checkCookieCodeRace, Math.random()*1000|0+500); //random wait (500-1500ms) before checking if race conditions occured
1072 // }
1073  }
1074  }
1075  }
1076  }
1077  else if(req.status == 0) //request was interrupted (probably window was closed)
1078  {
1079 // Debug.log("Status=0. Likely this means a window was closed, or the server crashed, in the middle of a request. " +
1080 // "\n(It also could mean 'potential security risk' like a cross-domain request) ",Debug.HIGH_PRIORITY);
1081  errStr = "Request was interrupted (Status=0). " +
1082  "Likely this means the server crashed (or the desktop window making the request was closed), " +
1083  " in the middle of a request. " +
1084  "\n(It also could mean 'potential security risk' like a cross-domain request) ";
1085  //return;
1086  }
1087  else //bad address response
1088  {
1089 
1090  errStr = "Request Failed (code: " + req.status +
1091  ") - Bad Address: " + origin + "?urn=" + urn +
1092  "\n" + requestURL;
1093  Debug.log(errStr,Debug.HIGH_PRIORITY);
1094 
1095  //handle multiple failed handlers
1096  var found = false;
1097  if(DesktopContent._arrayOfFailedHandlers.length < 2) //only give pop up behavior for first 2 failures (then go quiet)
1098  {
1099  for(var rh in DesktopContent._arrayOfFailedHandlers)
1100  if(DesktopContent._arrayOfFailedHandlers[rh] == returnHandler)
1101  {
1102  errStr = "Blocking multiple error responses to same handler. \nDoes target exist? Here is the (would be) returnHandler: \n\n" + returnHandler;
1103  Debug.log(errStr.substr(0,200) + "...",Debug.HIGH_PRIORITY);
1104  found = true; break;
1105  }
1106  }
1107  else
1108  {
1109  errStr = "Quiet Mode. Blocking multiple error responses to ALL handlers. \nDoes target exist? Here is the (would be) returnHandler: \n\n " + returnHandler;
1110  Debug.log(errStr.substr(0,200) + "...",Debug.HIGH_PRIORITY);
1111  found = true;
1112  }
1113  if(!found) DesktopContent._arrayOfFailedHandlers.push(returnHandler);
1114  if(found) return; //do not call handler for failed server for user code multiple times..
1115  }
1116 
1117  //if not calling handler on error, then get and display errors for user
1118  var errArr = (callHandlerOnErr || !req.responseXML)?[]:DesktopContent.getXMLRequestErrors(req);
1119  if(errArr.length && !callHandlerOnErr)
1120  {
1121  for(var i=0;i<errArr.length;++i)
1122  {
1123  errStr += (i?"\n\n":"") + errArr[i];
1124 
1125  console.log("Initial request location: \n" + callerLocation);
1126  Debug.log("Error: " + errArr[i],
1127  (ignoreSystemBlock || requestURL.indexOf("TooltipRequest?") >= 0)?
1128  Debug.LOW_PRIORITY: //do not alert if tooltip (auto request) - problematic when not logged-in and causing unnecessary alerts
1129  Debug.HIGH_PRIORITY);
1130  }
1131  }
1132  else if(errStr != "")
1133  {
1134  errStr += "\n\n(Try refreshing the page, or alert ots admins if problem persists.)";
1135 
1136  console.log("Initial request location: \n" + callerLocation);
1137  Debug.log("Error: " + errStr,
1138  (callHandlerOnErr ||
1139  ignoreSystemBlock ||
1140  requestURL.indexOf("TooltipRequest?") >= 0)?
1141  Debug.LOW_PRIORITY: //do not alert if tooltip (auto request) - problematic when not logged-in and causing unnecessary alerts
1142  Debug.HIGH_PRIORITY);
1143  //alert(errStr);
1144  req = 0; //force to 0 to indicate error
1145  }
1146 
1147  //success, call return handler
1148  if(returnHandler && (errStr=="" || callHandlerOnErr))
1149  {
1150  returnHandler(req, reqParam, errStr);
1151 
1152  //RAR commented out.. not sure if it is working as intended (weird desktop behavior is occurring during disconnects)
1153  // if(errStr=="" && DesktopContent._arrayOfFailedHandlers.length)
1154  // {
1155  // //since we had success, search through failed handler and remove if there
1156  // for(var i = 0; i<DesktopContent._arrayOfFailedHandlers.length; ++i)
1157  // if(DesktopContent._arrayOfFailedHandlers[i] == returnHandler)
1158  // {
1159  // DesktopContent._arrayOfFailedHandlers.splice(i,1); //remove that handler
1160  // break;
1161  // }
1162  // }
1163  }
1164 
1165  }
1166  }
1167 
1168  var reqData;
1169  if(!sequence)
1170  {
1171  //if(!DesktopContent._cookieCodeMailbox) //attempt to fix (e.g. for Desktop)
1172  // DesktopContent._cookieCodeMailbox = document.getElementById("DesktopContent-cookieCodeMailbox");
1173  var cc = DesktopContent._cookieCodeMailbox;//DesktopContent._cookieCodeMailbox?DesktopContent._cookieCodeMailbox.innerHTML:""; //get cookie code from mailbox if available
1174  reqData = "CookieCode="+cc+((data===undefined)?"":("&"+data));
1175  }
1176  else
1177  {
1178  reqData = "sequence="+sequence+((data===undefined)?"":("&"+data));
1179  }
1180 
1181 
1182  var urn = DesktopContent._localUrnLid;
1183  var origin = DesktopContent._localOrigin;
1184 
1185  if(!urn || targetSupervisor) //desktop supervisor, instead of local application
1186  {
1187  urn = DesktopContent._serverUrnLid;
1188  origin = DesktopContent._serverOrigin;
1189  }
1190 
1191 
1192  if(!doNotShowLoadingOverlay)
1193  DesktopContent.showLoading();
1194 
1195 
1196  var reqURL = origin+"/urn:xdaq-application:lid="+urn+"/"+requestURL;
1197  //Debug.log("Post " + reqURL + "\n\tData: " + reqData);
1198  req.open("POST", reqURL,true);
1199  req.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
1200  req.send(reqData);
1201 } // end XMLHttpRequest()
1202 //
1204 //DesktopContent.checkCookieCodeRace = function() {
1205 // //Debug.log("Checking cookie race conditions");
1206 // if(parseInt(DesktopContent._updateTimeMailbox.innerHTML) < DesktopContent._lastCookieTime) //then current code is newer
1207 // {
1208 // Debug.log("Cookie race occured!");
1209 //
1210 // DesktopContent._updateTimeMailbox.innerHTML = DesktopContent._lastCookieTime;
1211 // DesktopContent._cookieCodeMailbox.innerHTML = DesktopContent._lastCookieCode;
1212 // }
1213 //}
1214 
1215 //=====================================================================================
1216 //returns an array of error strings from xml request response
1217 DesktopContent.getXMLRequestErrors = function(req) {
1218  //make sure to give an error if the response is bad
1219  if(!req || !req.responseXML)
1220  return ["Unknown error occured " +
1221  "(XML response may have been illegal)!"];
1222 
1223  var errNodes = DesktopContent.getXMLChildren(req,"Error");
1224  var errArr = [];
1225  for(var i=0;i<errNodes.length;++i)
1226  errArr.push(errNodes[i].getAttribute("value"));
1227  return errArr;
1228 } //end getXMLRequestErrors()
1229 
1230 //=====================================================================================
1231 //returns xml entry value for an attribute
1232 DesktopContent.getXMLAttributeValue = function(req, name, attribute) {
1233  var el;
1234  if(el = DesktopContent.getXMLNode(req,name))
1235  return el.getAttribute(attribute);
1236  else if(name == "Error" && //make sure Error gives an error if the response is bad
1237  (!req || !req.responseXML))
1238  return "Unknown error occured " +
1239  "(XML response may have been illegal)!";
1240  else
1241  return undefined;
1242 } // end getXMLAttributeValue()
1243 
1244 //=====================================================================================
1245 //returns xml entry value for attribue 'value'
1246 // if !name assume req is xml node already
1247 DesktopContent.getXMLValue = function(req, name) {
1248  if(!req) return undefined;
1249 
1250  if(!name)
1251  return req.getAttribute("value");
1252 
1253  return DesktopContent.getXMLAttributeValue(req,name,"value");
1254 } //end getXMLValue()
1255 
1256 //=====================================================================================
1257 //returns array of xml children nodes
1258 // with tags that match nodeName
1259 DesktopContent.getXMLChildren = function(req, nodeName) {
1260 
1261  if(req && req.responseXML) //to allow for arbitrary starting xml node
1262  req = req.responseXML;
1263  return req.getElementsByTagName(nodeName);
1264 } //end getXMLChildren()
1265 
1266 //=====================================================================================
1267 //returns xml entry node (first node with name)
1268 // Note: could be any depth (not just depth 1)
1269 // ...uses getElementsByTagName(name)
1270 DesktopContent.getXMLNode = function(req, name) {
1271  var els;
1272  if(req && req.responseXML) //to allow for arbitrary starting xml node
1273  req = req.responseXML;
1274  if(req)
1275  {
1276  //find DATA
1277  var i;
1278  try
1279  {
1280  els = req.getElementsByTagName(name);//req.responseXML.childNodes[0].childNodes;
1281  }
1282  catch(e) {return undefined;}
1283 
1284  if(els.length)
1285  return els[0];
1286  //reverted to former way
1287 
1288  //for depth 1 sometime?
1289  // for(var i=0;i<els.length;++i)
1290  // if(els[i].nodeName == "DATA")
1291  // {
1292  // els = req.responseXML.childNodes[0].childNodes[i].childNodes;
1293  //
1294  // for(i=0;i<els.length;++i)
1295  // if(els[i].nodeName == name)
1296  // return els[i];
1297  // break;
1298  // }
1299  }
1300 
1301  return undefined;
1302 }
1303 
1304 //=====================================================================================
1305 //returns xml entry node (first node with name DATA)
1306 DesktopContent.getXMLDataNode = function(req, name) {
1307  return DesktopContent.getXMLNode("DATA");
1308 }
1309 
1310 //=====================================================================================
1311 //tooltipConditionString ~~
1312 // use to modify tooltip string with special keywords like INDENT and TAB
1313 DesktopContent.tooltipConditionString = function(str) {
1314  return str.replace(/<INDENT>/g,
1315  "<div style='margin-left:60px;'>").replace(/<\/INDENT>/g,
1316  "</div>").replace(/<TAB>/g,
1317  "<div style='margin-left:60px;'>").replace(/<\/TAB>/g,
1318  "</div>");
1319 } //end tooltipConditionString()
1320 
1321 //=====================================================================================
1322 //tooltip ~~
1323 // use uid to determine if tip should still be displayed
1324 // - ask server about user/file/function/id combo
1325 // - if shouldShow:
1326 // then show
1327 // add checkbox to never show again
1328 // id of "ALWAYS".. disables never show handling (no checkboxes)
1329 //
1330 DesktopContent.tooltip = function(id,tip,alwaysShow) {
1331 
1332  if(typeof Desktop !== 'undefined') //This call is from Desktop page.. so can use the urnLid_ & serverOrigin_
1333  {
1334  DesktopContent._serverUrnLid = urnLid_;
1335  DesktopContent._serverOrigin = serverOrigin_;
1336 
1337  DesktopContent._sequence = DesktopContent.getDesktopParameter(0,"code");
1338  if(!DesktopContent._sequence || DesktopContent._sequence == "")
1339  DesktopContent._sequence = 0; //normal desktop mode
1340  else
1341  Debug.log("In Wizard Mode with Sequence=" + DesktopContent._sequence);
1342  }
1343 
1344 
1345  var srcStackString,srcFunc,srcFile;
1346 
1347  if(Debug.BROWSER_TYPE == 1) //chrome
1348  {
1349  srcStackString = (new Error).stack.split("\n")[2];
1350  srcFunc = srcStackString.trim().split(' ')[1];
1351  }
1352  else if(Debug.BROWSER_TYPE == 2) //firefox
1353  {
1354  srcStackString = (new Error).stack.split("\n")[1];
1355  srcFunc = srcStackString.trim().split('@')[0];
1356  }
1357 
1358  srcFile = srcStackString.substr(srcStackString.lastIndexOf('/')+1);
1359  if(srcFile.indexOf('?') >= 0)
1360  srcFile = srcFile.substr(0,srcFile.indexOf('?'));
1361  if(srcFile.indexOf(':') >= 0)
1362  srcFile.substr(0,srcFile.indexOf(':'));
1363 
1364 
1365  if(tip === undefined)
1366  {
1367  Debug.log("Undefined tooltip string at " + srcStackString + "\n" +
1368  srcFunc + "\n" + srcFile +".\n\n Tooltip Usage: <id> <tip>", Debug.HIGH_PRIORITY);
1369  return;
1370  }
1371 
1372 
1373  var oldId = id;
1374  //remove all special characters from ID
1375  id = "";
1376  for(var i=0;i<oldId.length;++i)
1377  if((oldId[i] >= 'a' && oldId[i] <= 'z') ||
1378  (oldId[i] >= 'A' && oldId[i] <= 'Z') ||
1379  (oldId[i] >= '0' && oldId[i] <= '9'))
1380  id += oldId[i];
1381 
1382 
1383  if(alwaysShow || id == "ALWAYS") //no need to check
1384  localFinishTooltip();
1385  else
1386  DesktopContent.XMLHttpRequest(
1387  "TooltipRequest?RequestType=check" +
1388  "&srcFunc=" + srcFunc +
1389  "&srcFile=" + srcFile +
1390  "&srcId=" + id
1391  ,"" //post data
1392  ,localFinishTooltip //handler
1393  ,0,0,0,true,true); //show loading, and target supervisor
1394 
1395 
1396  return;
1397 
1398  //:::::::::::::::::::::::::::::::::::::::::
1399  //popupResize ~~
1400  function localFinishTooltip(req)
1401  {
1402 
1403  var showTooltip = !req ||
1404  DesktopContent.getXMLValue(req,"ShowTooltip");
1405 
1406  //Debug.log("showTooltip: " + showTooltip);
1407 
1408  if(showTooltip|0)
1409  {
1410  var str = "";
1411 
1412  //add checkbox
1413  if(id != "ALWAYS")
1414  {
1415  str += "<input type='checkbox' " +
1416  "id='DesktopContent-tooltip-SetNeverShowCheckbox-above-" +
1417  id + "' " +
1418  "onclick='" +
1419  "DesktopContent.tooltipSetAlwaysShow(\"" +
1420  srcFunc + "\",\"" +
1421  srcFile + "\",\"" +
1422  id + "\", this.checked);" + "'>";
1423  str += " ";
1424  str += "<a onclick='" +
1425  "var el = document.getElementById(\"" +
1426  "DesktopContent-tooltip-SetNeverShowCheckbox-above-" +
1427  id + "\");" +
1428  "el.checked = !el.checked;" +
1429  "DesktopContent.tooltipSetAlwaysShow(\"" +
1430  srcFunc + "\",\"" +
1431  srcFile + "\",\"" +
1432  id + "\", el.checked);" +
1433  "'>";
1434  str += "Never show the Tooltip below, or...";
1435  str += "</a>";
1436  str +="</input>";
1437 
1438  //snooze button
1439  str += "<br>"
1440  str += "<input type='checkbox' " +
1441  "id='DesktopContent-tooltip-SetNeverShowCheckbox-hour-" +
1442  id + "' " +
1443  "onclick='" +
1444  "DesktopContent.tooltipSetAlwaysShow(\"" +
1445  srcFunc + "\",\"" +
1446  srcFile + "\",\"" +
1447  id + "\", 0 /*neverShow*/, this.checked);" + "'>";
1448  str += " ";
1449  str += "<a onclick='" +
1450  "var el = document.getElementById(\"" +
1451  "DesktopContent-tooltip-SetNeverShowCheckbox-hour-" +
1452  id + "\");" +
1453  "el.checked = !el.checked;" +
1454  "DesktopContent.tooltipSetAlwaysShow(\"" +
1455  srcFunc + "\",\"" +
1456  srcFile + "\",\"" +
1457  id + "\", 0 /*neverShow*/, el.checked);" +
1458  "'>";
1459  str += "Silence this Tooltip for a week (can be reset in Settings):";
1460  str += "</a>";
1461  str +="</input>";
1462  }
1463 
1464  //add title
1465  if(id != "ALWAYS")
1466  {
1467  str += "<br><br>";
1468  str += "<center><b>'" + oldId + "' Tooltip</b></center><br>";
1469  }
1470  else
1471  str += "<br><br>";
1472 
1473  str += DesktopContent.tooltipConditionString(tip);
1474 
1475  str += "<br><br>";
1476 
1477  //add checkbox
1478  if(id != "ALWAYS")
1479  {
1480  str += "<input type='checkbox' " +
1481  "id='DesktopContent-tooltip-SetNeverShowCheckbox-below-" +
1482  id + "' " +
1483  "onclick='" +
1484  "DesktopContent.tooltipSetAlwaysShow(\"" +
1485  srcFunc + "\",\"" +
1486  srcFile + "\",\"" +
1487  id + "\", this.checked);" + "'>";
1488  str += " ";
1489  str += "<a onclick='" +
1490  "var el = document.getElementById(\"" +
1491  "DesktopContent-tooltip-SetNeverShowCheckbox-below-" +
1492  id + "\");" +
1493  "el.checked = !el.checked;" +
1494  "DesktopContent.tooltipSetAlwaysShow(\"" +
1495  srcFunc + "\",\"" +
1496  srcFile + "\",\"" +
1497  id + "\", el.checked);" +
1498  "'>";
1499  str += "Never show the Tooltip above.";
1500  str += "</a>";
1501  str +="</input>";
1502  }
1503 
1504  Debug.log("srcStackString " + srcStackString);
1505  Debug.log(str,Debug.TIP_PRIORITY);
1506  }
1507 
1508  } //end localFinishTooltip()
1509 
1510 } //end tooltip()
1511 
1512 //=====================================================================================
1513 DesktopContent.setWindowTooltip = function(tip)
1514 {
1515  var windowTooltipElement = document.createElement("div");
1516  windowTooltipElement.setAttribute("id", "otsDesktopWindowTooltipElement");
1517  windowTooltipElement.setAttribute("style", "display:none");
1518 
1519  windowTooltipElement.innerText = encodeURIComponent(tip);
1520  document.body.appendChild(windowTooltipElement);
1521 } //end setWindowTooltip()
1522 
1523 //=====================================================================================
1524 //setSecurityOne
1525 // make server request to enable random security sequence for URL
1526 DesktopContent.setSecurityOn = function(on) {
1527  console.log("Reached");
1528  DesktopContent.XMLHttpRequest(
1529  "ToggleSecurityCodeGeneration?RequestType=TurnGenerationOn" +
1530  "&srcFunc=0"
1531  ,""
1532  ,DesktopContent.toggleSecurityCodeGenerationHandler
1533  ,0,0,0,true,true);
1534  }
1535 
1536 //=====================================================================================
1537 //toggleSecurityCodeGenerationHandler ~~
1538 DesktopContent.toggleSecurityCodeGenerationHandler = function(req) {
1539  var status = DesktopContent.getXMLValue(req,"Status");
1540  Debug.log("Status: " + status);
1541  if (status == "Generation_Success") {
1542  Debug.log("Successfully switched to using authentication sequence!");
1543  Debug.closeErrorPop();
1544  Debug.log("If you wish to return to the default security generation, you can use the 'Reset User Information' in the " +
1545  "'Edit User Data' app.");
1546  Debug.log("Plase refer to the console for the new link!", Debug.INFO_PRIORITY);
1547  }
1548 }
1549 
1550 //=====================================================================================
1551 //tooltipSetNeverShow ~~
1552 // set value of never show for target tip to 1/0 based on alwaysShow
1553 DesktopContent.tooltipSetAlwaysShow = function(srcFunc,srcFile,id,neverShow,temporarySilence) {
1554  Debug.log("neverShow = " + neverShow + " tempSilence = " + temporarySilence);
1555 
1556  if(temporarySilence)
1557  neverShow = false; //force temporary to have priority
1558  DesktopContent.XMLHttpRequest(
1559  "TooltipRequest?RequestType=setNeverShow" +
1560  "&srcFunc=" + srcFunc +
1561  "&srcFile=" + srcFile +
1562  "&srcId=" + id +
1563  "&doNeverShow=" + (neverShow?1:0) +
1564  "&temporarySilence=" + (temporarySilence?1:0)
1565  ,""
1566  ,0,0,0,0,true,true); //show loading, and target supervisor
1567 
1568  if(temporarySilence) return;
1569 
1570  //make sure all checkboxes mirror choice
1571  document.getElementById("DesktopContent-tooltip-SetNeverShowCheckbox-below-" +
1572  id).checked = neverShow;
1573  document.getElementById("DesktopContent-tooltip-SetNeverShowCheckbox-above-" +
1574  id).checked = neverShow;
1575 } //end DesktopContent.tooltipSetAlwaysShow
1576 
1577 //=====================================================================================
1578 //popUpVerification ~~
1579 // asks user if sure
1580 // replace REPLACE in prompt with value passed as val (e.g. pass document.getElementById("myElementId").value)
1581 // call func (if exists) when user selects "Yes"
1582 //
1583 // Can change background color and text color with strings bgColor and textColor (e.g. "rgb(255,0,0)" or "red")
1584 // Default is yellow bg with black text if nothing passed.
1585 DesktopContent.popUpVerification = function(prompt, func, val, bgColor,
1586  textColor, borderColor, getUserInput, dialogWidth, cancelFunc,
1587  yesButtonText, noAutoComplete, defaultUserInputValue) {
1588 
1589  // Debug.log("X: " + DesktopContent._mouseOverXmailbox.innerHTML +
1590  // " Y: " + DesktopContent._mouseOverYmailbox.innerHTML +
1591  // " W: " + DesktopContent.getWindowWidth() +
1592  // " H: " + DesktopContent.getWindowHeight());
1593 
1594 
1595  //remove pop up if already exist
1596  if(DesktopContent._verifyPopUp)
1597  DesktopContent._verifyPopUp.parentNode.removeChild(DesktopContent._verifyPopUp);
1598 
1599  //replace REPLACE with val
1600  if(val != undefined)
1601  prompt = prompt.replace(/REPLACE/g, val);
1602 
1603 
1604  //create popup and add to body
1605 
1606 
1607  //setup style first
1608  if(!bgColor) bgColor = "rgb(255,241,189)"; //set default
1609  if(!textColor) textColor = "black"; //set default
1610  if(!borderColor) borderColor = "black";
1611  if(!dialogWidth) dialogWidth = 200;
1612 
1613  var css = "";
1614  //pop up div style
1615  //note: z-index of 2000 is above config gui treeview
1616  css += "#" + DesktopContent._verifyPopUpId + " " +
1617  "{position: absolute; z-index: 10000; border-radius: 5px; padding: 10px;" +
1618  "background-color: " + bgColor + "; border: 2px solid " + borderColor + ";" +
1619  "color: " + textColor + ";text-align: center; overflow: auto;" +
1620  "}\n\n";
1621  //pop up text style
1622  css += "#" + DesktopContent._verifyPopUpId + "-text " +
1623  "{" +
1624  "color: " + textColor + ";width: " + dialogWidth + "px; padding-bottom: 10px;" +
1625  "}\n\n";
1626  //..and anything in the text div
1627  css += "#" + DesktopContent._verifyPopUpId + " *" +
1628  "{" +
1629  "color: " + textColor + ";" +
1630  "}\n\n";
1631  css += "#" + DesktopContent._verifyPopUpId + " input" +
1632  "{" +
1633  "cursor: pointer;" +
1634  "}\n\n";
1635 
1636  //add style element to HEAD tag
1637  var style = document.createElement('style');
1638 
1639  if (style.styleSheet) {
1640  style.styleSheet.cssText = css;
1641  } else {
1642  style.appendChild(document.createTextNode(css));
1643  }
1644 
1645  document.getElementsByTagName('head')[0].appendChild(style);
1646 
1647 
1648  var body = document.getElementsByTagName("BODY")[0];
1649 
1650  var el = document.createElement("div");
1651  el.setAttribute("id", DesktopContent._verifyPopUpId);
1652  el.onmouseup = function(e) {e.stopPropagation();};
1653  el.onmousedown = function(e) {e.stopPropagation();};
1654  el.onmouseover = function(e) {e.stopPropagation();};
1655 
1656  var userInputStr = "";
1657  if(getUserInput)
1658  userInputStr +=
1659  "<input type='text' id='DesktopContent_popUpUserInput' " +
1660  "onclick='event.stopPropagation();'" +
1661  (noAutoComplete?"autocomplete='off' ":"") +
1662  " value='" +
1663  (defaultUserInputValue!==undefined?defaultUserInputValue:"") + "' " +
1664  ">";
1665 
1666  var str = "<div id='" + DesktopContent._verifyPopUpId + "-text'>" +
1667  prompt + "<br>" + userInputStr + "</div>" +
1668  "<input type='submit' value='" +
1669  (yesButtonText?yesButtonText:"Yes") +
1670  "' " +
1671  "onclick='event.stopPropagation();' " +
1672  "> " + //onmouseup added below so func can be a function object (and not a string)
1673  "&nbsp;&nbsp;&nbsp;" +
1674  "<input type='submit' " +
1675  "onclick='event.stopPropagation();' " +
1676  "value='Cancel'>";
1677  el.innerHTML = str;
1678 
1679  //onmouseup for "Yes" button
1680  el.getElementsByTagName('input')[0 + (getUserInput?1:0)].onmouseup =
1681  function(event){event.stopPropagation(); DesktopContent.clearPopUpVerification(func);};
1682  //onmouseup for "Cancel" button
1683  el.getElementsByTagName('input')[1 + (getUserInput?1:0)].onmouseup =
1684  function(event){event.stopPropagation(); DesktopContent.clearPopUpVerification(cancelFunc);};
1685 
1686 
1687  Debug.log(prompt);
1688  DesktopContent._verifyPopUp = el;
1689  el.style.left = "-1000px"; //set off page so actual dimensions can be determined, and then div relocated
1690  body.appendChild(el);
1691 
1692 
1693  if(getUserInput) //place cursor
1694  {
1695  var tel = el.getElementsByTagName('input')[0];
1696  tel.focus();
1697  tel.setSelectionRange(0,tel.value.length);
1698 
1699  //accept enter to close
1700  tel.onkeydown =
1701  function(event)
1702  {
1703  if(event.keyCode == 13) // ENTER
1704  {
1705  Debug.log("Accepting enter key");
1706  event.preventDefault();
1707  event.stopPropagation();
1708  DesktopContent.clearPopUpVerification(func);
1709  }
1710  else if(event.keyCode == 27) // ESC
1711  {
1712  Debug.log("Accepting escape key");
1713  event.preventDefault();
1714  event.stopPropagation();
1715  DesktopContent.clearPopUpVerification(cancelFunc);
1716  }
1717  }; //end keydown handler
1718  }
1719  else //focus on button, since no text
1720  el.getElementsByTagName('input')[0].focus();
1721 
1722  //add key handler to body too for enter & esc
1723  el.onkeydown =
1724  function(event)
1725  {
1726  if(event.keyCode == 13) // ENTER
1727  {
1728  Debug.log("Accepting enter key");
1729  event.preventDefault();
1730  event.stopPropagation();
1731  DesktopContent.clearPopUpVerification(func);
1732  }
1733  else if(event.keyCode == 27) // ESC
1734  {
1735  Debug.log("Accepting escape key");
1736  event.preventDefault();
1737  event.stopPropagation();
1738  DesktopContent.clearPopUpVerification(cancelFunc);
1739  }
1740  }; //end keydown handler
1741 
1742  //determine position
1743  var w = el.offsetWidth;
1744  var h = el.offsetHeight;
1745  var x = DesktopContent.getMouseX();
1746  var y = DesktopContent.getMouseY();
1747  x -= w/2; //center on x, but try to avoid having mouse lineup with buttons to avoid accidental double click by user
1748 // Debug.log("X: " + x +
1749 // " Y: " + y +
1750 // " W: " + w +
1751 // " H: " + h);
1752 
1753  while(x+w > DesktopContent.getWindowWidth())
1754  x -= w;
1755  if(y > DesktopContent.getWindowHeight()/2 + h/2)
1756  y -= h; //move to top half of screen
1757  while(y+h > DesktopContent.getWindowHeight())
1758  y -= h;
1759 
1760  if(x <= 0) x = 10;
1761  if(y <= 0) y = 10;
1762 
1763  Debug.log("X: " + x +
1764  " Y: " + y +
1765  " W: " + w +
1766  " H: " + h);
1767  //var
1768  el.style.left = (DesktopContent.getWindowScrollLeft() + x) + "px";
1769  el.style.top = (DesktopContent.getWindowScrollTop() + y) + "px";
1770 } //end popUpVerification()
1771 //=====================================================================================
1772 //clearPopUpVerification ~~
1773 // call func after clearing, if exists
1774 DesktopContent.clearPopUpVerification = function(func) {
1775 
1776  //get parameter value if exists
1777 
1778  var userEl = document.getElementById("DesktopContent_popUpUserInput");
1779  var param = userEl?userEl.value:undefined;
1780 
1781  //remove pop up if already exist
1782  if(DesktopContent._verifyPopUp) DesktopContent._verifyPopUp.parentNode.removeChild(DesktopContent._verifyPopUp);
1783  DesktopContent._verifyPopUp = 0;
1784 
1785  if(func)
1786  func(param); //return user input value if present
1787 } //end clearPopUpVerification()
1788 
1789 
1790 //=====================================================================================
1791 //setPopUpPosition ~~
1792 // centers element based on width and height constraint
1793 //
1794 // Note: assumes a padding and border size if not specified
1795 // Note: if w,h not specified then fills screen (minus margin)
1796 // Note: offsetUp and can be used to position the popup vertically (for example if the dialog is expected to grow, then give positive offsetUp to compensate)
1797 //
1798 // Note: the input element el will need local styling, e.g.:
1799 // #popUpDialog * {
1800 // color: black;
1801 // }
1802 // #popUpDialog a {
1803 // color: rgb(44, 44, 187);
1804 // font-size: 13px;
1805 // }
1806 DesktopContent.setPopUpPosition = function(el,w,h,padding,border,
1807  margin,doNotResize,offsetUp) {
1808 
1809  Debug.log("DesktopContent.setPopUpPosition");
1810 
1811  if(padding === undefined) padding = 10;
1812  if(border === undefined) border = 1;
1813  if(margin === undefined) margin = 0;
1814 
1815  var x,y;
1816 
1817  //:::::::::::::::::::::::::::::::::::::::::
1818  //popupResize ~~
1819  // set position and size
1820  DesktopContent.setPopUpPosition.stopPropagation = function(event) {
1821  //Debug.log("DesktopContent.setPopUpPosition stop propagation");
1822  event.stopPropagation();
1823  }
1824 
1825  //:::::::::::::::::::::::::::::::::::::::::
1826  //popupResize ~~
1827  // set position and size
1828  DesktopContent.setPopUpPosition.popupResize = function() {
1829 
1830  try //check if element still exists
1831  {
1832  if(!el) //if element no longer exists.. then remove listener and exit
1833  {
1834  window.removeEventListener("resize",DesktopContent.setPopUpPosition.popupResize);
1835  window.removeEventListener("scroll",DesktopContent.setPopUpPosition.popupResize);
1836  return;
1837  }
1838  }
1839  catch(err) {return;} //do nothing on errors
1840 
1841  //else resize el
1842  //Debug.log("DesktopContent.setPopUpPosition.popupResize");
1843 
1844 
1845  var ww = DesktopContent.getWindowWidth()-(padding+border)*2;
1846  var wh = DesktopContent.getWindowHeight()-(padding+border)*2;
1847 
1848  //ww & wh are max window size at this point
1849 
1850  var ah = el.offsetHeight;//actual height, in case of adjustments
1851 
1852  if(w === undefined || h === undefined)
1853  {
1854  w = ww - (margin)*2;
1855  h = wh - (margin)*2;
1856  }
1857  //else w,h are inputs and margin is ignored
1858 
1859  x = (DesktopContent.getWindowScrollLeft() + ((ww-w)/2));
1860  y = (DesktopContent.getWindowScrollTop() + ((wh-h)/2)) - (offsetUp|0) - 100; //bias up (looks nicer)
1861 
1862  if(y < DesktopContent.getWindowScrollTop() +
1863  margin + padding)
1864  y = DesktopContent.getWindowScrollTop() + margin +
1865  padding; //don't let it bottom out though
1866 
1867  //if dialog is smaller than window, allow scrolling to see the whole thing
1868  if(w > ww-margin-padding)
1869  x = -DesktopContent.getWindowScrollLeft();
1870  if(ah > wh-margin-padding)
1871  y = -DesktopContent.getWindowScrollTop();
1872 
1873  el.style.left = x + "px";
1874  el.style.top = y + "px";
1875  };
1876  DesktopContent.setPopUpPosition.popupResize();
1877 
1878  //window width and height are not manipulated on resize, only setup once
1879  el.style.width = w + "px";
1880  el.style.height = h + "px";
1881 
1882 
1883  //#popUpDialog {
1884  // position: absolute;
1885  // z-index: 10000;
1886  // border: 1px solid #770000;
1887  // background-color: #efeaea;
1888  // text-align: center;
1889  // padding: 10px;
1890  // color: black;
1891  //}
1892  el.style.position = "absolute";
1893  el.style.zIndex = "10000";
1894  el.style.border = "1px solid #770000";
1895  el.style.backgroundColor = "#efeaea";
1896  el.style.textAlign = "center";
1897  el.style.padding = "10px";
1898  el.style.color = "black";
1899 
1900  if(!doNotResize)
1901  {
1902  window.addEventListener("resize",DesktopContent.setPopUpPosition.popupResize);
1903  window.addEventListener("scroll",DesktopContent.setPopUpPosition.popupResize);
1904  }
1905  el.addEventListener("keydown",DesktopContent.setPopUpPosition.stopPropagation);
1906  el.addEventListener("mousemove",DesktopContent.setPopUpPosition.stopPropagation);
1907  el.addEventListener("mousemove",DesktopContent.mouseMove);
1908 
1909  el.style.overflow = "auto";
1910 
1911  return {"w" : w, "h" : h, "x" : x, "y" : y};
1912 
1913 } //end setPopUpPosition()
1914 
1915 //=====================================================================================
1916 //parseColor ~~
1917 DesktopContent.parseColor = function(colorStr)
1918 {
1919  //used to ignore the alpha in the color when returning to user
1920 
1921  //in general need to create an element.. but since all the color strings are rgb or rgba from settings, can simplify
1922  var m = colorStr.split("(")[1].split(")")[0].split(",");
1923  if( m) return "rgb("+m[0]+","+m[1]+","+m[2]+")";
1924  else throw new Error("Color "+colorStr+" could not be parsed.");
1925 } //end parseColor()
1926 
1927 //=====================================================================================
1928 //getColorAsRGBA ~~
1929 // http://stackoverflow.com/questions/11068240/what-is-the-most-efficient-way-to-parse-a-css-color-in-javascript
1930 // except the solution is broken.. unless you add element to page
1931 DesktopContent.getColorAsRGBA = function(colorStr)
1932 {
1933 
1934  //in general need to create an element..
1935  var div = document.createElement('div');
1936  var m;
1937 
1938  div.style.color = colorStr;
1939  div.style.display = "none";
1940  document.body.appendChild(div);
1941 
1942  m = getComputedStyle(div).color.split("(")[1].split(")")[0].split(",");
1943 
1944  document.body.removeChild(div);
1945 
1946  if(m && m.length == 3) return "rgba("+m[0]+","+m[1]+","+m[2]+",255)";
1947  else if(m && m.length == 4) return "rgba("+m[0]+","+m[1]+","+m[2]+","+m[3]+")";
1948  else throw new Error("Color "+colorStr+" could not be parsed.");
1949 } //end getColorAsRGBA()
1950 
1951 //=====================================================================================
1952 //get window and mouse info ~~
1953 DesktopContent.getWindowWidth = function() { return window.innerWidth-1; } //-1 to avoid weird rounding effects by browser that cause scroll bars
1954 DesktopContent.getWindowHeight = function() { return window.innerHeight-1; } //-1 to avoid weird rounding effects by browser that cause scroll bars
1955 DesktopContent.getBodyWidth = function() { return document.body.offsetWidth; }
1956 DesktopContent.getBodyHeight = function() { return document.body.offsetHeight; }
1957 DesktopContent.getWindowScrollLeft = function() { return document.documentElement.scrollLeft || document.body.scrollLeft || 0; }
1958 DesktopContent.getWindowScrollTop = function() { return document.documentElement.scrollTop || document.body.scrollTop || 0; }
1959 DesktopContent.getMouseX = function() { return DesktopContent._windowMouseX | 0; } //force to int
1960 DesktopContent.getMouseY = function() { return DesktopContent._windowMouseY | 0; } //force to int
1961 DesktopContent.getDefaultWindowColor = function() {
1962  //return the alpha mix of window color and desktop color
1963  if(!DesktopContent._windowColorPostbox || !DesktopContent._desktopColor)
1964  {
1965  //likely in wizard mode
1966  Debug.log("Color post boxes not setup! So giving default.",Debug.MED_PRIORITY);
1967  return "rgb(178,210,240)";
1968  }
1969 
1970  wrgba = DesktopContent._windowColorPostbox.split("(")[1].split(")")[0].split(",");
1971  drgb = DesktopContent._desktopColor.split("(")[1].split(")")[0].split(",");
1972  for(var i in drgb)
1973  drgb[i] = (drgb[i]*(1-wrgba[3]) + wrgba[i]*wrgba[3])|0; //floor of blend
1974  return "rgb("+drgb[0]+","+drgb[1]+","+drgb[2]+")";
1975 } //end getDefaultWindowColor()
1976 
1977 //=====================================================================================
1978 //get color scheme ~~
1979 DesktopContent.getDefaultDashboardColor = function() { return DesktopContent.parseColor(DesktopContent._dashboardColorPostbox); }//DesktopContent.parseColor(DesktopContent._dashboardColorPostbox.innerHTML); }
1980 DesktopContent.getDefaultDesktopColor = function() {
1981  if(!DesktopContent._desktopColor)
1982  {
1983  //likely in wizard mode
1984  Debug.log("Color post boxes not setup! So giving default.",Debug.MED_PRIORITY);
1985  return "rgb(15,34,105)";
1986  }
1987  Debug.log("Returning desktop color");
1988  return DesktopContent._desktopColor;
1989 } //end getDefaultDesktopColor()
1990 
1991 //=====================================================================================
1992 //getUsername ~~
1993 DesktopContent.getUsername = function() {
1994 
1995  DesktopContent.XMLHttpRequest(
1996  "Request?RequestType=GetUserDisplayName",
1997  "",
1998  function(req)
1999  {
2000  console.log(req);
2001 
2002  });
2003  var dispName = ""; //DesktopContent._theWindow.parent.document.getElementById("DesktopDashboard-user-displayName").innerHTML
2004  return dispName.substr(dispName.indexOf(",")+2);
2005 } //end getUsername()
2006 
2007 
2008 //=====================================================================================
2009 //openNewWindow ~~
2010 // first wait for mailbox to be clear
2011 // then take mailbox
2012 DesktopContent.openNewWindow = function(name,subname,windowPath,unique,completeHandler) {
2013 
2014  Debug.log("DesktopContent.openNewWindow= " + windowPath);
2015  Debug.log("name= " + name);
2016  Debug.log("subname= " + subname);
2017  Debug.log("unique= " + unique);
2018 
2019  //launch request to desktop
2020  DesktopContent._theDesktopWindow.postMessage(
2021  {
2022  "windowId": DesktopContent._theWindowId,
2023  "request": "openNewWindow",
2024  "windowName": name,
2025  "windowSubname": subname,
2026  "windowUnique": unique,
2027  "windowPath": windowPath
2028  },"*");
2029 
2030  if(completeHandler)
2031  completeHandler(); //call parameter handler
2032  return;
2033 
2034 // //extract params from DesktopContent._openWindowMailbox
2035 // //get parameters
2036 // var paramsStr = DesktopContent._openWindowMailbox.innerHTML;
2037 //
2038 //
2039 // var tryAgainCount = 0;
2040 //
2041 //
2042 // if(paramsStr != "") //then wait
2043 // {
2044 // Debug.log("Window creation is busy, trying again soon!");
2045 //
2046 // ++tryAgainCount;
2047 //
2048 // if(tryAgainCount > 50)
2049 // {
2050 // Debug.log("It looks like the window failed to open. Perhaps the Desktop is disconnected from the server; " +
2051 // "please reconnect and try again.", Debug.WARN_PRIORITY);
2052 // return;
2053 // }
2054 //
2055 // setTimeout(function(){ DesktopContent.openNewWindow(windowPath); }, 100);
2056 // return;
2057 // }
2058 //
2059 // //free to attempt to open window!
2060 // var str = "requestingWindowId=" + DesktopContent._myDesktopFrame.id.split('-')[1];
2061 // str += "&windowName=" + name;
2062 // str += "&windowSubname=" + subname;
2063 // str += "&windowUnique=" + unique;
2064 // str += "&windowPath=" + windowPath;
2065 // DesktopContent._openWindowMailbox.innerHTML = str;
2066 //
2067 // Debug.log("Waiting for complete...");
2068 //
2069 // tryAgainCount = 0;
2070 // var timeoutHandler = function() {
2071 // Debug.log("Checking for complete...");
2072 //
2073 // ++tryAgainCount;
2074 //
2075 // if(tryAgainCount > 50)
2076 // {
2077 // Debug.log("It looks like the window failed to open. Perhaps the Desktop is disconnected from the server; " +
2078 // "please reconnect and try again.", Debug.WARN_PRIORITY);
2079 // return;
2080 // }
2081 //
2082 // //extract params from DesktopContent._openWindowMailbox
2083 // //get parameters
2084 // var paramsStr = DesktopContent._openWindowMailbox.innerHTML;
2085 // var spliti = paramsStr.indexOf('&amp;');
2086 // params = [paramsStr.substr(0,spliti),paramsStr.substr(spliti+5)];
2087 // var varPair;
2088 // var requestingWindowId = "", done = "";
2089 // for(var i=0;i<params.length;++i)
2090 // {
2091 // spliti = params[i].indexOf('=');
2092 // varPair = [params[i].substr(0,spliti),params[i].substr(spliti+1)];
2093 // if(varPair[0] == "requestingWindowId")
2094 // requestingWindowId = varPair[1];
2095 // else if(varPair[0] == "done")
2096 // done = varPair[1];
2097 // }
2098 //
2099 // if(paramsStr = "" || (requestingWindowId != "" && done != ""))
2100 // {
2101 // //assume done!
2102 // Debug.log("requestingWindowId=" + requestingWindowId);
2103 // Debug.log("done=" + done);
2104 // if(requestingWindowId != DesktopContent._myDesktopFrame.id.split('-')[1])
2105 // Debug.log("There was a mismatch in window id!",Debug.MED_PRIORITY);
2106 //
2107 // //clear mailbox
2108 // DesktopContent._openWindowMailbox.innerHTML = "";
2109 //
2110 // if(completeHandler)
2111 // completeHandler(); //call parameter handler
2112 // return;
2113 // }
2114 // else //try again
2115 // setTimeout(timeoutHandler, 100); //try again
2116 //
2117 // }; //end setTimeout handler
2118 //
2119 // setTimeout(timeoutHandler,
2120 // 100); //end setTimeout
2121 
2122 } // end openNewWindow
2123 
2124 //=====================================================================================
2125 //openNewBrowserTab ~~
2126 // first wait for mailbox to be clear
2127 // then take mailbox
2128 //
2129 // Note: to open a window just using the Desktop icon name, leave subname and unique undefined
2130 // window path can optionially be used to send the window additional parameters, or left undefined.
2131 DesktopContent.openNewBrowserTab = function(name,subname,windowPath,unique)
2132 {
2133 
2134  if(windowPath !== undefined)
2135  {
2136  //remove leading ? because Desktop.js handling expects no leading ?
2137  if(windowPath[0] == '?')
2138  windowPath = windowPath.substr(1);
2139 
2140  //for windowPath, need to check lid=## is terminated with /
2141  // check from = that there is nothing but numbers
2142  try
2143  {
2144  var i = windowPath.indexOf("urn:xdaq-application:lid=") + ("urn:xdaq-application:lid=").length;
2145  var isAllNumbers = true;
2146  for(i;i<windowPath.length;++i)
2147  {
2148  //Debug.log(windowPath[i]);
2149 
2150  if(windowPath[i] < "0" || windowPath[i] > "9")
2151  {
2152  isAllNumbers = false;
2153  break;
2154  }
2155  }
2156  if(isAllNumbers)
2157  windowPath += "/";
2158  }
2159  catch(e)
2160  {
2161  Debug.log("An error occurred while trying to open the window. " +
2162  "The window path seems to be invalid:[" + DesktopContent.getExceptionLineNumber(e) + "]: " + e, Debug.HIGH_PRIORITY);
2163  return;
2164  }
2165  }
2166  Debug.log("DesktopWindow= " + windowPath);
2167 
2168  Debug.log("name= " + name);
2169  Debug.log("subname= " + subname);
2170  Debug.log("unique= " + unique);
2171 
2172  //var search = DesktopContent._theWindow.parent.parent.window.location.search;
2173  url = DesktopContent._serverOrigin +
2174  "/urn:xdaq-application:lid="+DesktopContent._serverUrnLid+"/";//DesktopContent._theWindow.parent.parent.window.location.pathname;
2175 
2176 
2177 
2178  var str = "requestingWindowId=" + DesktopContent._theWindowId;//DesktopContent._myDesktopFrame.id.split('-')[1];
2179  str += "&windowName=" + name;
2180  str += "&windowSubname=" + subname;
2181  str += "&windowUnique=" + unique;
2182  str += "&windowPath=" + windowPath;
2183 
2184 
2185  if(DesktopContent._sequence)
2186  url += "Verify?code=" + DesktopContent._sequence + "&" + str;
2187  else
2188  url += "?" + str;
2189 
2190  //if there is no search, need to check lid=## is terminated with /
2191  // check from = that there is nothing but numbers
2192 
2193 // if(search == "")
2194 // {
2195 // var i = url.indexOf("urn:xdaq-application:lid=") + ("urn:xdaq-application:lid=").length;
2196 // var isAllNumbers = true;
2197 // for(i;i<url.length;++i)
2198 // {
2199 // Debug.log(url[i]);
2200 //
2201 // if(url[i] < "0" || url[i] > "9")
2202 // {
2203 // isAllNumbers = false;
2204 // break;
2205 // }
2206 // }
2207 // if(isAllNumbers)
2208 // url += "/";
2209 // url += "?" + str;
2210 // }
2211 // else
2212 // {
2213 // //remove, possibly recursive, former new windows through url
2214 // var i = search.indexOf("requestingWindowId");
2215 // if(i >= 0)
2216 // search = search.substr(0,i);
2217 //
2218 // //replace sequence with updated sequence
2219 // if(search.substr(0,6) == "?code=")
2220 // {
2221 // i = search.substr('&');
2222 // search = "?code=" + DesktopContent._sequence +
2223 // (i>0?search.substr(i):"");
2224 // }
2225 //
2226 // //only add & if there are other parameters
2227 // if(search.length && search[search.length-1] != '?'
2228 // && search[search.length-1] != '&')
2229 // search += '&';
2230 // url += search + str;
2231 // }
2232 
2233  Debug.log("DesktopContent.openNewBrowserTab= " + url);
2234  //DesktopContent.openNewBrowserTab= /urn:xdaq-application:lid=200/?requestingWindowId=1002&windowName=ARTDAQ Config&windowSubname=&windowUnique=false&windowPath=/WebPath/html/ConfigurationGUI_artdaq.html?urn=281
2235  window.open(url,'_blank');
2236 
2237 
2238  return;
2239 
2240 
2241  if(windowPath !== undefined)
2242  {
2243  //remove leading ? because Desktop.js handling expects no leading ?
2244  if(windowPath[0] == '?')
2245  windowPath = windowPath.substr(1);
2246 
2247  //for windowPath, need to check lid=## is terminated with /
2248  // check from = that there is nothing but numbers
2249  try
2250  {
2251  var i = windowPath.indexOf("urn:xdaq-application:lid=") + ("urn:xdaq-application:lid=").length;
2252  var isAllNumbers = true;
2253  for(i;i<windowPath.length;++i)
2254  {
2255  //Debug.log(windowPath[i]);
2256 
2257  if(windowPath[i] < "0" || windowPath[i] > "9")
2258  {
2259  isAllNumbers = false;
2260  break;
2261  }
2262  }
2263  if(isAllNumbers)
2264  windowPath += "/";
2265  }
2266  catch(e)
2267  {
2268  Debug.log("An error occurred while trying to open the window. " +
2269  "The window path seems to be invalid:[" + DesktopContent.getExceptionLineNumber(e) + "]: " + e, Debug.HIGH_PRIORITY);
2270  return;
2271  }
2272  }
2273  Debug.log("DesktopWindow= " + windowPath);
2274 
2275  Debug.log("name= " + name);
2276  Debug.log("subname= " + subname);
2277  Debug.log("unique= " + unique);
2278 
2279  var search = DesktopContent._theWindow.parent.parent.window.location.search;
2280  url = DesktopContent._theWindow.parent.parent.window.location.pathname;
2281 
2282  var str = "requestingWindowId=" + DesktopContent._theWindowId;//DesktopContent._myDesktopFrame.id.split('-')[1];
2283  str += "&windowName=" + name;
2284  str += "&windowSubname=" + subname;
2285  str += "&windowUnique=" + unique;
2286  str += "&windowPath=" + windowPath;
2287 
2288  //if there is no search, need to check lid=## is terminated with /
2289  // check from = that there is nothing but numbers
2290 
2291  if(search == "")
2292  {
2293  var i = url.indexOf("urn:xdaq-application:lid=") + ("urn:xdaq-application:lid=").length;
2294  var isAllNumbers = true;
2295  for(i;i<url.length;++i)
2296  {
2297  Debug.log(url[i]);
2298 
2299  if(url[i] < "0" || url[i] > "9")
2300  {
2301  isAllNumbers = false;
2302  break;
2303  }
2304  }
2305  if(isAllNumbers)
2306  url += "/";
2307  url += "?" + str;
2308  }
2309  else
2310  {
2311  //remove, possibly recursive, former new windows through url
2312  var i = search.indexOf("requestingWindowId");
2313  if(i >= 0)
2314  search = search.substr(0,i);
2315 
2316  //replace sequence with updated sequence
2317  if(search.substr(0,6) == "?code=")
2318  {
2319  i = search.substr('&');
2320  search = "?code=" + DesktopContent._sequence +
2321  (i>0?search.substr(i):"");
2322  }
2323 
2324  //only add & if there are other parameters
2325  if(search.length && search[search.length-1] != '?'
2326  && search[search.length-1] != '&')
2327  search += '&';
2328  url += search + str;
2329  }
2330 
2331  Debug.log("DesktopContent.openNewBrowserTab= " + url);
2332  //DesktopContent.openNewBrowserTab= /urn:xdaq-application:lid=200/?requestingWindowId=1002&windowName=ARTDAQ Config&windowSubname=&windowUnique=false&windowPath=/WebPath/html/ConfigurationGUI_artdaq.html?urn=281
2333  window.open(url,'_blank');
2334 } // end openNewBrowserTab()
2335 
2336 //=====================================================================================
2337 //addDesktopIcon ~~
2338 // modify active context to include the new desktop icon
2339 // reset desktop icons
2340 //
2341 // Note: linkedApp can be the app LID, UID, or class type
2342 DesktopContent.addDesktopIcon = function(caption, altText,
2343  folderPath, unique, permissionString,
2344  imageURL, windowContentURL, linkedApp, parameters) {
2345 
2346  var iconParameters = "";
2347  if(parameters && parameters.length)
2348  {
2349  if(typeof parameters === "string")
2350  iconParameters = parameters; //just take string, if not object
2351  else //take parameters from object
2352  for(var i in parametersObject)
2353  {
2354  iconParameters += encodeURIComponent(i) + "=" +
2355  encodeURIComponent(iconParameters[i]) + "&";
2356  }
2357  }
2358 
2359  Debug.log("iconParameters = " + iconParameters);
2360 
2361  var iconLinkedApp = "";
2362  var iconLinkedAppLID = 0;
2363  if(linkedApp)
2364  {
2365  if((linkedApp|0) > 0)
2366  iconLinkedAppLID = linkedApp|0;
2367  else
2368  iconLinkedApp = linkedApp; //could be app UID or class
2369  }
2370 
2371  var req = "Request?RequestType=addDesktopIcon"
2372  /*get data*/
2373  + "&iconCaption=" + encodeURIComponent(caption)
2374  + "&iconAltText=" + encodeURIComponent(altText)
2375  + "&iconFolderPath=" + encodeURIComponent(folderPath)
2376  + "&iconPermissions=" + encodeURIComponent(permissionString)
2377  + "&iconImageURL=" + encodeURIComponent(imageURL)
2378  + "&iconWindowURL=" + encodeURIComponent(windowContentURL)
2379  + "&iconEnforceOneWindowInstance=" + (unique?"1":"0")
2380  + (iconLinkedAppLID?
2381  ("&iconLinkedAppLID=" + iconLinkedAppLID):
2382  ("&iconLinkedApp=" + iconLinkedApp)
2383  );
2384 
2385  Debug.log("Create Icon req = " + req);
2386 
2387  DesktopContent.XMLHttpRequest(req,
2388  /*post data*/
2389  "iconParameters=" + encodeURIComponent(iconParameters)
2390  ,
2391  function(req)
2392  {
2393  Debug.log("Successfully added icon '" +
2394  caption +
2395  "!'",Debug.INFO_PRIORITY);
2396 
2397  //if available update active system configuration handler, to display changes
2398  if(activateSystemConfigHandler)
2399  {
2400  activateSystemConfigHandler(req);
2401  }
2402 
2403 // if(!DesktopContent._blockSystemCheckMailbox &&
2404 // DesktopContent._blockSystemCheckMailbox.innerHTML == "")
2405 // {
2406 // //inform Desktop.js to refresh icons (handled by _checkMailboxes())
2407 // DesktopContent._blockSystemCheckMailbox.innerHTML = "RefreshIcons";
2408 // }
2409 
2410  //inform Desktop.js to refresh icons (handled by _checkMailboxes())
2411  DesktopContent._theDesktopWindow.postMessage(
2412  {
2413  "windowId": DesktopContent._theWindowId,
2414  "request": "refreshIcons"
2415  },"*");
2416 
2417  }, //end request handler
2418  0 /*reqParam*/, 0 /*progressHandler*/, false /*callHandlerOnErr*/,
2419  false /*doNotShowLoadingOverlay*/,
2420  true /*targetSupervisor*/); //end XMLHttpRequest() call
2421 
2422 } //end addDesktopIcon()
2423 
2424 //=====================================================================================
2425 DesktopContent.systemBlackout = function(doBlackout)
2426 {
2427  Debug.log("systemBlackout =" + doBlackout);
2428  //inform Desktop.js to refresh icons (handled by _checkMailboxes())
2429  DesktopContent._theDesktopWindow.postMessage(
2430  {
2431  "windowId": DesktopContent._theWindowId,
2432  "request": (doBlackout?"startSystemBlackout":"stopSystemBlackout")
2433  },"*");
2434 } //end systemBlackout()
2435 
2436 //=====================================================================================
2437 //getDesktopWindowTitle ~~
2438 // returns the text in header of the current desktop window
2439 DesktopContent.getDesktopWindowTitle = function()
2440 {
2441  return DesktopContent._theWindow.parent.document.getElementById(
2442  "DesktopWindowHeader-" +
2443  DesktopContent._theWindow.name.split('-')[1]).innerHTML;
2444 } //end getDesktopWindowTitle()
2445 
2446 DesktopContent.getExceptionLineNumber = function(e)
2447 {
2448  try
2449  {
2450  console.log(e);
2451  return e.stack.split('\n')[1].split(':')[4].split(')')[0]|0; }
2452  catch(newError) { return -1; } //hide error and give invalid line number
2453 } //end getExceptionLineNumber()
2454 
2455 
2456 
2457 
2458 
2459 
2460 
2461 
2462 
2463 
2464