PageSourceSearch

https://www.venangocountypa.gov/revize/util/snippet_helper.js

js venangocountypa.gov collected 2026-10-04 09:29:56 UTC 226,574 bytes, 6,393 lines download raw bytes

1/*
2#############################################################################
3##
4## 	file: .../util/snippet_helper.js
5##
6## 	JavaScript Library used on all Revize html pages
7##
8## 	Copyright (C) 2000-2014 Revize Software Systems All rights reserved.
9##
10##	--------------------------------------------
11##	Source Code Changes Required for Doc-O-Matic
12##	--------------------------------------------
13##
14##	Separate text with blank lines to force new link on output
15##
16##	Use ## to ignore lines in Doc-O-Matic (like these comments)
17##
18##	Bracket initialization code with the following:
19##		//DOM-IGNORE-BEGIN
20##		//DOM-IGNORE-END
21##
22##	Below are sample sections used:
23##
24##		For RZ.*** input arguments use one of the following section names
25##
26##			RZ Parameters:
27##			RZ Input Parameters:
28##
29##		Internal: Called by
30##		then start description with (Internal Function) ...
31##
32##		Future: under development (may be available in a later release)
33##
34##		Parameters:
35##		  	None: (no input parameters)
36##
37##		Returns:
38##		  	no value currently returned
39##
40## Add the following as preceeding comment for deprecated functions
41## 		Same as RZcalleditlist (retained for backward compatibility)
42*/
43/****************************************************************************
44##	First part of code below executes before the onload handler
45****************************************************************************/
46
47/*---------------------------------------------------------------------------
48Define RZ object and variables if not already defined.
49----------------------------------------------------------------------------*/
50if (!window.EZ) EZ = {};
51if (!EZ.isFeature) EZ.isFeature = function() {return false};
52
53if (typeof RZ == 'undefined') var RZ = new Object();
54if (typeof RZ.pagetype == 'undefined') RZ.pagetype = '';
55if (typeof RZ.jsversion == 'undefined') RZ.jsversion = '1.2';
56
57//********************************************************\\
58RZ.snippet_helper_version = '02-20-2014';
59//********************************************************//
60
61//-----	Define additional RZ objects used by javascript library functions
62if (typeof RZ.rte == 'undefined') RZ.rte = new Object();
63if (typeof RZ.link == 'undefined') RZ.link = new Object();
64if (typeof RZ.icons == 'undefined') RZ.icons = new Array();
65if (typeof RZ.image == 'undefined') RZ.image = new Object();
66if (typeof RZ.setvalues == 'undefined') RZ.setvalues = new Object();
67if (typeof RZ.control == 'undefined') RZ.control = new Object();
68if (typeof RZ.permits == 'undefined') RZ.permits = new Object();
69if (typeof RZ.permits.modules == 'undefined') RZ.permits.modules = new Object();
70if (typeof RZ.linkpagekey == 'undefined') RZ.linkpagekey = new Object();
71if (typeof RZ.linkparentnew == 'undefined') RZ.linkparentnew = new Object();
72if (typeof RZ.linkparentreset == 'undefined') RZ.linkparentreset = new Object();
73if (typeof RZ.linktemplates == 'undefined') RZ.linktemplates = new Object();
74if (typeof RZ.badlinks == 'undefined') RZ.badlinks = new Object();
75if (typeof RZ.warning == 'undefined') RZ.warning = '';
76if (typeof RZ.alert == 'undefined') RZ.alert = '';
77RZ.linklevel = -1
78RZ.nextseq = {linknames:{},modules:{}};	//can be removed after all channels published
79
80// For very old backward compatibility (probably build 27-) on templates
81RZ.webSpaceName = RZ.webspace;
82var rzRecordID = RZ.editrecordid;
83/*---------------------------------------------------------------------------
84Call additional setup functions as soon as JavaScript is compiled.
85
86TODO: all inline code should be moved to onload handler to eliminate race
87	  conditions mostly using image mananger with Firefox as of 08-01-2009
88	  Of course some code is needed to hide or display buttons so that login
89	  would need reworking (probably display:none until page loads)
90
91	  Consider RZeventadd(..) allowing this file in head for all scenaios
92----------------------------------------------------------------------------*/
93RZpageSetup();		// get page into
94RZpermits();		// setup module permissions
95RZpagepermission()	// determine page permission
96RZactionReset();  	// clear all action button input arguments
97RZpageLoaded();		// final page setup
98
99/****************************************************************************
100Remaining code defines javaScript library functions
101****************************************************************************/
102/*!
103  * Bowser - a browser detector
104  * https://github.com/ded/bowser
105  * MIT License | (c) Dustin Diaz 2013
106  * DCO 11-18-2015: function renamed by code not changed
107  */
108function RZbowser()
109{
110 /**
111    * navigator.userAgent =>
112    * Chrome:  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57 Safari/534.24"
113    * Opera:   "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.7; U; en) Presto/2.7.62 Version/11.01"
114    * Safari:  "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
115    * IE:      "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)"
116    * IE>=11:  "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; Media Center PC 6.0; rv:11.0) like Gecko"
117    * Firefox: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0) Gecko/20100101 Firefox/4.0"
118    * iPhone:  "Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5"
119    * iPad:    "Mozilla/5.0 (iPad; U; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5",
120    * Android: "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; T-Mobile G2 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
121    * Touchpad: "Mozilla/5.0 (hp-tabled;Linux;hpwOS/3.0.5; U; en-US)) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0"
122    * PhantomJS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34"
123    */
124
125  var ua = navigator.userAgent
126    , t = true
127    , ie = /(msie|trident)/i.test(ua)
128    , chrome = /chrome/i.test(ua)
129    , phantom = /phantom/i.test(ua)
130    , safari = /safari/i.test(ua) && !chrome && !phantom
131    , iphone = /iphone/i.test(ua)
132    , ipad = /ipad/i.test(ua)
133    , touchpad = /touchpad/i.test(ua)
134    , android = /android/i.test(ua)
135    , opera = /opera/i.test(ua) || /opr/i.test(ua)
136    , firefox = /firefox/i.test(ua)
137    , gecko = /gecko\//i.test(ua)
138    , seamonkey = /seamonkey\//i.test(ua)
139    , webkitVersion = /version\/(\d+(\.\d+)?)/i
140    , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i
141    , o
142
143  function detect() {
144
145    if (ie) return {
146        msie: t
147      , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2]
148      }
149    if (opera) return {
150        opera: t
151      , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i)[1]
152      }
153    if (chrome) return {
154        webkit: t
155      , chrome: t
156      , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1]
157      }
158    if (phantom) return {
159        webkit: t
160      , phantom: t
161      , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1]
162      }
163    if (touchpad) return {
164        webkit: t
165      , touchpad: t
166      , version : ua.match(/touchpad\/(\d+(\.\d+)?)/i)[1]
167      }
168    if (iphone || ipad) {
169      o = {
170        webkit: t
171      , mobile: t
172      , ios: t
173      , iphone: iphone
174      , ipad: ipad
175      , version: (ua.match(/CPU iPhone OS ([0-9_]+) like Mac OS X/i)[1] || '1.1.1').replace('_', '.')
176      }
177      return o
178    }
179    if (android) return {
180        webkit: t
181      , android: t
182      , mobile: t
183      , version: (ua.match(/Linux; Android ([0-9.]+)/i) || ua.match(firefoxVersion))[1]
184      }
185    if (safari) return {
186        webkit: t
187      , safari: t
188      , version: ua.match(webkitVersion)[1]
189      }
190    if (gecko) {
191      o = {
192        gecko: t
193      , mozilla: t
194      , version: ua.match(firefoxVersion)[1]
195      }
196      if (firefox) o.firefox = t
197      return o
198    }
199    if (seamonkey) return {
200        seamonkey: t
201      , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1]
202      }
203    return {}
204  }
205
206  var bowser = detect()
207
208  // Graded Browser Support
209  // http://developer.yahoo.com/yui/articles/gbs
210  if ((bowser.msie && bowser.version >= 8) ||
211      (bowser.chrome && bowser.version >= 10) ||
212      (bowser.firefox && bowser.version >= 4.0) ||
213      (bowser.safari && bowser.version >= 5) ||
214      (bowser.opera && bowser.version >= 10.0)) {
215    bowser.a = t;
216  }
217
218  else if ((bowser.msie && bowser.version < 8) ||
219      (bowser.chrome && bowser.version < 10) ||
220      (bowser.firefox && bowser.version < 4.0) ||
221      (bowser.safari && bowser.version < 5) ||
222      (bowser.opera && bowser.version < 10.0)) {
223    bowser.c = t
224  } else bowser.x = t
225
226  return bowser
227}
228/*---------------------------------------------------------------------------
229(Internal Function) Set page information and display in trace window
230Internal: Called by onload handler
231----------------------------------------------------------------------------*/
232function RZpageSetup()
233{
234	//----- Set flags
235	RZ.revizepreview = false
236
237	//----- Set browser settings
238	RZ.MSIE = false       // MS explorer mode
239	RZ.isnavigator = true // Netscape
240	RZ.pos = navigator.appVersion.indexOf('MSIE')
241	if(RZ.pos != -1)
242	{
243		RZ.MSIE = true
244		RZ.isnavigator = false
245	}
246	if (RZ.isnavigator)
247	{
248		RZ.language = navigator.language.substring(0,2)
249		RZ.browserversion = parseFloat(navigator.appVersion)
250	}
251	else
252	{
253		RZ.language = navigator.userLanguage.substring(0,2)
254		RZ.browserversion = parseFloat(navigator.appVersion.substring(RZ.pos+4))
255	}
256	if (navigator.appVersion.toLowerCase().indexOf('windows') != -1)
257	{
258		RZ.platform = 'win'
259		RZ.newline = '\r\n'
260	}
261	else
262	{
263		RZ.newline = '\r'
264		RZ.platform = 'mac'
265	}
266	//CREDIT: http://stackoverflow.com/questions/17447373/how-can-i-target-only-internet-explorer-11-with-javascript
267	//		  probably copied incorrectly because true/false switched (see not below)
268	//Following 2 lines depreciated
269	RZ.isIE11 = !navigator.userAgent.match(/Trident.*rv 11\./)	//true for any browser
270	RZ.isIEstandards = !navigator.userAgent.match(/Trident/)	//false for any IE ver; true if not any IE
271
272	//DCO 01-23-2014 (CREDIT: tiny_mce.3.5.10/tiny_mcs)
273	RZ.isIEstandardsMode = navigator.userAgent.match(/Trident/)	//array for any IE ver (i.e. true)
274
275	//DCO 03-26-2014: latest attempt at code that will pass the test of time
276	RZ.isIEw3c = !RZ.MSIE && navigator.userAgent.indexOf('Trident') != -1 && navigator.appCodeName.indexOf('Mozilla') != -1;
277
278	//DJO 04-22-2016: add MS edge user agent detection
279	RZ.isMSEdge = navigator.userAgent.match(/Edge/);
280
281	//DCO 12-16-2015: refactor w/o calling RZbowser() -- gets js error on iPad
282	var results, ua = navigator.userAgent
283	RZ.isMSIE = /(msie|trident)/i.test(ua);
284	RZ.isChrome = /chrome/i.test(ua);
285	RZ.isFirefox = /firefox/i.test(ua);
286	if (RZ.isMSIE)
287	{				//nogo for IE5 returns 7 but who cares
288		results = ua.match(/(msie |rv:)(\d+(\.\d+)?)/i);
289		if (results && results[2])
290			RZ.browserversion = results[2];
291	}
292	else if (RZ.isChrome)
293	{
294		results = ua.match(/chrome\/(\d+(\.\d+)?)/i)
295		if (results && results[1])
296			RZ.browserversion = results[1];
297	}
298	else if (RZ.isFirefox)
299	{				//seems to work but not 100% sure
300		results = ua.match(/firefox\/(\d+(\.\d+)?)/i)
301		if (results && results[1])
302			RZ.browserversion = results[1];
303	}
304
305	//----- Does browser support css (only old versions of navigator did not support)
306	//		Assume true to avoid race condition with image manager on Firefox
307	RZ.css = true;
308
309	//----- Parent window if accessable (otherwise current window)
310	//		TODO: susceptible to race condition with image_frame.jsp on Firefox
311	RZ.parent = window;
312	if (RZwinaccess(window.parent)) RZ.parent = window.parent;
313
314	//----- Set page information, login webspace and display page properties
315	RZ.page = RZgetfileinfo( location.href )
316
317	/* disabled 08-15-2012; causing issues on some versions of chrome, trace not
318	// enabled yet so it never prints AND superceeded by AdminPanel enhancements.
319	RZ.message = 'RZ.webspace: ' + RZ.webspace + '\n'
320			   + 'RZ.page.domain: ' + RZ.page.domain + '\n'
321			   + 'RZ.page.pathname: ' + RZ.page.pathname + '\n'
322			   + 'RZ.page.filename: ' + RZ.page.filename + '\n'
323			   + 'RZ.page.extension: ' + RZ.page.extension + '\n'
324			   + 'RZ.page.query: ' + RZ.page.query + '\n'
325			   + 'RZ.page.hash: ' + RZ.page.hash + '\n'
326			   + 'RZ.page.home: ' + RZ.page.home + '\n'
327			   + 'window.name: ' + window.name + '\n'
328			   + 'document.referrer: ' + document.referrer + '\n'
329			   + 'opener: '
330	if (RZwinaccess(RZ.parent.opener))
331	{
332		RZ.message += RZ.parent.opener.location.href + '\n'
333		if (RZ.parent.opener.name != '')
334			RZ.message += 'opener.name: ' + RZ.parent.opener.name
335	}
336	else if (typeof RZ.parent != 'undefined')
337		RZ.message += 'no access to opener'
338	else
339		RZ.message += 'no opener'
340
341	RZtrace("Initializing Page", RZ.message)
342	*/
343
344	RZ.login = RZgetCookieValue('RZlogin', RZ.page.domain);
345
346	//----- Determine trace and debug mode
347	RZ.trace = false;	//RZcheckHash('trace');		//issues on some versions of chrome...
348	RZ.debug = false;	//RZcheckHash('debug');		//...superceeded by enhanced adminpanel
349
350	if (RZ.webspace && RZ.webspace != 'REVIZE')
351	{
352		var trace = RZgetcookie('RZtrace',RZ.page.domain);
353		if (trace == RZ.webspace)
354			RZ.trace = true;
355		else if (trace != RZ.webspace)
356			RZsetcookie('RZtrace', (RZ.trace ? RZ.webspace : '') ,RZ.page.domain);
357
358		var debug = RZgetcookie('RZdebug',RZ.page.domain);
359		if (debug == RZ.webspace)
360			RZ.debug = true;
361		else if (debug != RZ.webspace)
362			RZsetcookie('RZdebug', (RZ.debug ? RZ.webspace : '') ,RZ.page.domain);
363	}
364
365	//----- Determine if called from workflow preview
366	if (RZwinaccess(parent))
367	{
368		if (parent.window.name=='revizepreview')
369			RZ.revizepreview = true
370
371		if ((parent.window.name != window.name			//must be in frames
372		&& parent.window.name=='revizepreview') || window.name == 'workflowCompare1' || window.name == 'workflowCompare2' )
373		{
374			RZ.login = ''
375			//RZ.revizepreview = true
376			RZsetuphandler( 'onpagehide', 'return RZtemplateclose()' )
377		}
378	}
379	else
380	{
381		// if standard permissions button and logged in as admin, treat as "Admin Panel"
382		// TODO: can be removed once break keyup is solid
383 		var permisisonButton = document.getElementById('RZadminwinButton')
384		if (permisisonButton
385		//&& RZisadmin()
386		//&& navigator.userAgent.indexOf("Firefox") == -1
387		&& !RZcheckoptions(RZ.webspacedesc,"noadminpanel")
388		&& permisisonButton.src.search('images/edit/permissions\\.(jpg|gif)') != -1)
389		{
390			permisisonButton.href = 'javascript:RZadminwin()';
391			permisisonButton.alt = 'Admin Panel';
392		}
393	}
394
395	/**********************************************************/
396	/*BOOKMARK RZpageSetup() DONE if AdminPanel not supported*/
397	/********************************************************/
398	if (RZ.revizepreview) return;
399	if (location.pathname.search(/(calendar_app\/index.html|calendar_app\/?$)/) != -1) return;
400	if (location.pathname.search(/.*\/calendar_app\/(editpages\/)?calendar_.*\.(html|jsp)/) != -1) return;
401
402	if (location.pathname.indexOf('/revize/admincenter/') == 0) return;
403	if (location.pathname.indexOf('/revize/debug/') == 0) return;
404	if (location.pathname.indexOf('/revize/trace/') == 0) return;
405	//if (location.pathname.indexOf('/revize/plugins/') == 0) return;
406	if (location.pathname.indexOf('/revize/security/') == 0) return;
407	if (location.pathname.indexOf('/revize/util/') == 0) return;
408
409	//----- "Pause/Break" keyup event monitor
410	RZadminwin.keypressCount = 0;
411	RZadminwin.toggle = function(e,win)
412	{
413		RZadminwin.keypressCount++;
414		/* use following to capture F1 key
415		document.onhelp = function() {return(false);}
416		window.onhelp = function() {return(false);}
417		processF1()
418		*/
419		var keycode = (window.event) ? event.keyCode : e.keyCode;
420		if (keycode == 19 || keycode == 3 || keycode == 135)
421		{
422			if (RZ.login && RZisadmin())
423			{
424				// Show more buttons if Ctrl key also pressed
425							var more = (keycode == 3) ? 'more' : '';
426				RZadminwin('',more);
427			}
428			else if (!RZ.login && RZadminwin.keypressCount >= 2)
429			{
430				if (!confirm('Login to Revize?')) return;
431				var url = RZ.protocolRelativeRevizeBaseUrl + '/revize/security/index.jsp?webspace=' + RZ.webspace
432						+ '&filename=/' + RZ.page.filenameFull;
433				parent.location = url;
434			}
435			/*
436			else
437			{
438				var msg = 'Must login as Administrator to open AdminPanel';
439				if (RZadminwin.keypressCount >= 2) alert(msg);
440				window.status = msg;
441			}
442			*/
443		}
444	}
445
446	//----- After page loads, complete AdminPanel setup
447	RZeventadd(window, "load", function()
448	{
449		// Open AdminPanel if needed
450		if (RZisadmin()
451		&& (location.hash.indexOf('adminpanel') == 1 || RZ.debug || RZ.trace))
452			RZadminwin();
453
454		// Activate "Pause/Break" keyup event monitor
455		RZeventadd(document, "keyup", function(e) {RZadminwin.toggle(event,window)});
456	});
457}
458/*---------------------------------------------------------------------------
459----------------------------------------------------------------------------*/
460/*function RZpublishcalendars()
461{
462	var fileinfo = RZgetfileinfo(location.href);
463	var url = fileinfo.domain + location.pathname;
464	var msg = 'Publishing Calendar Templates';
465	document.getElementById(RZ.adminwinId).innerHTML = msg;
466	location.href = '/revize/debug/PublishCalendarTemplates.jsp'
467				  + '?webspace=' + RZ.webspace
468				  + '&hash=' + 'RZadminwin'
469				  + '&returnurl=' + escape(url);
470}*/
471/*---------------------------------------------------------------------------
472Show or hide updated Admin Panel
473if adminpanel.html not yet loaded, load into new absolute <div> as iframe;
474otherwise if loaded, call adminpanel.html::RZadminwin(...)
475----------------------------------------------------------------------------*/
476function RZadminwin(msg,action)
477{
478	RZadminwin.width = 680;		//outer width (iframe & its container)
479	//if (!RZisadmin()) return;
480
481	// Open adminpanel.html iframe in absolute div at top of body
482	// RZ.adminwin set to iframe window object once initialized
483	if (!RZ.adminwin)
484	{
485		RZ.adminwin = 'setup';
486		RZadminwin.action = action;			//Save for adminpanel.html
487
488		var adminDiv = document.createElement('div');
489		adminDiv.setAttribute('id','RZadminpanelContainer');
490		adminDiv.style.position = "fixed";
491		adminDiv.style.zIndex = "999999999999";
492		adminDiv.style.left = '0px';
493		adminDiv.style.top = '0px';
494		adminDiv.style.margin = '0';
495		adminDiv.style.padding = '0';
496		adminDiv.style.boxShadow = '0 0 6px rgba(0,0,0,.175)';
497		adminDiv.style.width = '100%';
498		adminDiv.style.height = '80px';		//loading height
499/* 		adminDiv.style.border = '0px none #FFF'; */
500		adminDiv.style.font = '13px Arial,Helvetica,sans-serif';
501		adminDiv.style.lineHeight = '21px';
502/* 		adminDiv.style.color = 'black'; */
503		adminDiv.style.margin = '0';
504		adminDiv.style.padding = '20px 0';
505		adminDiv.style.textAlign = 'center';
506		adminDiv.style.backgroundColor = "#ffffff";
507		adminDiv.innerHTML = '<br><b id="RZadminwin-loading">&nbsp;&nbsp;&nbsp;Loading Admin Panel...</b>';
508
509		document.body.insertBefore(adminDiv,document.body.firstChild);
510		RZadminwin.container = adminDiv;	//save for adminpanel.html
511
512		var iframe = document.createElement('iframe');
513		var	src = '/revize/admincenter/adminpanel.jsp'
514		//if (RZ.webspace == 'RostraverTownship')
515		//	src = '/revize/admincenter/adminpanel.work.jsp'
516		iframe.setAttribute('id','RZadminpanel');
517		iframe.setAttribute('src',src);
518		iframe.setAttribute('width','100%');
519		iframe.setAttribute('height','20');			//loading height
520		iframe.setAttribute('scrolling','no');
521		iframe.setAttribute('frameborder','0');
522		iframe.setAttribute('marginwidth','0');
523		iframe.setAttribute('marginheight','0');
524		iframe.style.margin = '0';
525		iframe.style.padding = '0';
526		iframe.style.border = '0px none';
527		iframe.style.visibility = "hidden"; 		//hide IE inset borders while loading
528		adminDiv.replaceChild(iframe, adminDiv.firstChild);
529		return false;
530	}
531
532	// Ignore calls after loading starts until it completes
533	else if (RZ.adminwin == 'setup')
534		return false;
535
536	return RZ.adminwin.RZadminwin('',action);
537}
538/*---------------------------------------------------------------------------
539Add a new style rule or cssRule based on browser
540
541var rules = RZaddrules('.someClass, {color:'black', zIndex:99});
542----------------------------------------------------------------------------*/
543function RZaddrules(stylesheet,selector,selectorRules)
544{
545	var cssStyle, rule, rules = '';
546	for (rule in selectorRules)
547	{
548		if (!selectorRules.hasOwnProperty(rule)) continue;
549		cssStyle = RZcssfromstyle(rule)
550		if (document.all)
551			stylesheet.addRule(selector, cssStyle + ':' + selectorRules[rule]);
552		else
553			rules +=  cssStyle + ':' + selectorRules[rule] + ';';
554	}
555	if (!document.all)
556		stylesheet.insertRule(selector + '{' + rules + '}', 0);
557}
558/*
559* converts a css style name FROM a camelCase style property
560*/
561function RZcssfromstyle(style)
562{
563	return style.replace(/([A-Z])/g,'-$1').toLowerCase();
564}
565/*
566* converts a css style name TO a camelCase style property
567*/
568function RZcsstostyle(style)
569{
570	var results;
571	while (results = style.match(/(-)(\w)/))
572	{
573		style = style.substring(0,results.index)
574			  + results[2].toUpperCase()
575			  + style.substring(results.index+results[0].length)
576	}
577	return style;
578}
579/*-----------------------------------------------------------------------------------
580Returns specified element current specified style
581
582Paramenter:
583	el 			html element or element id
584	style		css style e.g. display, backgroundColor
585
586
58702-20-2014 DCO
588	Updated code based on: http://help.dottoro.com/ljscsoax.php
589
590	Prior cos document.defaultView.getComputedStyle(el,'') returning null
591	for chrome and FF (not sure of original reference used as base)
592
593	Updated code much more bullet-proff and accomodates IE11+)
594-----------------------------------------------------------------------------------*/
595function RZelementCurrentStyleValue(el,style)
596{
597	var value = '';
598
599	/* 02-20-2014 DCO: disabled see notes above
600	if (document.all)
601		value = el.currentStyle[style];
602	else
603		value =  document.defaultView.getComputedStyle(el,'').getPropertyValue(style);
604	*/
605
606	// 02-20-2014 DCO start \\
607	var currentStyle = null;
608	if (typeof(el) == 'string')
609		el = document.getDocumentById(el);
610
611	if (typeof(el) == 'object')
612	{
613		if (window.getComputedStyle)	//chrome & FF work (others TBD per Ray)
614			currentStyle = window.getComputedStyle;
615
616		else if (el.currentStyle)		//pre IE11
617			currentStyle = el.currentStyle
618
619		if (currentStyle && currentStyle[style])
620			value = currentStyle[style];
621	}
622	// 02-20-2014 DCO end //
623
624	return value;
625}
626/*-----------------------------------------------------------------------------------
627Return array of all values found for specified CSS selector (e.g. .left, #top)
628Array is filled as selector are discovered; CSS priority is not considered.
629Upgraded to return object containing array of all values for each specified selector.
630-----------------------------------------------------------------------------------*/
631function RZselectorValues(selectors)
632{
633	// if single selector specified as string, convert to array
634	if (typeof selectors == 'string')
635		selectors = selectors.split(',');
636
637    var values = {};
638	var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules
639    for (var x=0;
639x<classes.length;x++)
640	{
641        var cssSelector = classes[x].selectorText;
642		if (RZcheckoptions(selectors,cssSelector))
643		{
644            var value = (classes[x].cssText)
645					  ? (classes[x].cssText)
646					  : (classes[x].style.cssText);
647			if (!values[cssSelector])
648				values[cssSelector] = [];
649			values[cssSelector].push(value);
650        }
651    }
652	return values;
653}
654/*---------------------------------------------------------------------------
655* Set style to value for one or more rules
656* IE can only define single selector so rules is an array
657* (for Firefox it is a single element array)
658----------------------------------------------------------------------------*/
659function changeStyle(rules,style,value)
660{
661	for (var i=0;i<rules.length;i++)
662		rules[i]['style'][style] = value;
663}
664/*---------------------------------------------------------------------------
665(Internal Function) Disables links on workflow preview page.
666Internal: Called when trying to leave workflow preview page
667or onclick for Firefox (TODO: allow html popup by checking the event target).
668----------------------------------------------------------------------------*/
669function RZtemplateclose(value)
670{
671	if (!RZ.revizepreview) return
672	var msg = 'Links disabled during preview of content changes'
673	alert(msg)
674	location.href = location.href	//cancels hyperlink
675	return false
676}
677/*---------------------------------------------------------------------------
678(Internal Function) Look for specific hash (e.g. debug or trace) on current
679window, opener, referrer hash and associated cookie
680
681Internal: Diagnostic Support
682----------------------------------------------------------------------------*/
683function RZcheckHash(value)
684{
685	var key = false
686	if (!RZwinaccess(top))
687		return key;
688
689	//TODO: below has issues on some versions of chrome
690	//		(window.top.location.hash may be undefined)
691	if(window.top.location.hash.indexOf('#'+value) != -1
692	|| location.hash.indexOf('#'+value) != -1
693	|| RZ.parent.location.hash.indexOf('#'+value) != -1
694	|| RZgetCookieValue('RZ'+value) == 'ON' )
695	{
696		key = true
697	}
698	else if (RZwinaccess(RZ.parent.opener))
699	{
700		if( RZ.parent.opener.location.hash.indexOf('#'+value) != -1)
701			key = true
702		else if (typeof RZ.parent.opener.top != 'undefined'
703		&& RZ.parent.opener.top.location.hash.indexOf('#'+value) != -1)
704			key = true
705	}
706	else if (typeof document.referrer != 'undefined')
707	{
708		if (document.referrer.indexOf('#'+value) != -1) key = true
709	}
710	return key
711}
712/*---------------------------------------------------------------------------
713(Internal Function) Sets final variables based on page type
714Internal: Called after page loads and all initialzation is done.
715----------------------------------------------------------------------------*/
716function RZpageLoaded()
717{
718	window.focus()		//insure window gets focus() after loaded
719	if (RZ.pagetype == 'template')
720	{
721		//----- Display trace information
722		var recordid;
723		if (typeof RZ.record != 'undefined')
724			recordid = RZ.record.id
725		else
726			recordid = RZ.editrecordid
727
728		RZ.string = 'RZ.webspace: ' + RZ.webspace + '\n'
729				  + "RZ.editrecordid: (" + recordid + ")\n"
730				  + "Clearing Return URLs ..."
731		RZtrace( "Published Page Now Loaded", RZ.string )
732
733		//----- Update cookies
734		if (RZgetCookieValue('RZeditFormReturnUrl') != '')
735			RZsetCookieValue('RZeditFormReturnUrl','')
736
737		/*	deactivated when list allowed as popup
738			(better supports template as list page)
739		if (RZgetCookieValue('RZeditListReturnUrl') != '')
740			RZsetCookieValue('RZeditListReturnUrl','')
741		*/
742
743		if (location.hash == '#logout') return
744
745		//----- Save webSpace name in cookie unless logout call
746		RZsetCookieValue('RZwebspace',RZ.webspace + "#" + document.location)
747
748		if (RZlogin())
749		{
750			//----- Display page username and role in status bar
751			if (RZ.pagetype == 'template')
752				window.status = 'Logged in User is ' + RZ.username
753							  + ' (roles: ' + RZ.roles + ')'
754
755			//----- Call onload handler if permission warning enabled and logged in
756			if (RZcheckoptions(RZ.permissions_options,"warnings"))
757				RZsetuphandler( 'onload', 'RZshowIcons()' )
758
759			//----- Display critical and warnings for templates
760			if (RZ.alert != '') RZalert( RZ.alert );
761			RZwarning();
762		}
763
764		//----- Create login button for page permission testing
765		if (RZcheckoptions(RZ.permissions_options,"warnings")) document.write(
766			'<div id="RevizeLogin" style="visibility:visible; position:absolute; z-index:1; top:30">',
767			/* TODO: autoclick
768			'  <a href="javascript:RZautoClick();"><img border="0"',
769			'   src="/revize/images/warning-auto.gif" alt="Auto Click"></a>',
770			'  <br>',
771			*/
772			'  <a href="/revize/security/"><img border="0"',
773			'   src="/revize/images/RevizeRzSmall.gif" alt="Revize Login"></a>',
774			'</div>',
775			'')
776	}
777
778	//----- TODO: document why RZ.loaded not set true for edit forms
779	//		(perhaps we did not want to use onload handler)
780	if (RZ.pagetype != 'editform')
781	{
782		RZsetuphandler( 'onload', 'RZprocessHash()' )
783	}
784}
785/*---------------------------------------------------------------------------
786(Internal Function) position page on hash set by save
787Internal: Runs after page is loaded
788----------------------------------------------------------------------------*/
789function RZprocessHash()
790{
791	if(location.hash.indexOf('_rz') != -1
792	&& location.hash.indexOf('#trace') == -1
793	&& location.hash.indexOf('#debug') == -1)
794		location.hash = location.hash.substring(1);
795	RZ.loaded=true;
796}
797/*---------------------------------------------------------------------------
798(Internal Function) Displays stack trace(s) from rz.setup()
799Internal: NOT YET USED
800----------------------------------------------------------------------------*/
801function RZprintStackTrace(msg)
802{
803	RZ.tracewin = RZpopupUrl('RevizeTrace');
804	var msg = '<pre>' + msg + '</pre>'
805	RZ.tracewin.document.write(msg);
806}
807/*---------------------------------------------------------------------------
808(Internal Function) Repair bad page permission link
809Internal: Recovery Support
810Future: under development (currently placeholder with no functionality)
811----------------------------------------------------------------------------*/
812function RZbadlink(module,recordid,url)
813{
814}
815/*---------------------------------------------------------------------------
816(Internal Function) Displays page permissions warning on templates. NOT COMPLETED
817Called as onload handler only
818
819Internal: Called by onload handler permission warning are enabled and user is
820currently logged in.
821
822Future: under development (may be available in a later release)
823
824Parameters:
825  	None - no input parameters
826
827Returns:
828  	There is currently no value returned
829----------------------------------------------------------------------------*/
830function RZautoClick()
831{
832	var msg = 'Automatically click on every bad link to define parents.     '
833	if (!confirm(msg)) return
834
835return
836	RZ.msg = ''
837	var tag = 'A'
838	if (tag == '')
839		RZnodeProperties( 0, dw.getDocumentDOM("document").documentElement )
840	else
841	{
842		var allTags = document.getElementsByTagName(tag);
843		for (var i=0; i<allTags.length; i++)
844		{
845			RZ.msg += tag.toLowerCase() + '[' + i + ']:\n'
846			if (allTags[i].hasChildNodes())
847				for (var j=0; j<allTags[i].childNodes.length; j++)
848					RZnodeProperties( 1, allTags[i].childNodes[j] )
849		}
850	}
851
852	RZ.msg = RZ.msg.replace( /\t/g, '     ' )
853	var pattern = /(.*\n){0,40}/g
854	var matchArray = RZ.msg.match(pattern)
855	alert('Written to ' + RZ.constant.tempDOM + '\n\n'
856	     +'Up to 40 lines below:' + '\n' + matchArray[0])
857
858}
859/*---------------------------------------------------------------------------------------------
860Parse a DOM node
861Future: under development (may be available in a later release)
862---------------------------------------------------------------------------------------------*/
863function RZnodeProperties( level, childObj )
864{
865	var i,text
866	var tab = ''
867	var Node = new Object()
868	Node.TEXT_NODE = 2
869	Node.ELEMENT_NODE = 1
870	Node.COMMENT_NODE = 1
871
872
873	for (i=0; i<level; i++) tab += '\t'
874
875	if ( childObj.nodeType == Node.TEXT_NODE)
876	{
877		RZ.msg += tab + 'TEXT NODE:\n'
878		text = childObj.data
879		text = text.replace(/\r/g,'\\r')
880		text = text.replace(/\n/g,'\\n')
881		RZ.msg += tab + '\t' + text + '\n'
882	}
883	else if (childObj.nodeType == Node.ELEMENT_NODE)
884	{
885		var name = ''
886		if ( typeof childObj.getAttribute('name') != 'undefined')
887			name = ' ' + childObj.getAttribute('name')
888		RZ.msg += tab + '<' + childObj.tagName + '>'+name+':\n'
889	}
890	else if (childObj.nodeType == Node.COMMENT_NODE)
891	{
892		RZ.msg += tab + 'COMMENT NODE:\n'
893		text = childObj.data
894		text = text.replace(/\n/g, '\n\t' + tab )
895		RZ.msg += tab + '\t' + text + '\n'
896	}
897	else
898	{
899		RZ.msg += tab + 'UKNOWN nodeType=' + childObj.nodeType + ':\n'
900		RZ.msg += tab + 'Properties:\n'
901		for (i in childObj)
902			RZ.msg += tab + '-->' + i + '<--:' + childObj[i]
903	}
904
905	//----- Chase child nodes
906	if (childObj.hasChildNodes())
907		for (i=0; i<childObj.childNodes.length; i++)
908			RZnodeProperties( level+1, childObj.childNodes[i] )
909}
910/*---------------------------------------------------------------------------
911(Internal Function) Displays page permissions warning on templates.
912Internal: Called by onload handler if warning are active and a user logged in
913----------------------------------------------------------------------------*/
914function RZshowIcons()
915{
916	//----- Show top left icon
917	var icon = document.getElementById('RevizePageMessage')
918	if (icon != null)
919		icon.style.visibility = "visible";
920
921	//----- Show frown icon if button must specify a template
922	for (var i=0; i<RZ.icons.length; i++)
923	{
924		var module = RZ.icons[i]
925		if(typeof RZ.linktemplates[module] == 'undefined'
926		|| RZ.linktemplates[module] == '')
927		{
928			var icon = document.getElementById('RevizeButtonWarning' + i)
929			if (icon != null)
930				icon.style.visibility = "visible";
931		}
932	}
933}
934
935/*---------------------------------------------------------------------------
936Get File Info for specifiec URL or file.
937
938Description:
939	Parses either a url or file and breaks apart into individual fully
940	qualified components.  By default the input pathname is assumed to be a
941	file if the	syntax is ambigious.  To intepret first component as domain
942	as browsers do on the address line specify domain as an option.
943
944	If port 80 is specified on input, it is omitted like IE location functions
945	TODO: have not verified if Netscape location omits port 80
946
947Parameters:
948	pathname-		fully or partially qualified url or path/filename
949	options-		=domain treat everything up to first / as domain
950					(if protocol not specified e.g. http://)
951
952Return Value List:
953	page.domain     = 'http://localhost:8080'		//no trailing slash
954	page.pathname   = '/revize/demositeIII'	//with leading slash but not trailing
955	page.filename   = 'contacts'
956	page.extension  = 'html'
957	page.query      = '?webSpace=demositeII&recordid=1'	//contains leading ?
958	page.hash       = 'trace'						//leading # omitted
959	page.home       = 'http://localhost:8080//revize/demositeIII/index.html'
960
961Notes:
962	Regression test at .../revize/util/snippet_helper_getfileinfo_test
963
964	TODO: some scenarios noted as in above test do not currently work properly.
965	Many scenarios of domains ARE ONLY intrepreted correctly if domain option
966	is specified and the input pathname ends with a slash when no filename.
967	(remember page.href however is never returned with ending slash by design)
968	See: .../revize/util/snippet_helper_getfileinfo_test for details.
969----------------------------------------------------------------------------*/
970/* Same as RZgetfileinfo (retained for backward compatibility) */
971function RZgetFileInfo(pathname, options)
972{return RZgetfileinfo(pathname, options)}
973function RZgetfileinfo(pathname, options)
974{
975	var pos,idx,results
976	var href=''
977	var domain=''
978	var filename=''
979	var sep=''
980	var extension=''
981	var query=''
982	var hash=''
983	var home=''
984	if (typeof options == 'undefined')
985		options = '';
986	else
987		options += ','
988	if (!pathname) pathname = '';
989	if (pathname == '#') pathname = location.href
990	if (pathname != '')
991	{
992		pathname = pathname.split('\\').join('/');
993
994		//----- Determine domain
995		domain = ''
996		pos = pathname.indexOf(':')				//check for first colon :
997
998		//----- If domain option & protocol is missing, prepend to pathname
999		if (options.indexOf('domain,') != -1
1000		&& RZsubstring(pathname,pos+1,pos+3) != '//')
1001		{
1002			if (location.protocol != '')
1003				pathname = location.protocol + '//' + pathname
1004			else
1005				pathname = 'http://' + pathname
1006			pos = pathname.indexOf(':')			//reset colon pos
1007		}
1008
1009		//----- If protocol present, e.g. //http:// https:// ftp://
1010		if (RZsubstring(pathname,pos+1,pos+3) == '//')
1011		{
1012			pos += 3
1013			if (pathname.indexOf('/',pos) != -1)	//if first slash following //:
1014				pos = pathname.indexOf('/',pos)		//domain goes up to slash
1015			else if (RZsubstring(pathname,0,4).toLowerCase() != 'file')
1016				pos = pathname.length				//assume domain is all of pathname
1017		}
1018		else if (pos == -1)		//not file type (e.g. C:) so use current page domain
1019		{
1020			if (options.indexOf('domain,') != -1
1021			|| RZsubstring(pathname,0,4).toLowerCase() == 'www.')
1022			{
1023				pos = pathname.indexOf('/')
1024				if (pos >= 0)
1025				{
1026					domain = pathname.substring(0,pos)
1027					pathname = pathname.substring(pos+1)
1028				}else
1029				{
1030					domain = pathname
1031					pathname = ''
1032				}
1033			}
1034			else
1035			{
1036				domain = document.location.host			//blank if file
1037				if (document.location.protocol != '')	//if not file
1038				{
1039					domain = document.location.protocol + '//' + domain
1040					pos = domain.length
1041					if (RZsubstring(pathname,0,1) != '/')
1042						pathname = '/' + pathname
1043					pathname = domain + pathname
1044				}
1045			}
1046		}
1047
1048		//-----  if : found, file format of C: (split into domain and pathname)
1049		if (pos != -1)
1050		{
1051			if (pathname.substring(pos,pos+1) == ':')
1052				domain = pathname.substring(0,pos+1)
1053			else
1054				domain = pathname.substring(0,pos)
1055
1056			pathname = pathname.substring(pos)
1057			if (pathname.substring(0,1) == ':')
1058				pathname = pathname.substring(1)
1059		}
1060
1061		//----- Strip port 80 if present in domain
1062		pos = (domain+'/').indexOf(':80/')
1063		if (pos != -1)
1064			domain = domain.substring(0,pos);
1065
1066		//----- Parse pathname and filename
1067		//		DCO 03-09-2012 previously simple lastIndexOf('/') incorecctly
1068		//		               found slash past hash "#" or query "?"
1069		//		e.g. /calendar_app/index.html#Master,03/09/2012
1070		//			 (both results[0] & results[1] have pathname
1071		results = pathname.match(/^([^#?]*\/)[^#?]*?/m);
1072
1073		if (results)	//found slash PRECEEDING query "?" or hash "#"
1074
1075		{	//results.lastIndex NA on IE9
1076			pos = results.index + results[1].length;
1077			filename = pathname.substr(pos);
1078			pathname = pathname.substr(0,pos-1);
1079			if (pathname.substr(0,1) != '/')
1080				pathname = '/' + pathname;
1081		}
1082		else			//safe to use lastIndexOf() when no query or hash
1083		{
1084			filename = pathname;
1085			pathname = '';
1086		}
1087
1088		//------ Parse search (query)
1089		pos = filename.indexOf('?')
1090		if (pos == -1)
1091			query = ''
1092		else
1093		{
1094			query = filename.substring(pos)
1095			filename = filename.substring(0,pos)
1096		}
1097
1098		//------ Parse hash
1099		pos = filename.indexOf('#')
1100		if (pos != -1)
1101		{
1102			hash = filename.substring(pos+1)
1103			filename = filename.substring(0,pos)
1104		}
1105
1106		//------ Parse filename extension
1107		pos = filename.lastIndexOf('.')
1108		if (pos == -1)
1109			extension = ''
1110		else
1111		{
1112			extension = filename.substring(pos+1)
1113			filename = filename.substring(0,pos)
1114		}
1115		if (filename == '')		// use index.html when filename is blank
1116		{
1117			filename = ''
1118			extension = ''
1119		}
1120
1121		//----- home page (questionable value)
1122		home = domain + pathname
1123		if (RZright(home,1) != '/' && pathname != '') home += '/'
1124	}
1125
1126	//----- Return all the components
1127	var page = new Object();
1128	page.domain = domain;
1129	page.pathname = pathname;
1130	page.filename = filename;
1131	page.extension = extension;
1132	page.extention = extension;
1133
1134	page.filenameFull = page.filename;
1135	if (page.extension)
1136		page.filenameFull += '.' + extension;
1137	page.pathfilename = page.filenameFull;
1138	if (page.pathname)
1139		page.pathfilename = page.pathname + '/' + page.pathfilename;
1140
1141	page.query = query;
1142	page.search = query;
1143	page.hash = hash;
1144	page.home = home;
1145
1146	page.sep = ((extension != '') ? '.' : '')
1147	page.href = domain
1148	page.href += pathname
1149	page.href += ((filename != ''&& RZright(page.href,1) != '/') ? '/' : '')
1150	page.href += filename + page.sep + extension + query
1151	if (hash != '') page.href += '#' + hash
1152
1153	return page
1154}
1155/*---------------------------------------------------------------------------
1156----------------------------------------------------------------------------*/
1157function RZbuildurl(fileInfo)
1158{
1159	var location = fileInfo.domain + fileInfo.pathname
1160	if (RZright(location,1) != '/') location += '/'
1161	location += fileInfo.filename + fileInfo.sep + fileInfo.extension
1162	          + fileInfo.query
1163	if (fileInfo.hash != '') location += '#' + fileInfo.hash
1164	return location
1165}
1166/*---------------------------------------------------------------------------
1167Return Browser Version - report page design flaw if unknown
1168
1169Parameters:
1170	None- (no input parameters)
1171
1172Returns: Browser version
1173----------------------------------------------------------------------------*/
1174function RZbrowserversion()
1175{
1176	var version = 0
1177	if (RZ.isnavigator)
1178	{
1179		version = parseFloat( navigator.appVersion )
1180	}else
1181	{
1182		var pos = navigator.appVersion.indexOf("MSIE")
1183		version = parseFloat(navigator.appVersion.substring(pos+4))
1184	}
1185	if (isNaN(version) || version == 0)
1186		RZalert( "Unable to determine Browser version\n"
1187			 + "navigator.appVersion: " + navigator.appVersion )
1188
1189	return version
1190}
1191/*---------------------------------------------------------------------------
1192Resize window; if width or hieght not specified use available size
1193
1194Parameters:
1195	width -		specifies requested window width (text or number)
1196	hieght -	specifies requested window hieght (text or number)
1197	justify -	Optional string; right or left to justify window respectively
1198	win -		Optional window object to specify window if not window/frame
1199				that includes the snippet_helper.js library file.
1200----------------------------------------------------------------------------*/
1201function RZresize(width,height,justify,win)
1202{
1203	 return;
1204	 if (!width) width = screen.availWidth;
1205	 if (!height) height = screen.availHeight;
1206	 if (!justify) justify = 'center'
1207	 if (!win) win = window
1208	 if (win.dialogArguments) return; //DCO 02-04-2014
1209
1210	 //DCO 08-03-2009
1211	 //if (RZ.isnavigator) height -= 125  //TODO: for linkmanager ???
1212
1213	 var x = (screen.availWidth - width) / 2
1214	 var y = (screen.availHeight - height) / 2
1215	 if (justify == 'right')
1216	  x = screen.availWidth - width - 10
1217	 else if (justify == 'left')
1218	  x = 0
1219	 if (x < 0) x = 0
1220	 if (y < 0) y = 0
1221
1222	 win.resizeTo(width,height);
1223     win.moveTo( x,y )
1224
1225}
1226/*-----------------------------------------------------------------------------------
1227Return window and browser screen sizes and offset to locate block of width & height.
1228
1229NOTE: browser width & height returned are limited to screen width/height
1230
1231---------
1232Arguments:
1233---------
1234width		(optional) width of window or layer to open; default is full size
1235height		(optional) height of window or layer to open; default is full size
1236options		list of option=value or option separated by commas from list below:
1237				norounding	returned width/height & offsets rounded to nearest integer
1238				browser		returned width/height & offsets relative to browser window
1239							instead of screen
1240-----------------------------------------------------------------------------------*/
1241function RZscreensizes(width,height,options)
1242{
1243	if (typeof width == 'undefined') width = 0;
1244	if (typeof height == 'undefined') height = 0;
1245
1246	var base, offsetX, offsetY;
1247	var sizes = {
1248		width:width, height:height,
1249		screenWidth:0, screenHeight:0,
1250		browserWidth:0, browserHeight:0,
1251		offsetWidth:0, offsetHeight:0
1252	};
1253
1254	//----- Is offset limited and relative to browser or screen screen size
1255	var base = 'screen';
1256	if (RZcheckoptions(options,'browser'))
1257		base = 'browser';
1258
1259	//----- Window sizes...
1260	sizes.screenWidth=screen.width;
1261	sizes.screenHeight = screen.height;
1262	offsetY = 0;
1263	offsetX = 0;
1264
1265	//----- Browser sizes...
1266	if(!window.innerWidth)	//IE...
1267	{
1268		if (!(document.documentElement.clientWidth == 0))
1269		{					//...strict mode
1270			sizes.browserWidth = document.documentElement.clientWidth;
1271			sizes.browserHeight = document.documentElement.clientHeight;
1272			if (base == 'browser')
1273			{
1274				offsetY = document.documentElement.scrollTop;
1275				offsetX = document.documentElement.scrollLeft;
1276			}
1277		}
1278		else
1279		{					//...quirks mode
1280			sizes.browserWidth = document.body.clientWidth;
1281			sizes.browserHeight = document.body.clientHeight;
1282			if (base == 'browser')
1283			{
1284				offsetY = document.body.scrollTop;
1285				offsetX = document.body.scrollLeft;
1286			}
1287		}
1288	}
1289	else					//WC3...
1290	{
1291		sizes.browserWidth = window.innerWidth;
1292		sizes.browserHeight = window.innerHeight;
1293		if (base == 'browser')
1294		{
1295			offsetX = window.pageXOffset;
1296			offsetY = window.pageYOffset;
1297		}
1298	}
1299
1300	//----- If browser sizes exceed screen sizes, adjust
1301	sizes.browserWidth = Math.min(sizes.browserWidth,sizes.screenWidth);
1302	sizes.browserHeight = Math.min(sizes.browserHeight,sizes.screenHeight);
1303
1304	//----- Adjust height & width to center of browser or screen (depending on base value)
1305	//		If either width or height not specified, set to browser or screen width/height
1306	//		negative width or height uses full size less negative value specified
1307	if (width == 0)
1308		sizes.width = sizes[base+'Width'];
1309	else if (width < 0)
1310		sizes.width = sizes[base+'Width'] + width;
1311
1312	if (height == 0)
1313		sizes.height = sizes[base+'Height'];
1314	else if (height < 0)
1315		sizes.height = sizes[base+'Height'] + height;
1316
1317	//----- Limit width and height to browser or screen width and height
1318	sizes.width = Math.min(sizes.width,sizes[base+'Width']);
1319	sizes.height = Math.min(sizes.height,sizes[base+'Height']);
1320
1321	offsetX = (sizes[base+'Width'] - sizes.width) / 2 + offsetX;
1322	offsetY = (sizes[base+'Height'] - sizes.height) / 2 + offsetY;
1323
1324	//----- round up unless no rounding specified
1325	if (!RZcheckoptions(options,'norounding'))
1326	{
1327		offsetX = parseInt(offsetX + .5);
1328		offsetY = parseInt(offsetY + .5);
1329	}
1330
1331	sizes.offsetWidth = offsetX;
1332	sizes.offsetHeight  = offsetY;
1333
1334	//----- Return object with all sizes
1335	return sizes;
1336}
1337/*---------------------------------------------------------------------------
1338Return true if layer exists and is currently visible.
1339
1340Parameters:
1341----------
1342layerName-	text representing layer name
1343
1344doc-		Optional argument specifing document object
1345			(appropriate when caller in in another frame or window)
1346----------------------------------------------------------------------------*/
1347function RZisvisible(layerName,doc)
1348{
1349	if (typeof doc == 'undefined') doc = document
1350    if (typeof doc == 'undefined') return false;    //firefox cludge
1351	if (typeof(layerName) == 'object')
1352		layerName = layerName.id;
1353	var status = false;
1354
1355	if (doc.layers && doc.layers[layerName])		//ns
1356	{
1357		if(typeof doc.layers[layerName] != 'undefined'
1358		&& doc.layers[layerName].visibility == 'visible') status = true
1359	}
1360	else if (RZ.css)			//ie or firefox (see notes in RZshowlayer)
1361	{
1362		var el = doc.getElementById(layerName)
1363		if (!el && RZ.MSIE) el = doc.all[layerName];
1364		if (el != null)
1365		{
1366			var layerStyle = el.style
1367			if (layerStyle.visibility != ''	&& layerStyle.visibility == 'visible')
1368				status = true
1369			if (layerStyle.display != '' && layerStyle.display != 'none')
1370				status = true
1371		}
1372	}
1373
1374	return status;
1375}
1376/*---------------------------------------------------------------------------
1377Does layer exist?
1378
1379Parameters:
1380----------
1381layerName-	text representing layer name
1382
1383trueFalse-	Not used
1384
1385doc-		Optional argument specifing document object
1386			(appropriate when caller in in another frame or window)
1387----------------------------------------------------------------------------*/
1388function RZhavelayer(layerName,trueFalse,doc)
1389{
1390	if (typeof doc == 'undefined') doc = document
1391	if (typeof(layerName) == 'object')
1392		layerName = layerName.id;
1393	if (doc.layers && doc.layers[layerName])		//ns
1394	{
1395		if(typeof doc.layers[layerName] == 'undefined') return false
1396	}
1397	else if (RZ.css)			//ie or firefox (see notes in RZshowlayer)
1398	{
1399        var el = document.getElementById(layerName)
1400        if (el == null) return false
1401		//if(typeof doc.all[layerName] == 'undefined') return false
1402	}
1403	return true
1404}
1405/*---------------------------------------------------------------------------
1406Show or hide a layer based on browser type.  If the layer visibility property
1407is valid (non-blank), it is used to show or hide layer however it does not
1408work for Firefox.  If the visibility property is blank and the style.display
1409property if not blank, it is used to hide or show layer.
1410
1411This feature was initially added as a simple backward compatible method to use
1412this function in Firefox in legacy utility functions such as the link manager
1413by simply changing the condictionally displayed code to define a display
1414property and leave the visiblity property blank.
1415
1416Parameters:
1417----------
1418layerName-	text representing layer name
1419
1420trueFalse- 	optional argument:
1421			if not passed, toggle layer (i.e. hide if showing or show if hidden)
1422			otherwise: if true show layer, if false hide layer
1423
1424doc-		Optional argument specifing document object
1425			(appropriate when caller in in another frame or window)
1426----------------------------------------------------------------------------*/
1427function RZshowlayer(layerName,trueFalse,doc)
1428{
1429	var el, msg = '';
1430	if (typeof doc == 'undefined') doc = document
1431
1432	//----- Netscape 4 loses layers if page was resized so leave layer visible
1433	if (RZ.isnavigator
1434	&& RZ.isnavigatorLayers == true
1435	&& doc.layers.length == 0) return
1436
1437	if (typeof(layerName) == 'object')
1438		el = layerName;
1439
1440	//----- If invalie layerName of object, set status and return
1441	else if (typeof layerName != 'string')
1442	{
1443		RZalert('Invalid layer name must be text argument');
1444		return;
1445	}
1446 	//----- Get div/span/layer element
1447	else
1448	{
1449		el = doc.getElementById(layerName)
1450		if (!el && RZ.MSIE) el = doc.all[layerName];
1451	}
1452
1453	//----- If trueFalse not specified, toggle setting
1454	if (typeof trueFalse == 'undefined')
1455	{
1456		if ( RZisvisible(layerName,doc) == true)
1457			trueFalse = false
1458		else
1459			trueFalse = true
1460	}
1461
1462	//----- See if layers are found on Netscape
1463	var msg = "Can't Hide Layer because ...\n"
1464	if (trueFalse == true) msg ="Can't Show Layer because ...\n"
1465	if (doc.layers)									//ns
1466	{
1467		if(doc.layers.length == 0)
1468		{
1469			msg += 'No Netscape Layers Defined (may be caused by resizing the window)\n'
1470				 + 'Try refreshing the page and re-entering information'
1471			RZalert(msg)
1472			return
1473		}
1474		RZ.isnavigatorLayers = trueFalse;	//indicate layer existed at one time
1475		if(typeof doc.layers[layerName] == 'undefined')
1476		{
1477			msg += 'Netscape Layer Not Defined: ' + layerName
1478
1479			// list defined layers
1480			msg += '\n\nDOM document.layers properties'
1481			for (i in doc.layers)
1482				msg += '\n      ' + i + '=' + doc.layers[i]
1483			RZalert(msg)
1484			return
1485		}
1486	}
1487	else if (RZ.css)					//ie or firefox (see notes in description)
1488	{
1489		if (el == null)
1490		{
1491			msg += 'Layer Not Defined: ' + layerName
1492			RZalert(msg)
1493			return
1494		}
1495	}
1496
1497	//----- Show or hide layer
1498	if (trueFalse == true)	// show layer
1499	{
1500		if (doc.layers && doc.layers[layerName])			//ns
1501			doc.layers[layerName].visibility = 'visible';
1502
1503		else if (RZ.css)					//ie or firefox (see notes in description)
1504		{
1505			//var displayBlock = el.tagName.toUpperCase() == 'SPAN' ? 'inline' : 'block' ;
1506			var displayBlock = 'inline';	//most tags display=inline
1507			if (el.tagName.toLowerCase() == 'div')
1508				displayBlock = 'block';		//div display=block
1509			if (el.style.visibility != '')
1510			{
1511				el.style.visibility = 'visible';
1512				el.style.zIndex = 100;
1513			}
1514			else if (el.style.display != displayBlock)
1515				el.style.display = displayBlock;
1516		}
1517    }
1518    else 					// hide layer
1519    {
1520		if (doc.layers && doc.layers[layerName])			//ns
1521			doc.layers[layerName].visibility = 'hidden';
1522		else if (RZ.css)				//ie or firefox (see notes in description)
1523		{
1524			if (el.style.visibility != '')
1525				el.style.visibility = 'hidden';
1526			else if (el.style.display != 'none')
1527				el.style.display = 'none';
1528		}
1529	}
1530}
1531/*---------------------------------------------------------------------------
1532Set Cookie value
1533-----------
1534Parameters:
1535-----------
1536key			Key part of the Cookie key=value pair
1537value		Value part of key=value (may have optional qualifier appended)
1538qualifier	(Optional) string specifyin gualifier
1539			e.g. current page url or webspace domain
1540---------
1541Examples:
1542---------
1543	RZsetcookie('RZeditListReturnUrl',location.href);		//no qualifier
1544	RZsetcookie('RZlogin',RZ.webspace+"#"+RZ.page.domain);	//value has qualifier
1545	RZsetcookie('RZuser',RZ.username,RZ.page.domain)		//qualifier 3rd arg
1546----------------------------------------------------------------------------*/
1547function RZsetCookieValue( key, value, qualifier )
1548{ return RZsetcookie( key, value, qualifier ) }
1549function RZsetcookie( key, value, qualifier )
1550{
1551	if (!/^(builder|cms|webgen|development|migration|demo)[0-9]*\.revize\.com$/.test(location.host)) {
1552		return false;
1553	}
1554	if (!qualifier) qualifier = '';
1555	if (qualifier)
1556	{
1557		if (qualifier.substr(0,1) != '#')
1558			qualifier = '#' + qualifier;
1559		value += qualifier;
1560	}
1561
1562	var cookieSecure = window.location.protocol === 'https:' ? '; Secure' : '';
1563	value = encodeURIComponent(value);
1564	document.cookie = key + '=' + value
1565   	                + '; path=/; SameSite=Strict' + cookieSecure + '; Partitioned';
1566
1567	var text = key + "=" + value;
1568	RZtrace( 'Set Cookie', text )
1569	return text;
1570}
1571
1572/* Same as RZgetcookie (retained for backward compatibility) */
1573function RZgetCookieValue( key, qualifier )
1574{ return RZgetcookie( key, qualifier ) }
1575/*---------------------------------------------------------------------------
1576Get Cookie value
1577
1578Parameters:
1579----------
1580key-		Key part of the Cookie key=value pair
1581
1582qualifier-	Optional parameter that qualifies the cookie by requiring the
1583			value to end with qualifier string.  Either a blank value is
1584			returned the qualifier string is removed from the returned value.
1585			Examples qualifies are: server domain and/or page url
1586
1587			If qualifer is blank, accept any qualified value after stripping
1588			the cookie qualifier
1589----------------------------------------------------------------------------*/
1590function RZgetcookie( key, qualifier )
1591{
1592
1593	var msg = '';
1594	var value = '';
1595	if (!key)
1596		RZwarn('Key undefined');
1597
1598	else
1599	{
1600		var allcookies = document.cookie + ';'
1601		var pos = allcookies.toLowerCase().indexOf( key.toLowerCase()+';' );
1602		if (pos == -1)	// not empty string value
1603			pos = allcookies.toLowerCase().indexOf( key.toLowerCase()+'=' );
1604		if (pos == -1) 	// if no cookie defined, return blank
1605			value = ""
1606		else // when cookie defined, return value
1607		{
1608			var valStart = pos + key.length + 1;
1609			if (allcookies.substring(valStart-1,valStart) != "=" )
1610				value = ""
1611			else
1612			{
1613				var valEnd = allcookies.indexOf( ";", valStart );
1614				if (valEnd == -1 ) valEnd = allcookies.length - 1
1615				value = allcookies.substring( valStart, valEnd );  //keep value case sensitive
1616			}
1617		}
1618
1619		value = decodeURIComponent(value);
1620
1621		//----- Build trace message; check for qualifier and remove or set value to blank
1622		msg = key + "=" + value
1623		if (typeof qualifier != 'undefined')
1624		{
1625			msg += '\nQualifier: (' + qualifier + ')'
1626			pos = value.indexOf('#')
1627			if (pos <= 0)
1628				value = ''
1629			else if (qualifier != '' && value.substring(pos+1) != qualifier)
1630				value = ''
1631			else
1632				value = value.substring(0,pos)
1633			msg += '\nQualified Value: (' + value + ')'
1634		}
1635	}
1636
1637	RZtrace("Get Cookie",msg)
1638	return value
1639}
1640
1641async function RZremoveCookie( key )
1642{
1643	var cookies = await cookieStore.getAll(key);
1644	for (var cookie of cookies) {
1645		await cookieStore.delete(cookie.name);
1646	}
1647}
1648
1649async function RZrebuildRevizeCookies() {
1650	var cookies = await cookieStore.getAll();
1651	for (var cookie of cookies) {
1652		if (cookie.name.startsWith('RZ')) {
1653			var name = cookie.name;
1654			var value = RZgetcookie(cookie.name);
1655			await RZremoveCookie(cookie.name);
1656			RZsetcookie(name, value);
1657		}
1658	}
1659}
1660
1661/*----------------------------------------------------------------------------
1662Date subclass to supports dashes "-" in constructor for FF & Chrome:
1663	.e.g. new RZdate('12-21-2012')
1664
1665Plus additional properties and methods.
1666The builtin Date() object is not extended to avoid different behavior caused
1667by adding prototypes directly.
1668
1669TODO:
1670	date.formatted.revizeDate --> date.get('revizeDate')
1671----------------------------------------------------------------------------*/
1672function RZdate(year,month,day,hours,minutes,seconds,ms)
1673{
1674	var date = null;
1675	switch (RZdate.arguments.length)
1676	{
1677		case 0:
1678			date = new Date();
1679			break;
1680		case 1:		//milliseconds since midnight 1-1-70 -OR- date string
1681			if (typeof year == 'number')
1682				date = new Date(year)
1683			else
1684			{		//date object or string; replace dashs in date
1685				var dateStr = (year + '')
1686				dateStr = dateStr.replace(/Noon/i,'12:00pm');
1687				dateStr = dateStr.replace(/Midnight/i,'12:00am');
1688				dateStr = dateStr.replace(/(\d)\-(\d)/g,'$1/$2');
1689
1690				dateStr = dateStr.replace(/(\d{1,2}\/\d{1,2}\/)(\d{2})(?!\d)/, '$120$2');
1691				dateStr = dateStr.replace(/(\d)(am|pm)/, '$1 $2');
1692
1693				if (dateStr)
1694					date = new Date(dateStr);
1695				else
1696					date = new Date();
1697			}
1698			break;
1699		case 2:
1700			date = new Date(year,month);
1701			break;
1702		case 3:
1703			date = new Date(year,month,day);
1704			break;
1705		case 4:
1706			date = new Date(year,month,day,hours);
1707			break;
1708		case 5:
1709			date = new Date(year,month,day,hours,minutes);
1710			break;
1711		case 6:
1712			date = new Date(year,month,day,hours,minutes,seconds);
1713			break;
1714		default:
1715			date = new Date(year,month,day,hours,minutes,seconds,ms);
1716			break;
1717	}
1718	//----- If invalid date, return NaN
1719	if (isNaN(date)) return null;
1720
1721	date.isRZdate = true;
1722	date.string = date.toString();	//only used show value in debugger
1723	//date.toString = function() ... may work better
1724
1725	//----- Add additional properties and methods.
1726	//		calendar_app issues
1727	//		1. cloning does not get these properties and methods
1728	//		2. adding reference to homeframe freezes IE7
1729	//		   must explictly reference as homeframe.RZdate(...)
1730	//		3. valid date return true for isNaN beside invalid when
1731	//		   not called from homeframe
1732	for (var prop in RZdate.prototype)
1733		date[prop] = RZdate.prototype[prop];
1734
1735	if (date.getFormatted)			//TODO: change to getFormat()
1736		date.getFormatted();		//set formatted data for constructor date
1737	return date;
1738}
1739/*----------------------------------------------------------*/
1740/*BOOKMARK RZdate static properties (instance not required)*/
1741/*--------------------------------------------------------*/
1742RZdate.baseDate = '01/01/1970';
1743RZdate.monthNames = ["January", "February", "March", "April",
1744				     "May", "June", "July", "August",
1745					 "September", "October", "November", "December"];
1746RZdate.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday",
1747				   "Thursday", "Friday", "Saturday"];
1748
1749RZdate.getMonth = function(monthName)
1750{
1751	for (var i=0; i<RZdate.monthNames; i++)
1752		if (RZdate.monthNames[i] == monthName) return i;
1753	return -1;
1754}
1755
1756/*-------------------------------------------------------------*/
1757/*BOOKMARK RZdate instance properties (backward compatibility)*/
1758/*-----------------------------------------------------------*/
1759RZdate.prototype.monthNames = ["January", "February", "March", "April",
1760							   "May", "June", "July", "August",
1761							   "September", "October", "November", "December"];
1762
1763RZdate.prototype.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday",
1764							  "Thursday", "Friday", "Saturday"];
1765
1766/*------------------------*/
1767/*BOOKMARK RZdate methods*/
1768/*----------------------*/
1769RZdate.prototype.get = function(key)		//return format property
1770{											//TODO: extend to get any property
1771	if (typeof this.formatted[key] == 'undefined')
1772		return key;
1773
1774	this.getFormatted();
1775	return this.formatted[key];
1776}
1777RZdate.prototype.toString = function()		//return string for date
1778{
1779	return new Date(this.getTime()) + '';
1780}
1781RZdate.prototype.getMonthName = function()	//return full month name
1782{
1783	return this.monthNames[this.getMonth()];
1784}
1785RZdate.prototype.getDayName = function()	//return full day name
1786{
1787	return this.dayNames[this.getDay()];
1788}
1789RZdate.prototype.getDaysInMonth = function()
1790{
1791	//                  1  2  3  4  5  6  7  8  9 10 11 12
1792	var daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
1793	var month = this.getMonth();
1794	var days = daysInMonth[month];
1795	if (month==1 && isLeapYear(this.getFullYear()))
1796		days=29;
1797	return (days);
1798
1799	function isLeapYear(Year)
1800	{
1801		if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0))
1802			return true;
1803		else
1804			return false;
1805	}
1806	/* alt from: http://msdn.microsoft.com/en-us/library/aa239571(v=vs.60).aspx
1807	// may not work in non-IE browsers
1808	eomDate = new Date();
1809	eomDate.setMonth(eomDate.getMonth() + 1 );
1810	eomDate.setDate(1);
1811	eomDate.setDate( eomDate.getDate() - 1);
1812	alert("Last day of this month = " + eomDate);
1813	*/
1814}
1815/*----------------------------------------------------------------------------
1816Add/substract number of months to current date.
1817return number of days added or subtracted
1818----------------------------------------------------------------------------*/
1819RZdate.prototype.addMonth = function(number)
1820{	//backward compatibility
1821	return this.addMonths(number)
1822}
1823RZdate.prototype.addMonths = function(number)
1824{
1825	if (typeof number == 'undefined') number = 1;
1826	number = parseInt(number);
1827
1828	var time = this.getTime();
1829	var year = this.getFullYear() + parseInt(number / 12);
1830	var month = (this.getMonth() + number) % 12;
1831	if (number > 0 && month < this.getMonth())
1832		year++;
1833	else if (number < 0 & month > this.getMonth())
1834		year--;
1835	var day = this.getDate();
1836
1837	// advance to next month using day=1
1838	this.setDate(1);
1839	this.setYear(year);
1840	this.setMonth(month);
1841
1842	// adjust date using current day or last day of month
1843	day = Math.min(day,this.getDaysInMonth());
1844	this.setDate(day);
1845	this.getFormatted();
1846
1847	time = this.getTime() - time;
1848	return time / 24 / 60 / 60 / 1000; 	//number of days added
1849}
1850/*----------------------------------------------------------------------------
1851Add/substract number of weeks to current date.
1852return number of minutes added or subtracted
1853----------------------------------------------------------------------------*/
1854RZdate.prototype.addWeeks = function(number)
1855{
1856	if (typeof number == 'undefined') number = 1;
1857	return this.addDays(number*7);
1858}
1859/*----------------------------------------------------------------------------
1860Add/substract number of days to current date.
1861return number of minutes added or subtracted
1862
1863Credit: http://www.w3schools.com/js/js_obj_date.asp
1864They say if adding days goes into another month or year, Date object adjusts.
1865----------------------------------------------------------------------------*/
1866RZdate.prototype.addDays = function(number)
1867{
1868	if (typeof number == 'undefined') number = 1;
1869	number = parseInt(number);
1870
1871	var time = this.getTime();
1872	this.setDate(this.getDate() + number);
1873	this.getFormatted();
1874
1875	time = this.getTime() - time;
1876	return (time / 60 / 1000); 	//number of minutes added
1877}
1878/*----------------------------------------------------------------------------
1879Return new RZdate() object containing only the date portion of this RZdate().
1880----------------------------------------------------------------------------*/
1881RZdate.prototype.getDatePart = function()
1882{
1883	return new RZdate(this.getFullYear(),this.getMonth(),this.getDate());
1884}
1885/*----------------------------------------------------------------------------
1886Return a new Date() object which is GMT representation of time component.
1887
1888Therefore getTime() returns milliseconds since midnight not since GMT 12:00am
1889(e.g. 0 for midnight; 1*60*60*1000 = 3600000 for 1am, etc).
1890
1891However getHours() returns GMT hours not the hour specified when this RZdate
1892object was created. Therefore RZdate() with no time component (i.e. midnight)
1893returns 19 (7pm) from getHours() when local is EST since EST is GMT-5 hours.
1894----------------------------------------------------------------------------*/
1895RZdate.prototype.getTimePart = function()
1896{
1897	var date = new Date(1970,0,1);
1898	date.setUTCHours(this.getHours(),
1899					 this.getMinutes(),
1900					 this.getSeconds(),
1901					 this.getMilliseconds());
1902	return date;
1903}
1904/*----------------------------------------------------------------------------
1905Returns the week number for this date.
1906
1907@param int dowOffset (optional) day week starts on (0 to 6) 1 is Monday
1908@return int ISO 8601 week number
1909
1910Credit: Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com
1911----------------------------------------------------------------------------*/
1912RZdate.prototype.getWeek = function(dowOffset)
1913{
1914	if (isNaN(this)) return null;
1915	dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero
1916
1917	var newYear = new Date(this.getFullYear(),0,1);
1918	var day = newYear.getDay() - dowOffset; //the day of week the year begins on
1919	day = (day >= 0 ? day : day + 7);
1920	var daynum = Math.floor((this.getTime() - newYear.getTime() -
1921				 (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
1922	var weeknum;
1923
1924	//if the year starts before the middle of a week
1925	if(day < 4)
1926	{
1927		weeknum = Math.floor((daynum+day-1)/7) + 1;
1928		if(weeknum > 52)
1929		{
1930			nYear = new Date(this.getFullYear() + 1,0,1);
1931			nday = nYear.getDay() - dowOffset;
1932			nday = nday >= 0 ? nday : nday + 7;
1933			/*if the next year starts before the middle of
1934			  the week, it is week #1 of that year*/
1935			weeknum = nday < 4 ? 1 : 53;
1936		}
1937	}
1938	else
1939		weeknum = Math.floor((daynum+day-1)/7);
1940	return weeknum;
1941}
1942/*---------------------------------------------------------------------------------------------
1943getNthDayInMonth(nth)
1944If nth specified, get date for nth occurance of this.date dayOfWeek -OR-
1945If no parameters, determine occurance of day of week in this.date month
1946
1947----------------------
1948Parameters (optional):
1949----------------------
1950theDayOfWeek 	specifies day of week; 0-6 or day name (at least 3 characters)
1951theNth			specifies desired occurance of theDayOfWeek
1952
1953--------
1954Returns:
1955--------
1956if parameters:	(RZdate) matching theNth occurance of theDayOfWeek in the month
1957otherwise		(String) 1st to 4th or 'last' if nth > 4th)
1958
1959--------
1960Examples:
1961---------
1962this.date=01-01-2012
1963				getNthDayInMonth() 			returns '1st' 01-01-201 is 1nd Sun in Jan 2012
1964				getNthDayInMonth(1) 		returns RZdate('01-01-2012')
1965				getNthDayInMonth(4) 		returns RZdate('01-22-2012')
1966				getNthDayInMonth('last') 	returns RZdate('01-29-2012')
1967this.date=01-09-2012
1968				getNthDayInMonth() 			returns '2nd'; 01-09-201 is 2nd Mon in Jan 2012
1969				getNthDayInMonth(1) 		returns RZdate('01-02-2012')
1970				getNthDayInMonth(4) 		returns RZdate('01-23-2012')
1971				getNthDayInMonth('last') 	returns RZdate('01-23-2012')
1972---------------------------------------------------------------------------------------------*/
1973RZdate.prototype.getNthDayInMonth = function (nth,dayOfWeek)
1974{
1975	var day;
1976	var theDate = RZdate(this);		//work object that can be modified
1977	var daysInMonth = theDate.getDaysInMonth();
1978	var nthCount = 0;
1979	var dateTime = 0;
1980
1981	//----- Compute nth day of current date in month
1982	if (arguments.length == 0)
1983	{
1984		dayOfWeek = theDate.getDay();
1985		for (day=1;day<=daysInMonth;day++)
1986		{
1987	        theDate.setDate(day);
1988			if (theDate.getDay() == dayOfWeek)
1989				nthCount++;
1990			if (theDate.getDatePart()+'' == this.getDatePart()+'')
1991				break;
1992		}
1993		if (nthCount > 4)
1994			nthCount = 'last';
1995		else
1996			nthCount = RZnth(nthCount);
1997		return nthCount;
1998	}
1999
2000	//----- Find date of nth dayOfWeek in month
2001	else
2002	{
2003		if (nth != 'last')
2004			nth = nth.substr(0,1);					//drop th; keep number
2005		for (day=1;day<=daysInMonth;day++)
2006		{
2007			theDate.setDate(day);
2008			if (theDate.getDay() == dayOfWeek)
2009			{
2010				if (nth == 'last')
2011					dateTime = theDate.getTime();
2012				else if (nth == ++nthCount)
2013					return RZdate(theDate);
2014			}
2015		}
2016		return RZdate(dateTime);
2017	}
2018}
2019/*---------------------------------------------------------------------------------------------
2020Return various formatted strings for RZdate() object and save for future reference.
2021---------------------------------------------------------------------------------------------*/
2022RZdate.prototype.getFormatted = function(isForceFormat)
2023{
2024	//----- Initialize return object; formats shown below replaced by subsequent code:
2025	var formatted = {									//all dates are blank if no date component...
2026		briefDate:		'mm-dd-yy',						//2 digits for month, day & year
2027		shortDate:		'mm-dd-yyyy',					//2 digits for month & day; 4 digit year
2028		longDate:	 	'wwww mmmm d, yyyy',			//full day name & month name e.g. Monday January
2029		smartDate:		'mmm d, yyyy',					//3 char day of week (use substr(4) to omit or replace)
2030		revizeDate:		'yyyy-mm-dd',					//4 digit year, 2 digit month and day
2031
2032		month:			'mm',							//2 digit month 01-12
2033		minutes:		'MM',							//2 digit minutes
2034		seconds:		'ss',							//2 digit seconds
2035		hours:			'h',							//1 or 2 digit hour; 12 hr clock
2036		hoursPadded:	'h',							//hours with &nbsp;&nbsp prefix if single digit
2037														//single digit prefixed with ' &nbsp'
2038														//Noon for 12:00:00; Midnight for 00:00:00
2039
2040		hours12:		'hh',							//2 digit hours 12 hour format
2041		hours24:		'hh',							//2 digit hours 24 hour clock
2042		ampm:			'am/pm',						//am or pm
2043
2044		day:			'dd',							//2 digit day 01-31
2045		daySuffix:		'ST',							//st, nd ... th
2046		dayLong:		'dST',							//1-2 digit: 1st, 2nd.. 30th
2047
2048		dayName:     	'WWWW',							//full name of day e.g. Monday
2049		monthName:   	'mmmm',							//full name of month e.g. January
2050
2051		briefTime: 		'[hh:MM am/pm]',				//2 digits for hr; seconds always dropped
2052														//blank if timePart() == 0
2053														//Noon for 12:00:00; 12 hr clock
2054		shortTime: 		'hh:MM[:ss]',					//always 2 digits for hour; seconds dropped if 0
2055														//24 hour clock (hours are 00-23)
2056		longTime: 		'hh:MM:ss am/pm',				//2 digits for hr; seconds always displayed
2057														//Noon for 12:00:00; Midnight for 00:00:00
2058		miniTime:		'hh:MM{:ss] am/pm',				//same as longTime except seconds dropped if 0
2059														//Noon for 12:00:00; Midnight for 00:00:00
2060		ampmTime: 		'hh:MM{:ss] am/pm',				//same as longTime except seconds dropped if 0
2061														//does not use noon or midnight
2062		smartTime:    	' h:MM:ss am/pm',				//blank if no timePart(); single digit padded
2063														//Noon for 12:00:00; seconds dropped if 0
2064														//12 hour clock
2065		timeZone:		'zzzz',							//as shown in new Date().toString()
2066														//varies by browser
2067
2068		briefDateTime: 	'mm-dd-yy [hh:mm am/pm]', 		//time dropped if timePart() = 0
2069														//Noon for 12:00; seconds always dropped
2070		shortDateTime:	'mm-dd-yyyy hh:MM:ss',		    //time always displayed with seconds
2071													    //24 hour clock
2072		longDateTime:  	'wwww mmm d, yyyy hh:MM:ss zzzz', //time dropped if timePart() = 0
2073														//Noon for 12:00:00
2074		smartDateTime: 	' d, yyyy [h:mm:ss am/pm zzzz]', //time dropped if timePart() = 0
2075														//Noon for 12:00:00
2076		revizeDateTime:	'yyyy-mm-dd hh:MM:ss',			//time dropped if timePart() = 0
2077														//hh is 24 hour time; seconds dropped if 0
2078		shortDateBriefTime: '',
2079		formattedTime:  0								//getTime() value used for all formatted
2080	}
2081	// if not forcing formatting and date has not changed since last call, no need to run again
2082	if (!isForceFormat && this.formatted && this.formatted.formattedTime == this.getTime())
2083		return;
2084
2085	formatted.formattedTime == this.getTime();			//remember value last used for formatted
2086
2087	var day = this.getDate();
2088	var month = this.getMonth();
2089	var year = this.getFullYear()
2090	var dayOfWeek = this.getDay();
2091
2092	// day suffix e.g. 1st, 2nd. 3rd, 4th ... 30th
2093	var suffix = ''
2094	if (day == 1 || day == 21 || day == 31)
2095		suffix = 'st';
2096	else if (day == 2 || day == 22)
2097		suffix = 'nd';
2098	else if (day == 3 || day == 23)
2099		suffix = 'rd';
2100	else
2101		suffix = 'th';
2102	formatted.daySuffix = suffix;
2103	formatted.dayLong = day + suffix;
2104
2105	// Full dayName & monthName (use substr(0,3) for short names
2106	formatted.dayName = this.getDayName();
2107	formatted.monthName = this.getMonthName();
2108
2109	//----- Extract time zone from Date.toString() function
2110	//		chrome: Sun Mar 18 2012 23:21:58 GMT-0400 (Eastern Daylight Time)
2111	//		FF:		Sun Mar 18 2012 23:42:25 GMT-0400 (Eastern Daylight Time)
2112	//		IE7-9:  Sun Mar 18 23:21:14 EDT 2012 (may show EST not EDT)
2113	var pattern = new RegExp( '(\\w*' + day + ')(.*)('+year+')' );	//for IE format...
2114	formatted.timeZone = this.toString();								//...move year before timezone
2115	formatted.timeZone = RZtrim(formatted.timeZone.replace(pattern,'$1, $3$2'));
2116	var results = formatted.timeZone.match(/.*\d (.*)$/mi);			//find time zone at end
2117	if (results)
2118		formatted.timeZone = results[1];
2119	else
2120		formatted.timeZone = '';
2121
2122	//----- Dates...
2123	formatted.month = RZright('0'+(month+1),2);
2124	formatted.day = RZright('0'+day,2);
2125
2126	if (month == 0 && day == 1 && year == 1970)		//no date component
2127	{
2128		formatted.briefDate = '';
2129		formatted.shortDate = '';
2130		formatted.longDate = '';
2131		formatted.smartDate = '';
2132		formatted.revizeDate = '';
2133	}
2134	else
2135	{
2136		formatted.briefDate = formatted.month + '-' + formatted.day + '-' + (year+'').substr(2);
2137		formatted.shortDate = formatted.month + '-' + formatted.day + '-' + year;
2138		formatted.longDate = formatted.dayName + ' ' + formatted.monthName + ' '  + day + ', ' + year;
2139		formatted.smartDate = formatted.dayName.substr(0,3) + ' '
2140						    + formatted.monthName.substr(0,3) + ' '  + day + ', ' + year;
2141		formatted.revizeDate = year + '-' +  formatted.month + '-' + formatted.day;
2142	}
2143
2144	//----- Time formats...
2145	var hours = this.getHours();
2146	var minutes = this.getMinutes();
2147	var seconds = this.getSeconds();
2148
2149	var ampm = (hours < 12) ? ' am' : ' pm';
2150	formatted.ampm = ampm.substr(1);
2151	formatted.minutes = RZright('0' + minutes,2);
2152	formatted.seconds = RZright('0' + seconds,2);
2153
2154	formatted.hours24 = RZright('0' + hours,2);
2155	formatted.hours = hours <= 12 ? hours : hours -= 12;
2156	formatted.hours12 = RZright('0'+ (hours==0?'12':hours), 2);
2157	formatted.hoursPadded = (hours.toString().length == 1 ? '&nbsp;&nbsp;' : '') + hours;
2158
2159	formatted.briefTime = ((hours + minutes) > 0)
2160					    ? formatted.hours12 + ':' + formatted.minutes + ampm : '';
2161	formatted.briefTime = formatted.briefTime.replace(/12:00 pm/i,'Noon');
2162
2163	formatted.shortTime = formatted.hours24 + ':' + formatted.minutes
2164					    + (seconds > 0 ? ':' + formatted.seconds : '');
2165
2166	formatted.longTime  = formatted.hours12 + ':' + formatted.minutes + ':' + formatted.seconds + ampm;
2167	formatted.longTime  = formatted.longTime.replace(/12:00:00 am/i,'Midnight');
2168	formatted.longTime  = formatted.longTime.replace(/12:00:00 pm/i,'Noon');
2169
2170	formatted.ampmTime  = formatted.hours12 + ':' + formatted.minutes + ampm;
2171
2172	formatted.miniTime  = formatted.ampmTime.replace(/12:00 am/i,'Midnight');
2173	formatted.miniTime  = formatted.miniTime.replace(/12:00 pm/i,'Noon');
2174
2175	formatted.smartTime = ((hours + minutes + seconds) > 0)
2176					    ? (formatted.hoursPadded + ':' + formatted.minutes + ':' + formatted.seconds) + ampm : '';
2177	formatted.smartTime = formatted.smartTime.replace(/:00 /i,' ');			//drop seconds if zero
2178	formatted.smartTime = formatted.smartTime.replace(/12:00 pm/i,'Noon');
2179
2180	//----- Combine Date and Time
2181	formatted.briefDateTime = formatted.briefDate   + (formatted.briefTime ? ' ' + formatted.briefTime : '');
2182	formatted.shortDateTime = formatted.shortDate   + ' ' + formatted.shortTime;
2183	formatted.longDateTime = formatted.longDate     + ' ' + formatted.longTime;
2184	formatted.smartDateTime = formatted.smartDate   + (formatted.smartTime ? ' ' + RZtrim(formatted.smartTime) : '');
2185	formatted.revizeDateTime = formatted.revizeDate + (formatted.briefTime ? ' ' + formatted.briefTime : '');
2186
2187	// trim leading space in case there was no date or time component
2188	formatted.briefDateTime = RZtrim(formatted.briefDateTime);
2189	formatted.shortDateTime = RZtrim(formatted.shortDateTime);
2190	formatted.longDateTime = RZtrim(formatted.longDateTime);
2191	formatted.smartDateTime = RZtrim(formatted.smartDateTime);
2192	formatted.revizeDateTime = RZtrim(formatted.revizeDateTime);
2193
2194	// Additional date & time combinations
2195	formatted.shortDateBriefTime = RZtrim(formatted.shortDate + ' ' + formatted.briefTime);
2196
2197	this.string = this.toString();	//update value shown in debugger
2198	this.formatted = formatted;
2199	return formatted;
2200}
2201/*---------------------------------------------------------------------------------------------
2202Called to parse a Date string
2203
2204The JavaSript Date.Parse method is used to accept all valid date formats.  Only problem
2205is two digits years (99) are intrepreted as 20th century dates (1999),  We counteract this
2206by adding 100 to the year unless the 4 digit date string exists in the input date string.
2207
2208Parameters:
2209	fieldValue-	String representing a date in any standard format
2210
2211Returns:
2212	returns 	null if invalid date;
2213				blank if no date specified;
2214				formatted date: yyyy-mm-dd hh:mm:ss
2215---------------------------------------------------------------------------------------------*/
2216function RZparseDate(fieldValue)
2217{
2218	RZparseDate.date = null;
2219
2220	if (fieldValue == '') return '';
2221	if (typeof(fieldValue) == 'undefined' || fieldValue == null) return null;
2222
2223	if (fieldValue.constructor == Date)
2224		fieldValue = fieldValue.toString();
2225	if (typeof fieldValue != 'string')
2226		fieldValue = fieldValue + '';
2227
2228	var fieldValueOriginal = fieldValue;
2229	fieldValue = fieldValue.split('-').join('/');	//Chrome, Firefox does not accept -
2230	var dateSeconds = Date.parse(fieldValue);
2231
2232	// may have incorrectly changed dash in: "Mon Jan 09 2012 12:28:37 GMT-0500 (EST)"
2233	// try above legacy conversion first for safe backward compatibility
2234	if(isNaN(dateSeconds) || fieldValue.search('GMT/') != -1)
2235	{							// <digit>-<digit> --> <digit>/<digit>
2236		fieldValue = fieldValueOriginal.replace(/(\d)-(\d)/g,'$1/$2');
2237		dateSeconds = Date.parse(fieldValue);
2238	}
2239
2240	// try time only with today's date
2241	if(isNaN(dateSeconds))
2242	{							// <digit>-<digit> --> <digit>/<digit>
2243		fieldValue = fieldValueOriginal.replace(/(\d)-(\d)/g,'$1/$2');
2244		if (fieldValue.indexOf('/') == -1 && fieldValue.indexOf(':') != -1)
2245		{
2246			fieldValue = RZparseDate(new Date()+'').substr(0,11) + fieldValue;
2247			fieldValue = RZparseDate(fieldValue);
2248			if (RZparseDate.date) dateSeconds = 0;	//valid date/time
2249			fieldValue = RZparseDate.date;
2250			RZparseDate.date = null;				//restore default
2251		}
2252	}
2253
2254	if( isNaN(dateSeconds) ) return null;			//bad date
2255
2256	//----- Treat dates of the form 01 as 2001
2257	var theDate = new Date(fieldValue)
2258	var year = theDate.getYear()					//js 1.1 compatible
2259	if (year < 1000) year += 1900					//broswer quirks
2260	if (year < 2000)
2261	{
2262		//see if the 4 digit year matches a string in the date field
2263		//if not then they we need to add 100 to the year
2264		if (fieldValue.indexOf(year.toString()) == -1)
2265			year += 100
2266	}
2267	var theMonth = theDate.getMonth() + 1
2268	var theDay = theDate.getDate()
2269	fieldValue = year.toString() + '-'
2270			   + RZright('0' + theMonth, 2)
2271			   + '-'
2272			   + RZright('0' + theDay, 2)
2273	var hour = theDate.getHours()
2274	var minutes = theDate.getMinutes()
2275	var seconds = theDate.getSeconds()
2276	fieldValue += ' ' + RZright('0' + hour.toString(), 2)
2277			   +  ':' + RZright('0' + minutes.toString(), 2)
2278			   +  ':' + RZright('0' + seconds.toString(), 2)
2279
2280	//----- Save Date object with correct year and time to milliseconds
2281	RZparseDate.date = new Date(year,theDate.getMonth(),theDay,
2282								hour,minutes,seconds,theDate.getMilliseconds());
2283
2284	//----- return date/time formatted for saveing int Revize db yyyy-mm-dd hh:mm:ss
2285	return fieldValue;
2286}
2287/*---------------------------------------------------------------------------------------------
2288Called to validate Date field
2289
2290Parameters:
2291	fieldname-	field object containing date to validate
2292
2293Returns: true if valid date; otherwise false
2294---------------------------------------------------------------------------------------------*/
2295function RZcheckdate( thisField )
2296{
2297	var fault = false
2298	var dateString = RZparseDate( thisField.value )
2299	if (dateString == null)
2300	{
2301		fault = true
2302		alert( "I'm sorry.  You have not entered a valid Date\n\n"
2303		 + "Examples: 12/12/2011 or 01-01-2012" )
2304		thisField.focus()
2305	}
2306	else
2307	{
2308		var theDate = new Date(dateString)
2309		if (theDate.getFullYear() < 1900)
2310		{
2311			if ( !confirm( 'You have entered a date prior to 1900\n\n'
2312			             + 'Is this correct?' ) )
2313			{
2314				fault = true
2315				thisField.focus()
2316			}
2317		}
2318	}
2319	return !fault		//cancels save if error
2320}
2321/*---------------------------------------------------------------------------
2322Setup or lookup module permits.
2323-----------------------------------------------------------------------------
2324Used by RZaction() and RZlogin to determine if buttons or html should be
2325displayed based on known permissions.
2326
2327If RZpermits() is called with no parameters, the following setup occures:
2328
2329	Get all module permissions determined at login from RZpermits cookie
2330	Permits (crud) are stored in the cookie as: global=crud,links=r
2331
2332	RZ.permits.modules will be loaded with individual module permissions
2333	Following example above:
2334		RZ.permits.modules.global='crud';
2335		RZ.permits.modules.links='r'
2336
2337Currently only the links module permissions are stored at after sucessful
2338login by the control_panel.jsp page (which is only used by the revizelogin
2339template).
2340
2341Parameters:
2342	module-			Name of module to check
2343	requirePermits-	One of more of the following characters: (crud)
2344					c = Create
2345					r = Read
2346					u = Update
2347					d = Delete
2348
2349TODO: Look up all module permissions, store in future control_panel window
2350
2351Returns:
2352
2353If RZpermits() is called with a module and permissions, the specified module
2354object is checked for the requested permissions returning true or false.
2355
2356If there is no object for the specified module, the permissions are not known
2357therefore the function returns true.
2358----------------------------------------------------------------------------*/
2359function RZpermits(module,requiredPermits)
2360{
2361	if (RZ.isauthenticationactive == false)
2362		return true
2363
2364	//----- If setup call...
2365	else if (typeof module == 'undefined')
2366	{
2367		//----- Module permissions
2368		RZ.message = 'none defined';
2369		var permits = RZgetCookieValue('RZpermits')
2370		if (permits != '')
2371		{
2372			// temporarily support both delimeter formats
2373			var permitsArray = permits.indexOf("|") > -1 ? permits.split('|') : permits.split(',')
2374
2375			RZ.message = '';
2376			for (var i=0; i<permitsArray.length; i++)
2377			{
2378				var module_permit = permitsArray[i].split(':')
2379				RZ.permits.modules[module_permit[0]] = module_permit[1]
2380				if (module_permit[1] == '') module_permit[1] = '-none-'
2381				RZmsgAdd(module_permit[0], ' ' + module_permit[1])
2382			}
2383		}
2384		RZtrace('Module Permissions',RZ.message)
2385
2386		//----- Page permissions
2387		RZ.message = ''
2388		RZmsgAdd( 'RZ.page_key       ', ' ' + RZ.page_key )
2389		if (RZ.pagetype == 'template')
2390		{
2391			RZmsgAdd( 'RZ.page_role      ', ' ' + RZ.page_roles )
2392			RZmsgAdd( 'RZ.page_users     ', ' ' + RZ.page_users )
2393		}
2394		else
2395		{
2396			RZmsgAdd( 'RZ.permissions_module  ', ' ' + RZ.permissions_module )
2397			RZmsgAdd( 'RZ.permissions_parent  ', ' ' + RZ.permissions_parent )
2398			RZmsgAdd( 'RZ.permissions_template', ' ' + RZ.permissions_template )
2399		}
2400		RZtrace('Page Permissions',RZ.message)
2401	}
2402
2403	//----- Check permissions...
2404	else
2405	{
2406		//----- Assume full permissions if module not listed in permits
2407		var modulePermits = 'crud';
2408		if (typeof RZ.permits.modules[module] != 'undefined')
2409			modulePermits = RZ.permits.modules[module]
2410		var requiredPermitsOptions = requiredPermits.split('|')
2411
2412		var status = true
2413		for (var j=0; j<requiredPermitsOptions.length; j++)
2414		{
2415			var optionStatus = true
2416			for (var i=0; i<requiredPermitsOptions[j].length; i++)
2417			{
2418				var ch = requiredPermitsOptions[j].substring(i,i+1).toLowerCase()
2419					if (modulePermits.indexOf(ch) == -1)
2420					{
2421						optionStatus = false
2422						break;
2423					}
2424			}
2425			status = optionStatus
2426			if (optionStatus == true) break;
2427		}
2428
2429		RZ.message = ''
2430		RZmsgAdd( 'module', module)
2431		RZmsgAdd( 'module permits', modulePermits)
2432		RZmsgAdd( 'permits required', requiredPermits)
2433		RZmsgAdd( 'status', status)
2434		RZtrace('Permissions Checked', RZ.message)
2435		return status;
2436	}
2437}
2438/*---------------------------------------------------------------------------------------------
2439Determine current page permissions
2440---------------------------------------------------------------------------------------------*/
2441function RZpagepermission()
2442{
2443	RZ.roles = ''
2444	RZ.username = RZgetCookieValue('RZusername',RZ.page.domain)
2445	RZ.hashed_username = RZgetCookieValue('RZhashedusername',RZ.page.domain)
2446	if (RZ.username != '') RZ.roles = RZgetCookieValue('RZroles')
2447
2448	RZ.pagepermission = false;
2449
2450	//----- Get login username and roles
2451	var roles = '|' + RZ.roles + '|'
2452	var username = '|' + RZ.username + '|'
2453	var hashed_username = '|' + RZ.hashed_username + '|'
2454
2455	RZ.browserdev = (roles.indexOf('@browserdev') != -1);
2456
2457	if (RZ.isauthenticationactive == false)
2458		RZ.pagepermission = true;		//all permits if authentication disabled
2459
2460	else if (username == '|')
2461		RZ.pagepermission = false;	//do nothing (not logged in)
2462
2463	else if( roles.indexOf( '|superuser|' ) != -1
2464	||  roles.indexOf( '|administrator|') != -1)
2465		RZ.pagepermission = true;
2466
2467	else if (RZ.page_roles == '' && RZ.page_users == '')
2468		RZ.pagepermission = true;		//no users or roles defined so everyone has access
2469
2470	else
2471	{
2472		if ( ('|'+RZ.page_users+'|').indexOf(username) != -1 || ('|'+RZ.page_users+'|').indexOf(hashed_username) != -1 )
2473			RZ.pagepermission = true;
2474		else
2475		{
2476			var rolesArray = roles.split('|')
2477			for (var i in rolesArray)
2478			{
2479				if ( rolesArray[i] == '' ) continue;
2480				if ( ('|'+RZ.page_roles+'|').indexOf('|'+rolesArray[i]+'|') != -1)
2481				{
2482					RZ.pagepermission = true;
2483					break;
2484				}
2485			}
2486		}
2487	}
2488	return
2489}
2490/*---------------------------------------------------------------------------
2491Calls either addEventListener or attachEvent if defined
2492RZ.browsertype set to "standard", "non-standard" or "unknown"
2493
2494Example calls:
2495	RZeventadd(window, 'focus', function()
2496	{
2497		//do something
2498	});
2499	RZeventadd(form, 'submit', "validate('red,x=2')");
2500
2501	// FF (chrome?), specified function object (e.g. validate) must be defined
2502	// before RZeventAdd called (not required for above calling variations)
2503
2504	// On IE this form passes object as first argument (click event?)
2505	RZeventadd(form, 'submit', validate);
2506----------------------------------------------------------------------------*/
2507function RZeventadd(target, eventType, functionRef, capture)
2508{
2509    if (!capture) capture = false;
2510	if (eventType.substr(0,2) == 'on') eventType = eventType.substr(2);
2511	if (typeof target.addEventListener != "undefined")
2512    {
2513		// e.g. document.addEventListener("error", function, false);
2514        target.addEventListener(eventType, functionRef, capture);
2515        RZ.browsertype = "standards";
2516
2517    }
2518	else if (typeof target.attachEvent != "undefined")
2519	{
2520        target.attachEvent("on" + eventType, functionRef);
2521        RZ.browsertype = "non-standards";
2522    }
2523	else
2524	{
2525        RZ.browsertype = "unknown";
2526    }
2527}
2528/*---------------------------------------------------------------------------
2529Calls either removeEventListener or removeEvent if defined
2530
2531if (window.addEventListener) window.removeEventListener("focus", refresh, false);
2532else if (window.attachEvent) window.detachEvent("onfocus", refresh);   //IE
2533----------------------------------------------------------------------------*/
2534function RZeventremove(target, eventType, functionRef, capture)
2535{
2536    if (!capture) capture = false;
2537
2538	if (typeof target.addEventListener != "undefined")
2539        target.removeEventListener(eventType, functionRef, capture);
2540
2541	else if (typeof target.attachEvent != "undefined")
2542        target.detachEvent("on" + eventType, functionRef);
2543}
2544/*---------------------------------------------------------------------------------------------
2545Enable a new handler (append to current handler if one defined)
2546---------------------------------------------------------------------------------------------*/
2547function RZsetuphandler(handlerType,handlerFunction,isLast)
2548{
2549	//DCO 11-12-2015: MUST use event listeners when called by script before the body tag,
2550	//because body tag events MAY override (think IE) any body/window events defined here.
2551	var is = document.getElementsByTagName('body').length == 0;
2552
2553	//DCO 12-02-2015: if onload and no <body onload="...">, use listener for backward
2554	//compatibilty with webgen/jquery/scripts.js (which overrides window.onload event)
2555	if (!is && handlerType.indexOf('onload') != -1 && !window.onload) is = true;
2556	if (is)
2557	{
2558		var fn = typeof(handlerFunction) == 'function' ? handlerFunction
2559			   : new Function('', handlerFunction.toString());
2560		if (window.addEventListener) window.addEventListener(handlerType.substr(2), fn, false);
2561		else if (window.attachEvent) window.attachEvent(handlerType, fn
2561);   //IE
2562		else return false;	//safety for unexpected
2563		return true;
2564	}
2565
2566	var functionStr = window[handlerType]; //existing handler function if defined
2567	var parameters = ""; //parameters string
2568	var pos = -1; //position of '{'
2569	var pos1 = -1; //position of '('
2570	var pos2 = -1; //position of ')'
2571
2572	if ( functionStr != null )
2573	{
2574		functionStr = functionStr.toString()
2575		pos = functionStr.indexOf( '{' );
2576		pos1 = functionStr.indexOf( '(' );
2577		pos2 = functionStr.indexOf( ')' );
2578	}
2579
2580	//Check if parameters exist.  If they do, then append them to the current
2581	//parameters string.
2582	if ( pos1 >= 0  && pos2 >= 0 )
2583		parameters += functionStr.substring( pos1+1, pos2 );
2584
2585	//Check if the call to Function() exists.  If it does, then append a call to
2586	//new handler to it at the beginning; otherwise, just call new handler.
2587	if ( pos < 0 )
2588		functionStr = handlerFunction + ';'
2589
2590	else if (isLast)	//DCO 10-20-2014
2591		functionStr = functionStr.substring( pos+1, functionStr.length-1 )	//existing function
2592					+ '\n' + handlerFunction + ';'
2593	else
2594		functionStr = handlerFunction + ';'		//appended function call
2595					+ functionStr.substring( pos+1, functionStr.length-1 );	//existing function
2596
2597	//----- Set new handler and make trace entry
2598	window[handlerType] = new Function( parameters, functionStr );
2599
2600	RZtrace("Initialized " + handlerType + " Handler", window[handlerType].toString() )
2601	return true;
2602}
2603/*-----------------------------------------------------------------------------------
2604  Implements button action operations (e.g. forward, save, delete, new, exit)
2605  Either a button or image is displayed on the page if a valid user is
2606  authenticated via the login page. If security is disabled any username is
2607  allowed.
2608
2609  Normally code is generated to display button if authorized however if RZ.action=html
2610  function does not display button only returns html executed by specified button.
2611
2612  TODO:  Document remaining RZ.* variables
2613
2614  Parameters:
2615  action-		String representing type of action button (See Remarks)
2616  Parameters Format:
2617  <table 20c%>
2618  action         Button Types
2619  -------------  -----------------------------------------------
2620  editpage       "Edit this Page" calls -editform.jsp page
2621  editform       (same as above backward compatibility)
2622  editglobal     "Edit Globals" globals-editform.jsp
2623  \
2624  editlist       Edit this List (-editlist.jsp)
2625  exit           Exit Edit List page; return to caller
2626  newitem        Create new list item
2627  new            (same as above backward compatibility)
2628  edititem       Edit an existing list item
2629  edit           (same as above backward compatibility)
2630  delete         Delete an existing list item
2631  deleteitem     (same as above backward compatibility)
2632  \
2633  save           Edit form save button
2634  cancel         Edit form or Edit List cancel button
2635  \
2636  history        Edit form current record history
2637  editversion    Selects record to edit on history
2638  copyversion    Copy record on history as new version
2639  newversion     Create new version of current record
2640  permissions    opens permissions window
2641  </table>
2642
2643  RZ Input Parameters:
2644  RZ.module-      Name of module
2645  RZ.recordid-	  recordid to process
2646  RZ.nexturl-     url of page recieving control from button
2647  RZ.popupwidth-  width of popup window
2648  RZ.popupheight- height of popup window
2649  RZ.popupscroll- indicate if popup window has scroll bars
2650  RZ.img-         if non\-blank html displayed for button
2651  				  (usually an image tag but can be any html)
2652  RZ.caption-     Label of input type=button
2653  				  (image button used if RZ.img not blank)
2654  RZ.tagname-     If non\-blank specified form button name)
2655  RZ.parentkey-   If not blank, specified parent key rather than letting Revize
2656  				  automatically determine.
2657  RZ.action-	  =html, does not display button
2658                  =false TODO
2659                  =true TODO
2660
2661  Returns:  script executed when button clicked; If RZ.action
2662  -----------------------------------------------------------------------------------*/
2663function RZaction(action)
2664{
2665
2666	if (RZ.nexturl == null || RZ.nexturl == 'null' ) RZ.nexturl = ''
2667	if (RZ.popupwidth == null || RZ.popupwidth == 'null') RZ.popupwidth = ''
2668	if (RZ.popupheight == null || RZ.popupheight == 'null') RZ.popupheight = ''
2669	if (RZ.popupscroll == null || RZ.popupscroll == 'null') RZ.popupscroll = ''
2670
2671	var script=''
2672	var html=''
2673	var anchor = ''
2674	var level = ''
2675	var buttonName=''
2676	var requiredModule = RZ.module
2677	var requiredPermits = ''
2678	var options = ''
2679	var recordid = ''
2680	var parentkey = ''
2681	var msg = ''
2682
2683	//----- Create specific JavaScript executed when button clicked
2684	//		(based on type of action requested)
2685	switch ( action.toLowerCase() )
2686	{
2687
2688		case "editlist":
2689		{
2690			requiredPermits = 'c|u|d'
2691			if (RZ.tagname == '') RZ.tagname = 'RZeditlist';
2692
2693			//-----delete below to always use new code-----\\
2694			if (!EZ.isFeature("EZ"))
2695			script = "RZcalleditlist("
2696				   + "'" + RZ.nexturl + "',"
2697				   + "'" + RZ.popupwidth + "',"
2698				   + "'" + RZ.popupheight + "',"
2699				   + "'" + RZ.popupscroll + "', "
2700				   + "'" + RZ.set + "')"
2701			else
2702			//-----delete above to always use new code-----//
2703
2704			// build call of form:	RZeditlist( {nexturl:RZ.nexturl, ..., set:RZ.set});';
2705			script = 'RZeditlist({'
2706				   + EZ.concat([
2707								RZ.nexturl     ? "nexturl: '"    + RZ.nexturl     + "'" : '',
2708								RZ.module      ? "module: '"     + RZ.module      + "'" : '',	//added 12-15-2015
2709								RZ.popupwidth  ? "popupwidth: '" + RZ.popupwidth  + "'" : '',
2710								RZ.popupheight ? "popupheight:'" + RZ.popupheight + "'" : '',
2711								RZ.popupscroll ? "popupscroll:'" + RZ.popupscroll + "'" : '',
2712								RZ.set ? "set:'" + RZ.set.replace(/'/g, "\\'") + "'" : ''
2713								], ',')
2714				   + '})';
2715			break;
2716		}
2717
2718		//----- Common code for all new and edit actions
2719		case "new":
2720		case "newitem":
2721			level = RZ.linklevel;
2722			if (!RZ.linklevel && RZ.module)
2723				level = RZ.nextseq.listid ? RZ.nextseq.listid : 1;
2724
2725		case "edit":
2726		case "edititem":
2727		case "editform":
2728		case "editpage":
2729		case "editglobal":
2730
2731			recordid = RZ.recordid
2732
2733			//----- Format edit form call
2734			//		Note: without the isNaN test, remaining JavaScript not executed
2735			if ( !isNaN(RZ.recordid) || RZ.recordid.toLowerCase() != 'no items in list' )
2736			{
2737				if(action == 'edit' || action == 'edititem')
2738				{
2739					if (RZ.parentkey != '')
2740						parentkey = RZ.parentkey
2741					else
2742						parentkey = RZlevelQualifier(RZ.linkname,RZ.linklevel,RZ.recordid)
2743				}
2744				else if(action == 'new' || action == 'newitem')
2745				{
2746					parentkey = RZ.parentkey;	//non-blank if specified
2747				}
2748
2749
2750				if(action == 'new' || action == 'newitem'
2751				|| action == 'edit' || action == 'edititem')
2752				{
2753					//----- If page permissions warnings are enabled...
2754					if (RZcheckoptions(RZ.permissions_options,"warnings"))
2755					{
2756						// Display icon if module not specified on new or edit item button
2757						if (RZ.module == '' && RZ.template != '*none*')
2758						{
2759							msg = "'" + RZpermissionWarning(action,'') + "'"	//module req msg
2760							html += '<a href="JavaScript:RZpagemessage(' + RZreplace(msg,'\n','--') + ')">'
2761								 +  '  <img src="/revize/images/warning-button.gif" border=0>'
2762								 +  '</a>'
2763						}
2764
2765						// Display hidden icon in case template can not be determineed
2766						else if (RZ.template == '' && RZ.linkname == '')
2767						{
2768							RZ.html = '<span id="RevizeButtonWarning' + RZ.icons.length + '"'
2769									+ ' style="visibility:hidden">'
2770									+ '  <a href="JavaScript:RZiconMessage(\''+ action +'\','
2771									+ RZ.icons.length + ')"'
2772									+ '   ><img src=\"/revize/images/warning-button.gif\"'
2773									+ '   border=0 alt="Click for Details"></a>'
2774									+ '</span>'
2775							//RZ.html = RZ.html.replace(/</g,'&lt;')	//display html
2776							document.write( RZ.html )
2777							RZ.icons[RZ.icons.length] = RZ.module
2778						}
2779					}
2780				}
2781
2782				script = "RZedit( "
2783				       + "'" + RZ.recordid + "', "
2784				       + "'" + RZ.nexturl + "', "
2785				       + "'" + RZ.popupwidth + "',"
2786				       + "'" + RZ.popupheight + "',"
2787				       + "'" + RZ.popupscroll + "', "
2788				       + "'" + RZ.set + "', "
2789				       + "'" + RZ.module + "',"
2790				       + "'" + RZ.field + "',"
2791				       + "'" + RZ.linkname + "',"
2792				       + "'" + action + "',"
2793				       + "'" + RZ.template + "',"
2794				       + "'" + level + "',"
2795				       + "'" + parentkey + "')"
2796			}
2797
2798			// if setting a recordid, ignore the recordid.value
2799			if ( RZ.set.indexOf('_recordid=') >= 0 ) RZ.recordid = ''
2800
2801			//----- Button name dependent on action
2802			if (RZ.tagname == '')
2803			{
2804				switch (action)
2805				{
2806					case "new":
2807					case "newitem":
2808						RZ.tagname = 'RZnewitem';
2809						requiredPermits = 'c'
2810						anchor = 'Revize_' + RZ.module + '[new]'
2811
2812						break;
2813					case "edit":
2814					case "edititem":
2815						RZ.tagname = 'RZedititem' + RZ.recordid;
2816						requiredPermits = 'u'
2817						anchor = 'Revize_' + RZ.module + '[' + RZ.recordid + ']'
2818						break;
2819					case "editform":
2820					case "editpage":
2821						RZ.tagname = 'RZeditpage';
2822						requiredPermits = 'c|u'
2823						break;
2824					case "editglobal":
2825						RZ.tagname = 'RZeditglobal';
2826						requiredPermits = 'c|u'
2827						break;
2828				}
2829			}
2830			break;
2831
2832		case "exit":
2833			if(typeof RZ.nexturl != 'undefined' && RZ.nexturl != '' && RZ.nexturl != 'NEXTURL')
2834				script = "location='" + RZ.nexturl + "'";
2835			else
2836				script = "RZback( 'RZeditListReturnUrl' );"
2837			if (RZ.tagname == '') RZ.tagname = 'RZexit';
2838			break;
2839
2840		case "delete":
2841		case "deleteitem":
2842			if (RZ.recordid.toLowerCase() != 'no items in list')
2843			{
2844				//script = "RZrecordDelete( '" + RZ.recordid +  "', '" + RZ.module + "' );"
2845				script = "RZdelete( '" + RZ.recordid +  "', '" + RZ.module
2846				if (RZ.nexturl != '') script += "', '" + RZ.nexturl
2847				script +=  "' );"
2848			}
2849			if (RZ.tagname == '') RZ.tagname = 'RZdeleteitem';
2850			requiredPermits = 'd'
2851			break;
2852
2853		case "save":
2854			script = "RZsave( document.XMLForm, '" + RZ.nexturl + "' );"
2855			if (RZ.tagname == '') RZ.tagname = 'RevizeSave';
2856			break;
2857
2858		case "save_as_draft":
2859			script = "RZsave_as_draft( '" + RZgetoption(RZ.options,'workflow') + "' );"
2860			if (RZ.tagname == '') RZ.tagname = 'RevizeSaveAsDraft';
2861			break;
2862
2863		case "cancel":
2864			script = "RZeditFormCancel();"
2865			if (RZ.tagname == '') RZ.tagname = 'RevizeCancel';
2866			break;
2867
2868		case "history":
2869			if (RZ.nexturl != '')
2870				options += 'nexturl='+RZ.nexturl
2871			if (RZ.field != '')
2872				options += 'fields='+RZ.field
2873			script = "RZhistory("
2874			       + "'" + RZ.module + "',"
2875			       + "'" + RZ.recordid + "', "
2876			       + "'" + RZ.version + "', "
2877			       + "'" + options + "') "
2878			if (RZ.tagname == '') RZ.tagname = 'RevizeHistory';
2879			break;
2880
2881		case "permissions":
2882			requiredModule = RZ.permissions_module
2883			requiredPermits = 'u'
2884			if (RZ.nexturl != '')
2885				options += 'nexturl='+RZ.nexturl
2886			if (RZ.linkname != '')
2887				options += 'linkname='+RZ.linkname
2888			if (RZ.module != '')
2889				options += 'module='+RZ.module
2890			if (RZ.object != '')
2891				options += 'object='+RZ.object
2892
2893			// if standard permissions buttom, treat as "Admin Panel"
2894			var isAdminPanel = true;
2895			if(RZcheckoptions(RZ.webspacedesc,"noadminpanel"))
2896			{
2897				isAdminPanel = false;
2898			}
2899
2900			if (!options && isAdminPanel
2901			&& (RZ.img.indexOf('src="images/edit/permissions.jpg"') != -1
2902			|| RZ.img.indexOf('src="images/edit/permissions.gif"') != -1))
2903			{
2904				script = "void(0);";
2905				requiredModule = '';
2906				RZ.img = RZ.img.replace(/src="images\/edit\/permissions.jpg"/,'src="/revize/images/edit/admin_panel.jpg"');
2907				RZ.img = RZ.img.replace(/src="images\/edit\/permissions.gif"/,'src="/revize/images/edit/admin_panel.jpg"');
2908				RZ.img = RZ.img.replace(/alt="Permissions"/,'alt="Admin Panel" id="RZadminwinButton" onmouseup="RZadminwin()"');
2909			}
2910			// if permissions active
2911			else if (RZ.permissions_module != '')
2912				script = "RZpermissions("
2913					   + "'" + RZ.set + "',"
2914					   + "'" + options + "') "
2915
2916			if (RZ.tagname == '') RZ.tagname = 'RevizePermissions';
2917			break;
2918
2919		case "copyversion":
2920				options += ',copy'
2921		case "newversion":
2922		case "editversion":
2923			if (RZ.nexturl != '')
2924				options += 'nexturl='+RZ.nexturl
2925			script = "RZeditversion("
2926			       + "'" + RZ.module + "',"
2927			       + "'" + RZ.version + "', "
2928			       + "'" + options + "') "
2929			//TODO: perhaps button should be displayed and message if clicked.
2930			if (RZ.editnextversion == '') script = ''	//new record - no history
2931			if (RZ.tagname == '') RZ.tagname = 'RevizeVersion';
2932			break;
2933
2934		default:
2935			script = "RZalert('Unknown or Invalid Revize Action Request');"
2936	}
2937
2938	//----- Build html containing script (image or button version)
2939	if (script == '')
2940		html = ''
2941	else
2942	{
2943		if (RZ.script != '')
2944		{
2945			//----- Test results of user specified script via conditional operator
2946			//		so RZ.script code can cancel the button by returing false
2947			//
2948			// 			e.g. if (!user script)?donothing:button script;
2949			//
2950			if (RZright(RZ.script,1) != ';') RZ.script += ';'
2951			script = 'RZ.results=' + RZ.script
2952			       + '(!RZ.results && typeof RZ.results != \'undefined\')?void(0):'
2953			       + script;
2954		}
2955
2956		if (RZ.img != "")
2957		{
2958			html += '<a href="javascript:' + script + '">' + RZ.img + '</a>'
2959
2960			// show the help button after the adminpanel button
2961			if (RZ.img.indexOf('/revize/images/edit/admin_panel.jpg') != -1)
2962				html += '&nbsp;<a href="http://cms4.revize.com/revize/supportrevize/revize_faq.php" target="_new">'
2963					  + '<img src="../images/edit/help.jpg" alt="Help" border="0" /></a>';
2964		}
2965		else
2966		{
2967			if (RZ.caption == '') RZ.caption = 'Edit Page'
2968			html += '<input type="button" name="' + RZ.tagname + '" value="' + RZ.caption + '" '
2969				 + 'onClick="' + script + ';">'
2970		}
2971	}
2972
2973	//----- Add <br> and/or anchor tag to html if requested
2974	if (html != '')
2975	{
2976		if (RZ.options.indexOf('<br>') != -1) html += '<br>'
2977		if (anchor != '') anchor = '<a name="' + anchor + '"></a>'
2978		html += anchor
2979	}
2980
2981	//----- write html if logged into this webspace with correct permits
2982	//
2983	//		If RZ.active is blank or false, only write html if logged in with
2984	//		correct permissions for specified module and only return script
2985	//		when html written (default case).
2986	//
2987	//		If RZ.active is true, always write html
2988	//
2989	//		If RZ.active = 'html': return html instead of writting.  If not
2990	//		logged in or do not have permissions return blank for html.
2991
2992	var active = RZ.active;
2993	if (active == 'html')
2994	{
2995		if ( RZlogin('', requiredModule, requiredPermits, action) )
2996			script = html;
2997		else
2998			script = '';
2999	}
3000	//----- If action is blank (i.e. not used)...
3001	else if (active == '')	// RZ.active blank or false (note: blank returns false)
3002	{
3003		// write html if logged into this webspace & permits for module
3004		active = RZlogin( html, requiredModule, requiredPermits, action );
3005		if (!active) script = '';
3006	}
3007	//----- If RZ.action is true, write html without checks
3008	else if ( active == 'true'						// RZ.active is 'true'
3009	|| (typeof active == 'boolean' && active) )		// RZ.active is true
3010	{
3011		document.write(html);
3012	}
3013
3014	RZ.message = ''
3015	RZmsgAdd( "action", action )
3016    RZmsgAdd( "active", active )
3017	RZmsgAdd( "webspace", '\t' + RZ.webspace )
3018    RZmsgAdd( "module  ", '\t' + RZ.module )
3019    RZmsgAdd( "field   ", '\t' + RZ.field )
3020    RZmsgAdd( "linkname", '\t' + RZ.linkname )
3021    RZmsgAdd( "recordid", "\t(" + RZ.recordid + ")" )
3022    RZmsgAdd( "nexturl",  RZ.nexturl )
3023    RZmsgAdd( "popup",    RZ.popupwidth + "," + RZ.popupheight + "," + RZ.popupscroll )
3024    RZmsgAdd( "set",      RZ.set )
3025    RZmsgAdd( "img tag",  RZ.img )
3026    RZmsgAdd( "tagname",  RZ.tagname )
3027    RZmsgAdd( "caption",  RZ.caption )
3028    RZmsgAdd( "options",  options )
3029    RZmsgAdd( "generated html", html )
3030	RZtrace( "Action Button Processed", RZ.message );
3031
3032	//----- clear RZ.* action arguments
3033	RZactionReset();
3034
3035	//if (!active) script = ''
3036	return script;		//return generated script
3037}
3038/*---------------------------------------------------------------------------
3039Append "key: value" to RZ.message if value is not blank
3040Note: empty string same as false AND false matches \t & \t\t
3041----------------------------------------------------------------------------*/
3042function RZmsgAdd(key,val)
3043{
3044	//----- Following line avoids false matching empty string, \t & \t\t
3045	//		(also allow use of substring on true and false values)
3046	return;
3047	value = String(val)
3048
3049	//----- Return if any empty value
3050	if(value==''
3051	|| value==null
3052	|| value=='\t()'					// empty recordid
3053	|| value=='0,0,' || value==',,'		// empty popup
3054	|| value=='\t' || value=='\t\t')
3055		return
3056
3057	//----- Append : to key if value does not begin with a tab
3058	if (value.substring(0,1) != '\t') key += ': '
3059
3060	//----- Append value to message
3061	RZ.message += key + value + '\n'
3062}
3063/*---------------------------------------------------------------------------
3064  (Internal Function) Resets RZ.* variables used as input variables for
3065  serveral functions called using RZ input parameters:
3066  	RZaction, RZlinkmanager, RZdelete
3067
3068  This function is called during page setup and after arguments are used.
3069  This ensures values from one call are not carried forward to the next call.
3070
3071  Parameters:
3072	  None  (no input parameters)
3073
3074  Returns:
3075  No return value but the RZ input objects are set to an empty string
3076  * (see source code for current list of objects)
3077  ---------------------------------------------------------------------------*/
3078function RZactionReset()
3079{
3080	RZ.module=""; RZ.field=""; RZ.recordid=""; RZ.nexturl="";
3081	RZ.popupwidth=0; RZ.popupheight=0; RZ.popupscroll="";
3082	RZ.img=""; RZ.set=""; RZ.caption=""; RZ.tagname="";
3083	RZ.options=""; RZ.active=""; RZ.script="";
3084	RZ.rtefont=""; RZ.rtestyles = "";
3085	RZ.template=""; RZ.object="";
3086	RZ.linkname=""; RZ.linkmodule=""; RZ.linklevel="";
3087	RZ.filelocation=""; RZ.imagelocation="";
3088	RZ.version=""; RZ.nextversion="";
3089	RZ.imagemaxwidth=''; RZ.imagemaxheight=''; RZ.imagemaxbytes='';
3090	RZ.parentkey=''; RZ.windowname='';
3091
3092	// optional link properties not initialized by RZTagSupport
3093	RZ.linkpathname = ''
3094	RZ.linknewsection = ''
3095	RZ.linkdisplaydefault = ''
3096	RZ.linktemplatedefault = ''
3097	RZ.linkfilenamedefault = ''
3098	RZ.linkautocontinue = ''
3099}
3100
3101/*--------------------------------------------------------------------------
3102  Convert url to absolute url using the page location information determined
3103  during page initialization.
3104  Parameters:
3105  url :  url to convert
3106  --------------------------------------------------------------------------*/
3107function RZabsoluteUrl(url)
3108{
3109	if (url != '')
3110	{
3111		if ( !RZisAbsoluteUrl(url) )
3112		{
3113			if(url.substring(0,4) == 'www.')
3114				url = 'http://'+url;
3115			else
3116            {
3117                //DCO 02-22-2007\\
3118                //url = RZ.page.domain + RZ.page.pathname + '/' + url
3119
3120                // domain + page pathname + baseprefix yeilds url to base channel
3121                url = RZ.page.domain + RZ.page.pathname + '/'
3122                	+ (RZ.baseurlprefix ? RZ.baseurlprefix : '')
3123                	+ url;
3124
3125                while (url.indexOf("/../") > 0)
3126                {   //for each ../ remove it along with preceeding folder
3127                    var offsetEnd = url.indexOf("/../");
3128                    var offsetBeg = url.lastIndexOf("/",offsetEnd-1);
3129                    url = RZsubstring(url,0,offsetBeg)
3130                        + RZsubstring(url,offsetEnd+3);
3131                }
3132                //DCO 02-22-2007//
3133            }
3134		}
3135	}
3136	return url
3137}
3138/*---------------------------------------------------------------------------
3139is url absolute reference
3140----------------------------------------------------------------------------*/
3141function RZisAbsoluteUrl(url)
3142{
3143	if(url.substring(0,1) != '/'
3144	&& url.substring(0,7) != 'http://'
3145	&& url.substring(0,8) != 'https://')
3146		return false
3147	else
3148		return true
3149}
3150/*---------------------------------------------------------------------------
3151Determine Edit Page URL
3152----------------------------------------------------------------------------*/
3153function RZgetEditPageUrl( editPageUrl )
3154{
3155	var url = ""
3156	if (editPageUrl == 'EDITLISTURL')
3157		url = RZ.page.filename + '-editlist.jsp'
3158	else if (editPageUrl == 'EDITFORMURL')
3159		url = RZ.page.filename + '-editform.jsp'
3160	else
3161		url = editPageUrl
3162
3163	//----- IE may need baseurlprefix
3164	//DCO 01-23-2014
3165	//if (RZ.MSIE && editPageUrl != '' && !RZisAbsoluteUrl(editPageUrl)
3166
3167	// DJO 06-01-2016 - Can handle Edge with base url method just like IE
3168	if ((RZ.isMSEdge || RZ.MSIE || RZ.isIEstandardsMode)
3169	&& editPageUrl != '' && !RZisAbsoluteUrl(editPageUrl)
3170	&& typeof RZ.baseurlprefix != 'undefined' && RZ.baseurlprefix.length > 0)
3171		url = RZ.baseurlprefix + url;
3172
3173	//----- if url contains a function call, replace with results
3174	//		function call is "non-letter a-z...(...);" semi-colon required
3175	url = url.replace(/([^\w])(\w+\(.*?\));/g,
3176	function (inputStr,nonWord,functionCall,semicolon)
3177	{
3178		return nonWord + eval(functionCall);
3179	});
3180
3181	return url
3182}
3183/*---------------------------------------------------------------------------
3184Save return URL in cookie
3185TODO: store in control panel window
3186----------------------------------------------------------------------------*/
3187function RZsaveReturnUrl( returnUrlKey, url )
3188{
3189	if (arguments.length < 2) url = location.href	//DCO 10-20-2014
3190	//var url = location.href						//		 ''
3191	var hash = location.hash
3192	if (hash != '')
3193		url = url.substring(0,url.length-hash.length)
3194	if (RZ.trace)
3195		url += '#trace'
3196	if (RZ.debug)
3197		url += '#debug'
3198	RZsetCookieValue( returnUrlKey, url )
3199}
3200/*----------------------------------------------------------------------------
3201Call EDIT LIST page
3202----------------------------------------------------------------------------*/
3203/**
3204 *	DCO 03-07-2012: now pass single object argument to RZeditlist()
3205 *					object more flexible & readable
3206 *	Below function with named arguments retained for backward compatibility.
3207 **/
3208function RZcalleditlist(editPageUrl, width, height, scroll, set)
3209{
3210	var args = 		//args element names match RZ.??? names passed to RZaction()
3211	{				//argument names coorespond to legacy argument names
3212		nexturl     : editPageUrl,
3213		popupwidth  : width,
3214		popupheight : height,
3215		popupscroll : scroll,
3216		set         : set
3217	}
3218	return RZeditlist(args);
3219}
3220/**
3221 *	DCO 03-07-2012: new primary function passed single object argument whose
3222 *					element names match RZ.??? names passed to RZaction()
3223 *	Example call:
3224 *		RZeditlist( {nexturl: nexturl, popupwidth: popupwidth, ...} );
3225 **/
3226function RZeditlist (args)
3227{
3228	//----- Internal work variables
3229	var msg = '';
3230
3231	//----- Following variables were previously passed as named arguments
3232	//		Local variables & args element names match RZ.??? names passed to RZaction()
3233	var nexturl     = args.nexturl     ? args.nexturl     : location.href;
3234	var popupwidth  = args.popupwidth  ? args.popupwidth  : '';
3235	var popupheight = args.popupheight ? args.popupheight : '';
3236	var popupscroll = args.popupscroll ? args.popupscroll : '';
3237	var set         = args.set         ? args.set         : '';
3238
3239	//----- New input arguments never passed as named arguments
3240	var windowname = args.windowname ? args.windowname
3241				   : 'ListWindow';	//default
3242
3243	//----- Call Developer defined onlist handler and quit if it returns false
3244	if (typeof window.onlist == 'function')
3245	{
3246		// update args with current values and pass to onedit handler
3247		// returns false to cancel delete, or object with below values:
3248		args.windowname = windowname;
3249		var returnValues = window.onlist(args);
3250		if (typeof returnValues == 'undefined' || returnValues == false)
3251		{
3252			window.status = 'Edit Canceled'
3253			return void(0)
3254		}
3255		else if (typeof(returnValues) == 'object')
3256		{
3257			if (returnValues.set) set = returnValues.set;
3258			if (returnValues.nexturl) nexturl = returnValues.nexturl;
3259			if (returnValues.windowname) windowname = returnValues.windowname;
3260		}
3261	}
3262
3263	//----- Default nexturl if blank and adjust for IE if not absolute
3264	RZ.parameters = RZgetEditPageUrl(nexturl);
3265	RZaddUrlParameter( 'webspace=' + RZ.webspace )
3266	if (args.module && EZ.isFeature("EZ"))
3267	{
3268		RZaddUrlParameter( 'module=' + args.module )			//RZ.editmodule for editlist
3269		if (EZ && EZ.formfields && EZ.formfields.setupDropdown)
3270			set = EZ.formfields.setupDropdown(set, args.module); //check for EZdropdown class
3271	}
3272	RZsetParameter(set)
3273	RZaddUrlParameter( 'permissions_template=' + RZ.pagetemplatename )
3274	RZaddUrlParameter( 'permissions_parent=' + RZ.page_key )
3275	nexturl = RZ.parameters;
3276
3277	RZtrace("Calling Edit List", RZ.message )
3278
3279	RZ.editWindow = RZpopupUrl(windowname, nexturl, popupwidth, popupheight, popupscroll)
3280	if (RZ.editWindow == null)	//no popup properties defined
3281	{
3282		RZsaveReturnUrl( 'RZeditListReturnUrl' )
3283		document.location = nexturl;
3284	}
3285	return void(0)
3286}
3287/*---------------------------------------------------------------------------
3288----------------------------------------------------------------------------*/
3289function RZlistbegin( listid )
3290{
3291	RZ.nextseq.listid = listid + 1;
3292}
3293/*---------------------------------------------------------------------------
3294Called by closing list tag to remember the dependent template used by a link
3295tag inside the list.  See Dreamweaver help for more details.
3296
3297TODO: consider triggering a warning if there is more than one list using the
3298same module which puts the template determination at risk.  Also RZTagSupport
3299might consider multple links and/or templates ambigous.
3300
3301This function is also called with the linkname if a link manager link tag was
3302encountered inside the list.
3303----------------------------------------------------------------------------*/
3304function RZlinktemplate( module, template, listlinkname )
3305{
3306	if (module != '')
3307	{
3308		if (typeof RZ.linktemplates[module] == 'undefined'
3309		||  RZ.linktemplates[module] == '')
3310			RZ.linktemplates[module] = template
3311	}
3312}
3313
3314/*---------------------------------------------------------------------------
3315Multi-level menu / page permissions support:
3316
3317This function NOW called by RZaction to determine parentkey for level > 0.
3318For level 0, blank is returned because parent is determined by other means.
3319The parentkey is stored in RZ.linkpagekey by RZlinkmanager() which is called
3320via the script generated by the rz:link tag.
3321TODO: RZ.linkpagekey should probably be qualified by linkname.
3322
3323This function WAS called by RZlinkmanager() and RZaction() to remember the 1st
3324recordid encountered at each level change for use by edit buttons.
3325
3326This scheme is required to pass information from link tag to edit button
3327processing because the link tag may occur after the button in the html.
3328----------------------------------------------------------------------------*/
3329function RZlevelQualifier(linkname,level,recordid)
3330{
3331	var parentkey = ''
3332
3333	if (isNaN(level)) return '';
3334	level = parseInt(level)
3335
3336	/* deprecated but strategy may be useful in the future
3337	//----- If recordid not a number return
3338	if (isNaN(recordid)) return '';
3339
3340	if (typeof RZ.linklevelmemory == 'undefined')
3341		RZ.linklevelmemory = -1
3342
3343	//----- Clear level qualifier whenever level moves up
3344	if (level < RZ.linklevelmemory)
3345	{
3346		RZ.linklevelmemory = level
3347		RZ.levelrecordid[level] == null
3348	}
3349
3350	//----- Save page_key of prior menu item when level moves down
3351	else if (level > RZ.linklevelmemory)
3352	{
3353		RZ.linklevelmemory = level
3354		RZ.levelrecordid[level] = recordid
3355
3356	}
3357	*/
3358
3359	//----- Get above level pagekey if level > 0
3360	if (level > 0)
3361		parentkey = RZ.linkpagekey[level-1]
3362
3363	return parentkey
3364}
3365/*----------------------------------------------------------------------------
3366Call EDIT FORM page
3367----------------------------------------------------------------------------*/
3368/* Same as RZedit (retained for backward compatibility) */
3369function RZcallEditForm(recordid, editPageUrl, width,height,scroll, set)
3370{
3371	return RZedit(recordid, editPageUrl, width,height,scroll, set);
3372}
3373/* Same as RZedit (retained for backward compatibility) */
3374function RZcalleditform(recordid, editPageUrl, width,height,scroll, set, module, field, linkname)
3375{
3376	return RZedit(recordid, editPageUrl, width,height,scroll, set, module, field, linkname);
3377}
3378/**
3379* 01-20-2014 DCO: moved from setup_editlist_javascript.jsp
3380* Probably only called by NEW and EDIT ITEM buttons created with DW before 02-29-01.
3381**/
3382function RZrecordEdit( recordID, editPageUrl ){
3383  RZcallEditForm ( recordID, editPageUrl )
3384}
3385function RZrecordNew( editPageUrl ){
3386  RZcallEditForm ( 'new', editPageUrl )
3387}
3388/**
3389 *	DCO 03-07-2012: now pass single object argument to RZeditform()
3390 *					way too many arguments; object more flexible & readable
3391 *	Below function with named arguments retained for backward compatibility.
3392 **/
3393function RZedit(recordid, editPageUrl, width, height, scroll, set, module, field, linkname, action, template, level, parentkey)
3394{
3395	var args = 		//args element names match to RZ.??? names passed to RZaction()
3396	{				//argument names coorespond to legacy argument names
3397		recordid    : recordid,
3398		nexturl     : editPageUrl,
3399		popupwidth  : width,
3400		popupheight : height,
3401		popupscroll : scroll,
3402		set         : set,
3403		module      : module,
3404		field       : field,
3405		linkname    : linkname,
3406		action      : action,
3407		template    : template,
3408		level       : level,
3409		parentkey   : parentkey
3410	}
3411	return RZeditform(args);
3412}
3413/**
3414 *	DCO 03-07-2012: new primary function passed single object argument whose
3415 *					element names match RZ.??? names passed to RZaction()
3416 *	Example call:
3417 *		RZeditform( {recordid: nexturl, popupwidth: popupwidth, ...} );
3418 **/
3419function RZeditform(args)
3420{
3421	//----- Internal work variables
3422	var str = '';
3423	var msg = '';
3424
3425	//----- Following variables were previously passed as (optional)named arguments.
3426	//		Local variables & args element names match RZ.??? names passed to RZaction()
3427	var recordid    = args.recordid    ? args.recordid : '';
3428	var nexturl     = args.nexturl     ? args.nexturl : '';
3429	var popupwidth  = args.popupwidth  ? args.popupwidth : ''
3430	var popupheight = args.popupheight ? args.popupheight : ''
3431	var popupscroll = args.popupscroll ? args.popupscroll : ''
3432	var set         = args.set         ? args.set : ''
3433	var module      = args.module      ? args.module : ''
3434	var field       = args.field       ? args.field  : ''
3435	var linkname    = args.linkname    ? args.linkname : ''
3436	var action      = args.action      ? args.action : ''
3437	var template    = args.template    ? args.template : ''
3438	var level       = args.level       ? args.level : ''
3439	var parentkey   = args.parentkey   ? args.parentkey : ''
3440
3441	//----- New input arguments never passed as named arguments
3442	var windowname = args.windowname ? args.windowname
3443				   : (window.name == 'EditWindow' ? 'EditWindowPopup' : 'EditWindow');
3444
3445	var samplearg  = args.samplearg  ? args.samplearg : ''; //default is ''
3446
3447	//----- Processing...
3448	RZtrace( "Edit Form Button Clicked", "Record Id: (" + recordid + ")" );
3449
3450	//----- Call Developer defined onedit handler and quit if it returns false
3451	if (typeof window.onedit == 'function')
3452	{
3453		// update args with current values and pass to onedit handler
3454		// returns false to cancel delete, or object with below values:
3455		args.windowname = windowname;
3456		var returnValues = window.onedit(args);
3457		if (typeof returnValues == 'undefined' || returnValues == false)
3458		{
3459			window.status = 'Edit Canceled'
3460			return void(0)
3461		}
3462		else if (typeof(returnValues) == 'object')
3463		{
3464			if (returnValues.set) set = returnValues.set;
3465			if (returnValues.nexturl) nexturl = returnValues.nexturl;
3466			if (returnValues.windowname) windowname = returnValues.windowname;
3467		}
3468	}
3469
3470	//----- Apply baseurl prefix to nexturl if IE browser
3471	var url = RZgetEditPageUrl(nexturl);
3472	if (linkname == '')
3473	{
3474		RZ.message = ''
3475		var nextseqKey = module + '_' + level;	//level is listid
3476		if (action == 'newitem' && RZ.nextseq.modules[nextseqKey]
3477		&& (','+set).indexOf(','+ module + '.' + RZ.nextseq.modules[nextseqKey].field) == -1)
3478		{
3479			str = module + '.' + RZ.nextseq.modules[nextseqKey].field + '=' + RZ.nextseq.modules[nextseqKey].seq;
3480			if (set) set += ',';
3481			set += str;
3482		}
3483
3484		RZsetEditParameters(module,field,set)
3485
3486		recordidParameter = RZsetEditRecordParameter(recordid)
3487		if (recordidParameter == '*ERROR*') return void(0)
3488
3489		//----- Page Permissions processing (non-link manager)
3490		if (RZ.permissions_module != '')
3491		{
3492			if (action == 'new' || action == 'newitem'
3493			|| action == 'edit' || action == 'edititem')
3494			{
3495				msg = RZpermissionWarning(action,template,module)
3496				if (msg != '')
3497					if (!RZconfirm(msg)) return
3498
3499				if (template == '')
3500					if (typeof RZ.linktemplates[module] != 'undefined')
3501						template = RZ.linktemplates[module];
3502
3503				// When template passed on url, RZsave will include template & parent page_key
3504				// in the save record XML request (template defined by new & edit buttons).
3505				if (template != '' && template != '*none*')
3506					RZaddUrlParameter( 'permissions_template=' + template )
3507			}
3508			else if (action == 'editform' || action == 'editpage' || action == 'editglobal')
3509			{
3510				// edit this page button(s) do not define parents because the edited recordid
3511				// is usually not the dependent record module.  Another issue is parent passed
3512				// below is the current page when links are added and would not be correct for
3513				// this dependent page.
3514				//RZaddUrlParameter( 'permissions_template=' + RZ.pagetemplatename )
3515			}
3516
3517			//----- Always pass parent_key in case the edit form adds links via the RTE.
3518			//		NOTE: Don't add parent if already on url but this is a very specific sce
3518nario.
3519			if (RZ.pagetype == 'template' && url.indexOf("permissions_parent=") == -1)
3520				RZaddUrlParameter( 'permissions_parent=' + RZ.page_key )
3521			else	//editlist page
3522				RZaddUrlParameter( 'permissions_parent=' + RZ.permissions_parent )
3523
3524			//----- Pass caller page key to determine workflowname
3525			if (RZ.page_key != '')
3526				RZaddUrlParameter( 'page_key=' + RZ.page_key )
3527		}
3528
3529		if (url.indexOf('?') != -1 && RZ.parameters.substr(0,1) == '?')
3530			RZ.parameters = '&' + RZ.parameters.substring(1);
3531		url += RZ.parameters + recordidParameter
3532		RZtrace('Edit Form url parameters',RZ.message)
3533	}
3534
3535	//----- Check for link manager parameters
3536	else
3537	{
3538		if (typeof RZ.link[linkname] != 'object')
3539			msg = 'Specified Link Name ('+linkname+') Does Not Exist or is Not\n'
3540				+ 'Properly Defined (make sure the ' + linkname + ' link exists).\n'
3541				+ 'The link tag defines required options used by Link Manager\n\n'
3542				+ 'If the list is not displaying a message when empty,\n'
3543				+ '(i.e. noemptylistmessage option set) a copy of the\n'
3544				+ 'link tag must be inside the list header.\n\n'
3545				+ 'If link tag exists make sure its name matches the name specified\n'
3546				+ 'specified on this button.'
3547
3548		if (msg == '' && module == '')
3549			msg = 'Link Name ('+linkname+') associated with this action has\n'
3550				+ 'not specified a module.\n\n'
3551				+ 'Link Manager can not be called without knowing the module\n'
3552				+ '(check associated link and make sure a module is specified).'
3553
3554		//----- If errors display message and return
3555		if (msg != '' )
3556		{
3557			RZalert(msg);
3558			return void(0);
3559		}
3560
3561		//----- Set all link manager properties including window size and url
3562		//		(RZsetLinkManagerProperties calls RZsetEditParameters)
3563		//
3564		RZsetLinkManagerProperties(linkname,module,field,recordid,set,url)
3565		recordidParameter = RZsetEditRecordParameter(recordid)
3566		if (recordidParameter == '*ERROR*') return void(0)
3567
3568		//----- Pass user popup window values to link manager on url
3569		RZ.link[linkname].popupwidth = popupwidth
3570		RZ.link[linkname].popupheight = popupheight
3571		RZ.link[linkname].popupscroll = popupscroll
3572		RZ.link[linkname].nexturl = RZabsoluteUrl( url )
3573
3574		//----- Get link manager popup window properties
3575		popupwidth  = RZ.link[linkname].linkwidth
3576		popupheight = RZ.link[linkname].linkheight
3577		popupscroll = RZ.link[linkname].linkscroll;
3578		url    = RZ.link[linkname].linkurl + recordidParameter
3579			   + (RZ.linkmanagertest ? '#test' : '');
3580
3581		//----- Pass linkparent
3582		var parent = ''
3583		if (level == '')
3584		{
3585			if (typeof RZ.link[linkname].linkparent != 'undefined')
3586				parent = RZ.link[linkname].linkparent
3587			if (parent == '')
3588				parent = RZ.page_key;
3589		}
3590		else	//multi-level processing
3591		{
3592			if (parentkey != '')	//if passed as argument
3593				parent = parentkey;
3594			else if ( isNaN(level) )
3595			{
3596				msg = 'Non-numberic level specified for this button.\n\n'
3597				    + 'Multi-level menu relationships can not be maintained\n'
3598				    + '(check button and specify a numeric level).'
3599				if (!RZconfirm(msg)) return
3600			}
3601			else if (action == 'new' || action == 'newitem')
3602			{
3603				// for existing level, linkparentnew should be defined
3604				if(typeof RZ.linkparentnew[linkname] != 'undefined'
3605				&& typeof RZ.linkparentnew[linkname][level] != 'undefined')
3606					parent = RZ.linkparentnew[linkname][level]
3607
3608				// new level; use last item recordid at prior level for parent
3609				else if (eval(level) != 0)	//TODO: should be min level (not 0)
3610					parent = RZ.linkpagekey[level-1];	//undefined caught below
3611				else
3612					parent = RZ.permissions_parent
3613			}
3614			else if (action == 'edit' || action == 'edititem')
3615			{
3616				if (eval(level) == 0)
3617				{
3618					if(typeof RZ.linkparentnew[linkname] != 'undefined'
3619					&& typeof RZ.linkparentnew[linkname][level] != 'undefined')
3620						parent = RZ.linkparentnew[linkname][level]
3621				}
3622				else	//level > 0
3623					parent = parentkey;		//undefined caught below
3624			}
3625		}		// end of multi-level processing
3626
3627		//----- Must have a parent when page permissions are enabled
3628		if (RZ.permissions_module != ''
3629		&& (typeof parent == 'undefined' || parent == 'undefined' || parent == ''))
3630		{
3631			msg = 'this'
3632			if (action.indexOf('new') == 0) msg = 'new'
3633			msg = 'This button is not configured for the '+msg+' page to properly INHERIT\n'
3634			    + 'page permissions because the parent is unknown'
3635			if (level != '') msg += ' for level ' + level
3636			msg +='.\n\n'
3637			    + 'Permissions may need to be explicitly defined on the page\n'
3638			    + 'associated with this link.'
3639			//if ( !RZconfirm(msg) ) return
3640		}
3641
3642		if (parent != '' && parent != 'undefined')
3643			RZ.link[linkname].linkparent = parent
3644
3645		if (!RZ.link[linkname].linkseq && RZ.nextseq.linknames[linkname])
3646			RZ.link[linkname].linkseq = RZ.nextseq.linknames[linkname].seq;
3647	}
3648
3649	RZtrace("Calling Edit Form", "URL: " + url )
3650
3651	//----- Suppress empty url parameters
3652	if (url.indexOf('/revize/util/linkmanager') == 0)
3653	{
3654		var urlFull = url;
3655		url = url.replace(/\&[^\&]*=(?=\&)/g,'');
3656		if (urlFull != url)
3657			RZtrace("Calling linkmanager (empty parameters deleted)", "URL: " + url )
3658	}
3659
3660	//----- Call popup window if requested else goto Edit Page URL
3661	RZ.editWindow = RZpopupUrl(windowname, url, popupwidth, popupheight, popupscroll)
3662	if (RZ.editWindow == null)	//no popup properties
3663	{
3664		RZsaveReturnUrl( 'RZeditFormReturnUrl' )
3665		var pathfilename = RZisPopupCall() ? RZgetfileinfo(RZabsoluteUrl(url)).pathfilename : '';
3666		RZsetcookie('RZnotPopup', pathfilename, RZ.webspace);
3667		document.location = url
3668	}
3669	//----- If popup call, clear RZeditFormReturnUrl cookie //DCO 10-20-2014
3670	else
3671		RZsaveReturnUrl( 'RZeditFormReturnUrl', '' );
3672
3673	//----- Suspend processing if called as submit
3674	return void(0);
3675}
3676/*---------------------------------------------------------------------------
3677(Internal Function) Display page permission warning
3678Internal: Diagnostics Support
3679----------------------------------------------------------------------------*/
3680function RZlinkWithoutParent(module,recordid,code)
3681{
3682	if (typeof RZ.noparent[module] == 'undefined')
3683		RZ.noparent[module] = new Object();
3684	RZ.noparent[module][recordid] = code
3685
3686	code = "'" + code + "'"
3687	var html = '<a href="javascript:RZpagemessage(' + code + ')">'
3688	         + '<img src="/revize/images/warning-parent.gif" border="0"></a>'
3689	RZlogin(html)
3690}
3691/*---------------------------------------------------------------------------
3692(Internal Function) Display message regarding button configuration issue
3693Internal: Diagnostics Support
3694----------------------------------------------------------------------------*/
3695function RZiconMessage(action,index)
3696{
3697	module = RZ.icons[index]
3698	var msg = RZpermissionWarning(action,'',module)
3699	if (msg != '')
3700		if (!RZconfirm(msg)) return
3701}
3702/*---------------------------------------------------------------------------
3703(Internal Function) Display warning if button not configured correctly
3704Internal: Diagnostics Support
3705----------------------------------------------------------------------------*/
3706function RZpermissionWarning(action,template,module)
3707{
3708	var msg = '';
3709	var buttonName = ''
3710	if (RZsubstring(action,0,3).toLowerCase() == 'new')
3711		buttonName = 'NEW '
3712	else if (RZsubstring(action,0,4).toLowerCase() == 'edit')
3713		buttonName = 'EDIT '
3714
3715	// Get dependent template for page permissions
3716	if (template == '')
3717	{
3718		if (module == '')	//test by clearing RZ.template and RZ.module on button
3719		{
3720			msg = 'The template used to create the new page could not be \n'
3721				+ 'determined because no module was specified on the '
3722				+ buttonName + 'button.'
3723			}
3724
3725		// Get template processed from the list associated with the specified module
3726		else if (typeof RZ.linktemplates[module] != 'undefined')
3727			template = RZ.linktemplates[module];
3728
3729		else				//test by specifing incorrect module on button
3730			msg = 'The template used to create new pages can not be determined\n'
3731				+ 'because there does not appear to be any lists associated with\n'
3732				+ 'with the currently specified module: ' + module + '.'
3733	}
3734	if (msg == '' && template == '')	//test by clearing RZ.template on button
3735		msg = 'The template used to create new pages can not be determined\n'
3736			+ 'because there are no links in the list associated with the\n'
3737			+ 'currently specified module: ' + module + '\n\n'
3738			+ 'The developer may need to specify the template on the ' + buttonName + 'button\n'
3739			+ 'If pages are not created when list items are added, a template of none\n'
3740			+ 'should be specified.'
3741
3742	// template not required for single record edits
3743	if (template == '*none*'
3744	|| action == 'editform' || action == 'editpage' || action == 'editglobal')
3745		msg = ''
3746
3747	// Warn content editor about potential permissions inheritance issues
3748	if (msg != '')
3749	{
3750		if (buttonName == 'NEW ')
3751		{
3752			msg = 'If this NEW button creates a new page, that page will NOT\n'
3753				+ 'inherit permissions for the following reason:\n\n'
3754				+ msg
3755			msg=''
3756		}
3757		else if ( !RZcheckoptions(RZ.permissions_options,"warnings") )
3758			msg = ''	//no warning if migration option not enabled
3759		else
3760			msg = 'The EDIT button is not configured to properly pass page permissions\n'
3761				+ 'to the page created when this item was added to the associated list.\n\n'
3762				+ 'The template must be known to assign a parent to child pages.\n\n'
3763				+ msg
3764	}
3765	return msg
3766}
3767/*---------------------------------------------------------------------------
3768(Internal Function) Sets general edit url parameters used with or w/o link manager.
3769Internal: Update Record Support
3770----------------------------------------------------------------------------*/
3771function RZsetEditParameters(module,field,set)
3772{
3773	RZ.parameters = ''
3774
3775	//----- Append webspace parameter
3776	RZaddUrlParameter( 'webspace=' + RZ.webspace )
3777
3778	/* Was considered for page navigation variables
3779	//----- Template name used to create pageid
3780	if (RZ.pagetemplatename	!= '')
3781		RZaddUrlParameter( 'template=' + RZ.pagetemplatename )
3782	*/
3783
3784	//----- Append module & field
3785	if (module!='')
3786		RZaddUrlParameter( 'module=' + module )	//used by link manager
3787	if (field!='')
3788		RZaddUrlParameter( 'field=' + field )		//future
3789
3790
3791	RZsetParameter(set);	//Append set parameters
3792}
3793/*---------------------------------------------------------------------------
3794(Internal Function) Adds the RZ.set values to the url
3795Called by RZsetEditParameters() & RZcalleditlist()
3796Internal: Update Record Support
3797----------------------------------------------------------------------------*/
3798function RZsetParameter(set)
3799{
3800	RZaddUrlParameter( 'pagetemplateid=' + RZ.pagetemplateid );
3801	RZaddUrlParameter( 'linkedmoduleid=' + RZ.pagemoduleid );
3802	RZaddUrlParameter( 'linkedrecordid=' + RZ.pagerecordid );
3803	//----- Append set parameters
3804	if (set != '')
3805	{
3806		set = set.split('pagerecord._recordid').join( RZ.editrecordid )
3807		RZaddUrlParameter( 'set=' + escape(set) )
3808	}
3809}
3810/*---------------------------------------------------------------------------
3811(Internal Function) Sets recordid parameter used with or w/o link manager.
3812Internal: Update Record Support
3813----------------------------------------------------------------------------*/
3814function RZsetEditRecordParameter(recordid)
3815{
3816	var recordidParameter = '*ERROR*'
3817
3818	if (recordid == 'new')
3819		recordidParameter = '&new'
3820
3821	//----- Calculated value
3822	else if (recordid.length>0 && recordid.substring(recordid.length-1)==';')
3823		recordidParameter = '&recordid=' + eval(recordid)
3824
3825	//----- If rz.fetch returned an error message as text
3826	//		(use alert because it may not be design flaw)
3827	else if (recordid != '' && isNaN(recordid))
3828		alert( 'Revize Button specifies Invalid Record Id: \n' + recordid )
3829
3830	else if (recordid != '')
3831		recordidParameter = '&recordid=' + recordid
3832
3833	else
3834		recordidParameter = ''
3835
3836	return recordidParameter
3837}
3838/*---------------------------------------------------------------------------
3839(Internal Function) Called from above and also from snippet_helper_editform.js
3840before calling RTE.
3841
3842Computed window size just fits 800 X 600 for all options.
3843Create link object if undefined and use default options if undefined.
3844
3845Internal: Link Manager Support
3846----------------------------------------------------------------------------*/
3847function RZsetLinkManagerProperties(linkname,module,field,recordid,set,url)
3848{
3849	//----- Set general edit Url paramters
3850	RZ.message = ''
3851	RZsetEditParameters(module,field,set)
3852
3853	//----- If link object not yet defined, define it
3854	if (typeof RZ.link[linkname] == 'undefined') RZ.link[linkname] = new Object()
3855
3856	//----- Get current options (use default values if undefined)
3857	var options = RZ.link[linkname].options
3858	if (typeof options == 'undefined') options = 'url,template,file'
3859	RZ.link[linkname].options = options
3860
3861	if (typeof RZ.linkoptions != 'undefined' && RZ.linkoptions != '')
3862	RZ.link[linkname].options = RZ.linkoptions
3863
3864	//----- Following properties are used by jsp code and must be passed on url
3865	RZaddUrlParameter( "linkname=" + linkname )
3866	RZsetLinkUrlParameter(linkname,'options')
3867	RZaddUrlParameter( "nexturl=" + RZabsoluteUrl(url) )
3868
3869	//----- Template specfic properties (DW only defines template property)
3870	RZdefaultLinkParameter(linkname,'template')			//blank for all templates
3871	RZdefaultLinkParameter(linkname,'editform')			//template specific editforms
3872	RZdefaultLinkParameter(linkname,'modulelinkfield')	//back link from dependent module
3873
3874	//----- TODO: Following properties are now passed on url (but should NOT)
3875	//		(they are not used by jsp code except to retrieve values for js)
3876	RZdefaultLinkParameter(linkname,'filelocation')		//file manager location (supported by RTE)
3877	RZdefaultLinkParameter(linkname,'fileextension')	//file manager extensions
3878
3879	//----- TODO: Following properties are now passed on url (but probably NOT even used)
3880	RZdefaultLinkParameter(linkname,'imagelocation')	//image manager location
3881	RZdefaultLinkParameter(linkname,'imageextension')	//image manager extensions
3882
3883	//----- Following properties NOT used by jsp code are accessed from the opener window
3884	//		They can be set on RZ.link.<linkname>.<property_below>
3885	RZdefaultLinkOption(linkname,'linkpathname')		//prepended pathname (supported by RTE)
3886	RZdefaultLinkOption(linkname,'linknewsection')		//list of templates that can start new sections
3887
3888	RZdefaultLinkOption(linkname,'linkdisplaydefault')	//default linkdisplay
3889	RZdefaultLinkOption(linkname,'linktemplatedefault')	//default template
3890	RZdefaultLinkOption(linkname,'linkfilenamedefault')	//default path/filename
3891	RZdefaultLinkOption(linkname,'linkautocontinue')	//Auto click Continue button
3892	RZdefaultLinkOption(linkname,'nexturl')				//next editform for all templates
3893	RZdefaultLinkOption(linkname,'set')					//Set passed to dependent module
3894	RZdefaultLinkOption(linkname,'linkparent')			//parent that added link
3895	RZdefaultLinkOption(linkname,'linkmodule')			//list module
3896
3897	//----- Determine link parent (defined by new or edit button - single level menu)
3898	var linkparent = RZ.link[linkname].linkparent
3899	if (linkparent == '')
3900	{
3901		if (RZ.permissions_parent != '')	//this page is surogate parent (e.g. editlist)
3902			linkparent = RZ.permissions_parent
3903		else
3904			linkparent = RZ.page_key
3905	}
3906	RZ.link[linkname].linkparent = linkparent
3907
3908	//----- Convert nexturl to absolute url (some RTE calls have property defined at this time)
3909	var nexturl = RZ.link[linkname].nexturl
3910	if (nexturl != '')
3911		RZ.link[linkname].nexturl = RZabsoluteUrl(nexturl)
3912
3913	//----- Compute link manager window size
3914	var width = 600
3915	var height = 240 		// base height IE or NS (includes target)
3916	var testopt = ',' + options + ','
3917	if (testopt.indexOf(',none,') != -1) height += 25
3918	if (testopt.indexOf(',url,') != -1) height += 40
3919	if (testopt.indexOf(',file,') != -1) height += 45
3920	if (testopt.indexOf(',template,') != -1)
3921	{
3922		height += 220 + 40;		//add 40 for section prompt
3923		if (RZ.isnavigator) height += 25
3924	}
3925
3926	//----- Store computed values in the link object itself
3927	RZ.link[linkname].linkwidth   = width
3928	RZ.link[linkname].linkheight  = height
3929	RZ.link[linkname].linkscroll  = 'yes'
3930
3931	//----- Store link manager url with parameters
3932	RZ.link[linkname].linkurl = '/revize/util/linkmanager_frame.html' + RZ.parameters
3933
3934	//----- Display all link manager properties on trace
3935	RZtrace('Link Manager linkname (' + linkname + ') url parameters',RZ.message)
3936	var msg = ''
3937	for (var i in RZ.link[linkname])
3938		msg += i + '  =  ' + RZ.link[linkname][i] + '\n'
3939	RZtrace('RZsetLinkManagerProperties() linkname (' + linkname + ')',msg)
3940}
3941/*---------------------------------------------------------------------------
3942(Internal Function)Save all link manager information for this link in a new
3943object that is referenced at run time by new and edit buttons.
3944
3945This function is called by the link object to define link properties for use by
3946new and edit buttons.  A separate link object is defined for each linkname so
3947these properties are available when the new or edit button is clicked. The new
3948and edit buttons can then simply supply the linkname to access these properties.
3949
3950See RZTagSupport.java for more information on the link manager calling process.
3951
3952**IMPORTANT**
3953When changing functionality, please update Dreamweaver help file:
3954	RevizePermissionsWorks-Help.htm (contains high level description)
3955
3956Internal: Link Manager / Page Permissions Support
3957----------------------------------------------------------------------------*/
3958function RZlinkmanager( linkname, linkmodule, linkrecordid, linklevel,
3959	                    linkpagekey, linkparent )
3960{
3961	if (typeof linkname == 'undefined') linkname = RZ.linkname
3962	if (typeof linkmodule == 'undefined') linkmodule = ''
3963	if (typeof recordid == 'undefined') recordid = ''
3964	if (typeof linklevel == 'undefined') linklevel = ''
3965	if (typeof linkpagekey == 'undefined') linkpagekey = ''
3966	if (typeof linkparent == 'undefined') linkparent = ''
3967	if (linkparent.indexOf('This is a STANDARD text field:') == 0) linkparent = '';
3968
3969	//----- For multi-level link manager lists...
3970	if (linkmodule != '' && linklevel != '')
3971	{
3972		//----- Save first non-blank linkparent for this level
3973		if (typeof RZ.linkparentnew[linkname] == 'undefined')
3974			RZ.linkparentnew[linkname] = new Object();
3975
3976		if (typeof RZ.linkparentreset[linklevel] == 'undefined')
3977			RZ.linkparentreset[linklevel] = 'reset'
3978
3979		if (typeof RZ.linkparentnew[linkname][linklevel] == 'undefined'
3980		|| RZ.linkparentreset[linklevel] == 'reset')
3981		{
3982			if (linkparent == '') linkparent = RZ.permissions_parent
3983			RZ.linkparentnew[linkname][linklevel] = linkparent
3984			RZ.linkparentreset[linklevel] = ''
3985		}
3986
3987		//----- Indicate new next higher level linkparent can be reset
3988		var nextlevel = RZinteger(linklevel) + 1
3989		RZ.linkparentreset[nextlevel] = 'reset'
3990
3991		//----- Save most recent pagekey (used to get parent for new level button)
3992		RZ.linkpagekey[linklevel] = linkpagekey
3993		if (typeof RZ.linkpagekey[linklevel+1] != 'undefined')
3994			RZ.linkpagekey[linklevel+1] = 'undefined';	//clear lower level value
3995	}
3996
3997	//----- Create link object if not defined to hold module and parent
3998	if (typeof RZ.link[linkname] == 'undefined')
3999	{
4000		RZ.link[linkname] = new Object()
4001		RZ.link[linkname].linkparent = ''
4002		RZ.link[linkname].linkmodule = ''
4003	}
4004
4005	//----- Set linkparent to 1st non-blank parent encountered (used for single level links)
4006	//		When no linkparent is set, the page_key is used when new or edit button clicked.
4007	if (linkparent != '' && RZ.link[linkname].linkparent == '')
4008		RZ.link[linkname].linkparent = linkparent
4009
4010	//----- Save additional link properties
4011	if(RZ.linkname != '')
4012	{
4013
4014		if (RZ.link[linkname].linkmodule == '' && linkmodule != '')
4015			RZ.link[linkname].linkmodule = linkmodule;
4016
4017		RZ.link[RZ.linkname].options = RZ.linkoptions
4018		RZ.link[RZ.linkname].filelocation = RZ.linkfilelocation
4019		RZ.link[RZ.linkname].fileextension = RZ.linkfileextension
4020		RZ.link[RZ.linkname].imagelocation = RZ.linkimagelocation
4021		RZ.link[RZ.linkname].imageextension = RZ.linkimageextension
4022
4023		RZ.link[RZ.linkname].template = RZ.linktemplate
4024		RZ.link[RZ.linkname].editform = RZ.linkeditform
4025		RZ.link[RZ.linkname].modulelinkfield = RZ.linkmodulelinkfield
4026
4027		//----- Properties not passed on url
4028		//		TODO: automatically pick up all options starting with link
4029		RZ.link[RZ.linkname].linkpathname = RZ.linkpathname
4030		RZ.link[RZ.linkname].linknewsection = RZ.linknewsection
4031		RZ.link[RZ.linkname].linkdisplaydefault = RZ.linkdisplaydefault
4032		RZ.link[RZ.linkname].linktemplatedefault = RZ.linktemplatedefault
4033		RZ.link[RZ.linkname].linkfilenamedefault = RZ.linkfilenamedefault
4034		RZ.link[RZ.linkname].linkautocontinue = RZ.linkautocontinue
4035	}
4036
4037	//----- clear RZ.* action arguments
4038	RZactionReset();
4039}
4040/*---------------------------------------------------------------------------
4041(Internal Function) Call RZdefaultLinkOption then add to RZ.parameters
4042Internal: Link Manager Support
4043----------------------------------------------------------------------------*/
4044function RZdefaultLinkParameter(linkname,property)
4045{
4046	RZdefaultLinkOption(linkname,property)
4047	RZsetLinkUrlParameter(linkname,property)
4048}
4049/*---------------------------------------------------------------------------
4050(Internal Function) If property is undefined, set to blank
4051Internal: Link Manager Support
4052----------------------------------------------------------------------------*/
4053function RZdefaultLinkOption(linkname,property)
4054{
4055	if (typeof RZ.link[linkname][property] == 'undefined')
4056		RZ.link[linkname][property] = ''
4057
4058	//RZtrace('RZdefaultLinkOption('+linkname+'):' + property
4059	//       + '<br>-->' +(RZ.link[linkname][property])+ '<--')
4060}
4061/*---------------------------------------------------------------------------
4062(Internal Function) Build link manager url parameters using link properties
4063presumably defined elsewhere on the page if property is defined and not blank.
4064
4065Internal: Link Manager Support
4066----------------------------------------------------------------------------*/
4067function RZsetLinkUrlParameter(linkname,property)
4068{
4069	if (typeof RZ.link[linkname][property] != 'undefined')
4070	{
4071		var value = RZ.link[linkname][property]
4072		if (value != '')
4073			RZaddUrlParameter( 'link' + property + '=' + value )
4074	}
4075}
4076/*---------------------------------------------------------------------------
4077Adds jsp parameter to url
4078* parameter appended RZ.parameters with preceeding ? or & character
4079* parameter appended to RZ.message for output by RZtrace()
4080
4081Parameters:
4082	parameter-	url parameter of the form key = value
4083----------------------------------------------------------------------------*/
4084function RZaddUrlParameter(parameter)
4085{
4086	//----- Build url parameter
4087	if (RZ.parameters.indexOf('?') == -1)
4088		RZ.parameters += '?' + parameter
4089	else
4090		RZ.parameters += '&' + parameter
4091
4092	//----- Build trace message
4093	RZ.message += unescape(parameter) + '\n'
4094}
4095
4096/* Same as: RZback (retained for backward compatibility) */
4097function RZpriorPage(returnUrlKey) { RZback(returnUrlKey) }
4098/*-------------------------------------------------------------------------
4099  Return to calling page (normally called by cancel button)
4100
4101  If popupcall, close window and refresh if not an editform
4102
4103  If returnUrlKey ends with a semicolon, assume it is an expression for url
4104
4105  Otherwise, return to PRIOR PAGE using the following steps
4106  * If URL defined in cookie, use it (returnUrlKey specifies cookie name)
4107  * If not edit list page, use history
4108  * If RZ.page.home is not blank, use it
4109  * Make trace entry and stay on current page
4110
4111  Parameters:
4112  returnUrlKey-	if specified, one of the following:
4113                1) expression containing url of page to get control
4114                2) if expression, must end with semicolon
4115                3) Cookie name containing calling page url
4116  win-			Optional specifies the current window (default is window)
4117  Returns:
4118  There is currently no value returned
4119-------------------------------------------------------------------------*/
4120function RZback(returnUrlKey,win)
4121{
4122	if (typeof win == 'undefined') win = window;
4123	if (!returnUrlKey)
4124		returnUrlKey = (RZ.pagetype == 'editlist' ? 'RZeditListReturnUrl' : 'RZeditFormReturnUrl');
4125
4126	//----- If opener and access to opener
4127	if ( RZisPopupCall(win) )
4128	{
4129		//----- Added for LinkManager RTE interface (but never refresh editform)
4130		if(RZ.parent.opener.RZ != 'undefined'
4131		&& RZ.parent.opener.RZ != null
4132		&& RZ.parent.opener.RZ.pagetype != 'editform')
4133			win.opener.location.reload(true);
4134		win.close()
4135		return;
4136	}
4137
4138	//----- Not a popup call
4139	var returnUrl = ''
4140	if (RZright(returnUrlKey,1) == ';')		//url passed as variable / equation
4141		returnUrl = eval( returnUrlKey )
4142	else									//url read from cookie
4143	{
4144		returnUrl = RZgetCookieValue(returnUrlKey)
4145		if (returnUrl != "")
4146		{	// if cookie defined
4147			RZsetCookieValue(returnUrlKey,"")
4148		}else
4149		{	// when cookie not defined
4150			if (RZ.pagetype == 'editform')
4151			{
4152				returnUrl = ''
4153				history.go(-1); // use history if not edit list
4154			}
4155			else
4156			{
4157				returnUrl = RZ.page.home // use home if edit list
4158			}
4159		}
4160	}
4161
4162	if (returnUrl != null && returnUrl != '')
4163		RZ.parent.location = returnUrl
4164	else
4165		RZtrace('snipper_helper: RZback('+returnUrlKey+')',
4166				'No Prior URL could be determined')
4167}
4168/*--------------------------------------------------------------------------
4169(Internal Function) Determine if this page was called as a popup.
4170
4171Internal: Used by Save & Cancel functions to return to calling window.
4172
4173Returns: true if opener with RZ.pagetype variable defined; otherwise false
4174--------------------------------------------------------------------------*/
4175function RZisPopupCall(win, isStrict)
4176{
4177	if (typeof win == 'undefined') win = window
4178
4179	if (win.parent.opener
4180	&& RZwinaccess(win.parent.opener)
4181	&& typeof win.parent.opener != 'undefined'
4182	&& typeof win.parent.opener != 'undefined'
4183	&& typeof win.parent.opener.RZ != 'undefined'	//opener is a Revize page
4184	&& win.parent.opener.RZ != null
4185	&& typeof RZ.parent.opener.RZ.pagetype != 'undefined'
4186	&& typeof RZ.parent.opener.RZ.editWindow != 'undefined'
4187	&& win.parent.opener.RZ.editWindow == win.parent
4188	&& RZisPopupCallStrict())
4189	{
4190		return true;
4191	}
4192	//----- If opened from workflow task window
4193	//		TODO: probably should always assume popup if opener exists but too risky w/o
4194	//		more analysis and serious regression testing.
4195	else if (win.parent.name == 'Revize_Edit_Record' && typeof win.opener != 'undefined')
4196		return true;
4197
4198	// DCO 10-20-2014:
4199	// Below code can cause js error in RZback() because this is the wrong place to test
4200	// for callback function in RZnextsavereturn; RZsave() should test. Moot point when
4201	// RZ.callback used because RZ.nextsavereturn never contains paraenthesis and RZsave()
4202	// does not rely solely on isPopup() to post save to itself.
4203
4204	//----- If callback function specified after save
4205	else if(RZ.nextsavereturn
4206	&& RZ.nextsavereturn.indexOf('(') > 0 && RZ.nextsavereturn.indexOf(')') > 0)
4207		return true;
4208
4209	else
4210		return false;
4211	//______________________________________________________________________
4212	/**
4213	 *	(Internal function) originally added for email notify
4214	 *
4215	 *	Check if opener and referrer pathnames match -- Prevents editform
4216	 *	from closing popup editlist when editform is not called as popup.
4217	 *
4218	 *	Probably always valid test but as safety, only checks if isStrict
4219	 *	specified and EZ feature active otherwise returns true.
4220	 */
4221	function RZisPopupCallStrict()
4222	{
4223		if (!isStrict || !EZ.isFeature("EZ")) return true;
4224		if (window.dialogArguments) return true;
4225
4226		return RZgetFileInfo(location.href).pathfilename != RZgetcookie('RZnotPopup',RZ.webspace)
4227	}
4228}
4229/*---------------------------------------------------------------------------
4230Following function is called by the DELETE ITEM button
4231Deleted specified recordid after prompting
4232----------------------------------------------------------------------------*/
4233/* Same as RZdelete (retained for backward compatibility) */
4234function RZrecordDelete( recordid, module ) { RZdelete( recordid, module ) }
4235/**
4236 *	DCO 03-07-2012: Can now be called with single object argument whose
4237 *					element names match RZ.??? names passed to RZaction()
4238 *	Example call:
4239 *		RZdelete( {recordid: recordid, module: module, ...} );
4240 *
4241 *	DO NOT add new named arguments; below retained for backward compatibility.
4242 **/
4243
4244/**
4245 * Add Event Listener to delete
4246 */
4247var selectedBtn;
4248document.addEventListener("DOMContentLoaded", function() {
4249	var deleteBtns = document.querySelectorAll('a[href*="javascript:RZdelete"]');
4250	for(var i = 0, len = deleteBtns.length; i < len; i++){
4251		deleteBtns[i].addEventListener('click', function(e){
4252			selectedBtn = e.target.parentNode;
4253		}, false);
4254	}
4255});
4256
4257
4258function RZdelete(recordid, module, nexturl, win)
4259{
4260	//----- Internal work variables
4261	var msg = '';
4262
4263	//----- If first argument is an object, it contains all input arguments as elements.
4264	//		Local variable names & args element names match RZ.??? passed to RZaction()
4265	var args = recordid;	//1st argument
4266
4267	// If first argument not object, create args object containing legacy named arguments
4268	if (typeof(args) != 'object')
4269	{
4270		args = {};
4271		args.recordid = recordid ? recordid : '';
4272		args.module   = module   ? module   : '';
4273		args.nexturl  = nexturl  ? nexturl  : '';
4274		args.win      = win      ? win      : '';
4275	}
4276
4277	//----- Initialize legacy local variables originally passed as named arguments
4278	recordid = args.recordid ? args.recordid : '';
4279	module   = args.module   ? args.module   : '';
4280	win      = args.win      ? args.win      : window;
4281	nexturl  = args.nexturl  ? args.nexturl  : win.location.href;
4282
4283	//----- New input arguments never passed as named arguments
4284	var samplearg = args.samplearg ? args.samplearg : '';	//default '' is in the example
4285
4286	//----- Processing...
4287	RZ.message = "WebSpace: " + RZ.webspace + "\n"
4288			 + "Module: " + module + "\n"
4289			 + "Record Id: (" + recordid + ")\n"
4290			 + "Redirect Url: " + nexturl + "\n"
4291	RZtrace( "Delete Item Clicked", RZ.message );
4292
4293	if (isNaN(recordid))
4294	{
4295		win.alert( 'Invalid Record Id: ' + recordid )
4296		return void(0)
4297	}
4298	else if (recordid=='')
4299	{
4300		win.alert( 'Record Not Specified (Id is Blank)' )
4301		return void(0)
4302	}
4303
4304	var deletemsg='Are you sure you want to delete this link?\n\n'
4305	+'Keep in mind that if this link or page is not being referenced from any other page from your website'
4306	+' then DELETE will physically delete the page record from the database and there would be no way to restore'
4307	+' it if you change your mind. You want to proceed?';
4308	//if (!win.confirm("Ok to Delete This Item?")) return
4309
4310	if(module !== 'links') {
4311		deletemsg = 'Are you sure you want to delete this item?\n\n This action is not reversible.';
4312	}
4313
4314	if(RZ.pagetemplatename === 'document_center'){
4315		var delName = selectedBtn.parentNode.parentNode.querySelector('.docs-toggle');
4316		if(delName != null){
4317			var delChild = delName.firstChild;
4318			var delTexts = [];
4319
4320			while(delChild){
4321				if(delChild.nodeType == 3){
4322					delTexts.push(delChild.data);
4323				}
4324				delChild = delChild.nextSibling;
4325			}
4326
4327			var delText = delTexts.join("");
4328			var delPromp = win.prompt("Are you sure you want to delete this whole category?"
4329			+"\nPlease keep in mind that, if you delete this category, ALL THE DOCUMENTS UNDER THIS CATEGORY WILL BE PERMANENTLY DELEETED AND CAN NOT BE RESTORED BY REVIZE STAFF."
4330			+"\n\nIf you are sure and still want to delete the '"+ delText +"' category, please type in the following in all caps:"
4331			+"\n"+delText.toUpperCase());
4332
4333			if(delPromp !== delText.toUpperCase()){
4334				alert('You entered "'+delPromp+'" while the system expected "'+delText.toUpperCase()+'".\nThe record will NOT be deleted.');
4335				return;
4336			}
4337		} else {
4338			if (!win.confirm(deletemsg)) return
4339		}
4340	} else if(RZ.pagetemplatename === 'agenda_list' || RZ.pagetemplatename === 'agendalist'){
4341		if (!win.confirm(deletemsg)) return
4342	} else {
4343		if (!win.confirm(deletemsg)) return
4344	}
4345
4346	//----- Call Developer defined ondelete handler and quit if it returns false
4347	if (typeof win.ondelete == 'function')
4348	{
4349		// update args with default values and pass to ondelete handler
4350		// returns false to cancel delete, or object with below values;
4351		var returnValues = win.ondelete(args);
4352		if (typeof returnValues == 'undefined' || returnValues == false)
4353		{
4354			win.status = 'Delete Canceled'
4355			return void(0)
4356		}
4357		else if (typeof returnValues == 'object')
4358		{
4359			if (typeof returnValues.nexturl != 'undefined')
4360				nexturl = returnValues.nexturl
4361		}
4362
4363	}
4364
4365	if (EZ.isFeature("EZ"))
4366		RZsetcookie('RZlastedit', (RZ.pagetype + ':delete:' + module + ':' +recordid), RZ.webspace);
4367
4368	// Use the XML translator servlet instead of the old XML form method.
4369	nexturl = RZgetEditPageUrl(nexturl);
4370	var deleteUrl =	"/revize/HTTPTranslatorServlet" +
4371					"?resourcetype=record" +
4372					"&action=delete" +
4373					"&webspace=" + RZ.webspace +
4374					"&softdelete=true" +
4375					"&id=" + recordid +
4376					"&pagetemplateid=" + RZ.pagetemplateid +
4377					"&linkedmoduleid=" + RZ.linkedmoduleid +
4378					"&linkedrecordid=" + RZ.linkedrecordid +
4379					"&modulename=" + module +
4380					"&pagekey=" + RZ.page_key +
4381					"&redirect=" + escape(RZabsoluteUrl(nexturl));
4382	RZtrace( "Delete Item Request", deleteUrl );
4383	RZactionReset();
4384	win.location = deleteUrl;
4385
4386
4387}
4388/*---------------------------------------------------------------------------
4389Bring up page permissions window.
4390
4391The options argument can contain one of the following:
4392	nexturl, linkname, module, object
4393
4394The AdminPanel uses adminpanel option to specify additional url parameters.
4395----------------------------------------------------------------------------*/
4396function RZpermissions(set,options)
4397{
4398	var pos;
4399	if (typeof set == 'object') set = '';	//called from admin panel
4400	if (typeof set == 'undefined') set = ''
4401	if (typeof options == 'undefined') options = ''
4402
4403	var adminpanel = RZgetoption(options, 'adminpanel');
4404	var linkname = RZgetoption(options, 'linkname');
4405	var module = RZgetoption(options, 'module');
4406	var nexturl = RZgetoption(options, 'nexturl');
4407	if (nexturl == '')
4408	{
4409		var fileInfo = RZgetfileinfo('/revize/util/permissions-editform.jsp')
4410		nexturl = RZbuildurl(fileInfo)
4411	}
4412
4413	RZ.message = ''
4414	RZ.parameters = nexturl
4415	RZaddUrlParameter( 'webspace=' + RZ.webspace )
4416	RZaddUrlParameter( 'page_key=' + RZ.page_key )
4417	RZaddUrlParameter( 'parent_key=' + RZ.parent_key  )
4418	if(RZ.workflowmodule != '' && RZ.workflowmodule != undefined)
4419		RZaddUrlParameter('workflowmodule=' + RZ.workflowmodule);
4420	if (adminpanel)
4421		RZaddUrlParameter(adminpanel)
4422
4423	if (set == '')
4424	{
4425		set = RZ.permissions_module + '.page_key=' + RZ.page_key
4426		if (linkname != '')
4427			set += linkname
4428		else if (module != '')
4429			set += module
4430	}
4431	RZaddUrlParameter('set='+escape(set))
4432
4433	RZtrace('Page Permissions Call',RZ.message)
4434	RZ.editWindow = RZpopupUrl( 'EditWindow', RZ.parameters, 600, 500, 'yes')
4435}
4436/*---------------------------------------------------------------------------------------
4437Find all tagName elements with className
4438---------------------------------------------------------------------------------------*/
4439function RZgetTagsByClassName(tagName,className)
4440{
4441	var tags = [];
4442	var elements = document.getElementsByTagName(tagName);
4443	if (elements.length)
4444		for (var i=0;i<elements.length;i++)
4445			if ( (elements[i].className+' ').indexOf(className+' ') != -1)
4446				tags.push(elements[i]);
4447	return tags;
4448}
4449/*---------------------------------------------------*/
4450/*BOOKMARK ----- String minupulation functions -----*/
4451/*-------------------------------------------------*/
4452/*---------------------------------------------------------------------------------------
4453Return number occurances of chars (default char is dash)
4454---------------------------------------------------------------------------------------*/
4455function RZdup(number,char)
4456{
4457	var value = ''
4458	if (!char) char = '-';
4459	for (var i=0;i<number;i++)
4460		value += char;
4461	return value;
4462}
4463/*-----------------------------------------------------------------------------------------------
4464Append th, st, nd or rd to number specified by n.
4465Credit: http://uk.answers.yahoo.com/question/index?qid=20100902055222AAr3Bt6
4466-----------------------------------------------------------------------------------------------*/
4467function RZnth(n)
4468{
4469	n=n+'';
4470	if (!n) return 0;
4471	var l=n.length, r=parseInt(n.substring(l-2,l)), i = n % 10;
4472	var suffix = ((r < 11 || r > 19) && (i < 4)) ? ['th','st','nd','rd'][i] : 'th';
4473	return n + suffix;
4474}
4475/*-----------------------------------------------------------------------------
4476Return "s" if count > 1 otherwise return empty string
4477-----------------------------------------------------------------------------*/
4478function RZs(count)
4479{
4480		if (count.constructor == Array)
4481			count = count.length;
4482		else if (typeof(count) == 'string')
4483			count = count.split(',').length;
4484		else if (isNaN(count))
4485			count = 0;
4486
4487	if (count != 1)
4488			return 's';
4489	else
4490	return '';
4491}
4492/*------------------------------------------------------------------------------
4493Remove any leading and ending blank spaces from string (trim)
4494
4495Parameters:
4496	tmpStr - Input string
4497
4498Returns:
4499	String with leading and trailing spaces removed
4500------------------------------------------------------------------------------*/
4501function RZtrim(tmpStr)
4502{
4503	if (typeof(tmpStr) == 'undefined' || tmpStr == null || tmpStr == '')
4504		return tmpStr;
4505
4506	//----- need to strip \t besides ' '
4507	//while(tmpStr.substring(0,1) == ' ')
4508	while (/^\s/.test(tmpStr))
4509		tmpStr = tmpStr.substring(1, tmpStr.length);
4510
4511	//while(tmpStr.substring(tmpStr.length-1,tmpStr.length) == ' ')
4512	while (/\s$/.test(tmpStr))
4513		tmpStr = tmpStr.substring(0, tmpStr.length - 1);
4514
4515	return tmpStr;
4516}
4517/*------------------------------------------------------------------------------
4518RZreplace(inStr, fromString, toString)
4519
4520Replace all occurances of fromString with toString
4521
4522Created before javascript string.replace was available
4523(retain RZreplaceAll & RZreplacesubstring for backward compatibility)
4524
4525Parameters:
4526	inStr - Input String
4527	fromString - String to replace
4528	toString - Replacement String
4529
4530Returns:
4531	String with replacements
4532------------------------------------------------------------------------------*/
4533function RZreplace( inStr, fromString, toString )
4534{ return RZreplacesubstring( inStr, fromString, toString ) }
4535function RZreplaceAll( inStr, fromString, toString )
4536{ return RZreplacesubstring( inStr, fromString, toString ) }
4537function RZreplacesubstring( inStr, fromString, toString )
4538{
4539	var pos = 0
4540	if (inStr == null
4541	|| typeof inStr.length == 'undefined' //true or false
4542	|| inStr.length == 0) return '';
4543
4544	var fromLen = fromString.length
4545	if (fromLen == 0) return inStr
4546
4547	while (true)
4548	{
4549		pos = inStr.indexOf(fromString,pos)
4550		if (pos == -1) break
4551		inStr = RZsubstring( inStr, 0, pos )
4552		      + toString
4553		      + RZsubstring( inStr, pos + fromLen )
4554		pos += toString.length
4555	}
4556	return inStr
4557}
4558/*------------------------------------------------------------------------------
4559Subsitute for substring method (does not produce javascript errors)
4560
4561A null or empty input string returns empty string
4562
4563Start and end positions outside boundries intrepreted as follows:
4564
4565	if end position not specified or greater than string length,
4566	adjust to input string length
4567
4568	if end position before 1st character,
4569	return empty string
4570
4571	if start position greater than ending position,
4572	return empty string
4573
4574	if start position less than 0,
4575	assume 0
4576
4577Parameters:
4578----------
4579	str-		Input string
4580	startpos-	Starting position
4581	endpos-		Ending position (optional)
4582
4583Returns:
4584	substring as described above.
4585
4586------------------------------------------------------------------------------*/
4587function RZsubstring(str, startpos, endpos)
4588{
4589	if (typeof endpos == 'undefined') endpos = str.length + 1
4590
4591	//----- Validate input string
4592	if (str == null || str.length == 0)	//if null or empty string
4593		return "";						//...return empty string
4594
4595	//----- Validate end position
4596	if (endpos > str.length )			//greater than string length
4597		endpos = str.length;			//...set to length
4598
4599	else if( endpos <= 0 )				//if end position before 1st character
4600		return "";						//...return empty string
4601
4602	//----- Validate start position
4603	if( startpos >= endpos )  			//if start position greater than ending position
4604		return "";						//...return empty string
4605
4606	else if (startpos < 0) 				//if start position less than 0
4607		startpos = 0;					//...assume 0
4608
4609	//----- Return the substring
4610	return str.substring(startpos,endpos);
4611}
4612/*---------------------------------------------------------------------------
4613returns rightmost number of characters specified
4614
4615Parameters:
4616	str - Input String
4617	noChars - number of rightmost characters desired
4618
4619Example:
4620	* right("1234",2) returns "34"
4621    * right("1234",0) returns ""
4622    * right("0",4) returns "0"
4623
4624Returns:
4625	Rightmost substring possible; does not throw exception if string too short
4626----------------------------------------------------------------------------*/
4627function RZright( str, noChars )
4628{
4629	if (!str) return '';
4630	var len = str.length;
4631	if (len == 0) return "";
4632
4633	if (noChars > len) noChars = len;
4634	return str.substring(len-noChars);
4635}
4636/*---------------------------------------------------------------------------------------------
4637Converts number to the nearest integer
46380 is returned if not a valid number unless a defaultValue is supplied
4639
4640Parameters:
4641	number - string or number to be converted to an integer (whole number)
4642	defaultValue - number returned in number parameter is not a valid number
4643
4644Returns:
4645	Nearest whole number of input number; if input number or string is undefined or not
4646	a number, the defaultValue is returned
4647---------------------------------------------------------------------------------------------*/
4648function RZinteger(number,defaultValue)
4649{
4650	if (typeof defaultValue == 'undefined') defaultValue = 0
4651
4652	if (isNaN(number))
4653		return defaultValue
4654
4655	return parseInt( parseFloat(number)+.5 )	//convert number to number then round up
4656}
4657
4658/* Same as RZcheckoptions (retained for backward compatibility) */
4659function RZcheckOptions( pOptions, pChoices )
4660{ return RZcheckoptions( pOptions, pChoices ) }
4661/*---------------------------------------------------------------------------
4662Look for specific option choice(s) in the options string.  Both options and
4663choices use commas to seperate multiple individual options.
4664
4665Parameters:
4666        pOptions - Caller supplied options (e.g. "filter,editsingle,alt")
4667        pChoices - specific option choices to look for (e.g. alt,url,image)
4668
4669Returns:
4670        True if at least one choice is contained in options
4671        False if none of the choice(s) are found
4672
4673Example: RZcheckOptions('cristy,pam,sandy','cristy') returns true
4674----------------------------------------------------------------------------*/
4675function RZcheckoptions( optionsArg, pChoices )
4676{
4677	if (typeof(optionsArg) == 'object' && typeof(optionsArg.length) != 'undefined')
4678		pOptions = optionsArg.join(',');
4679	else
4680		pOptions = optionsArg
4681
4682	if (pOptions == null || pChoices == null
4683	|| typeof pOptions == 'undefined' || typeof  pChoices == 'undefined')
4684		return false;
4685
4686	var str, pos;
4687	var inputSep = pOptions.indexOf('|') != -1 ? '|' : ',';
4688	var inputOpts = inputSep + pOptions + inputSep;
4689	inputOpts = inputOpts.toLowerCase();
4690
4691	var searchSep = pChoices.indexOf('|') != -1 ? '|' : ',';
4692	var searchOpts = pChoices.toLowerCase();
4693
4694	//----- For each desired choice ...
4695	while ( !searchOpts == "" )
4696	{
4697		str = searchOpts;
4698		pos = str.indexOf(searchSep);
4699		if (pos == 0)
4700		{
4701			searchOpts = str.substring(pos+1);	//strip comma
4702			continue;
4703		} else if (pos > 0)
4704		{
4705			searchOpts = str.substring(pos+1);
4706			str = str.substring(0,pos);
4707		} else
4708		{// no commaa
4709			searchOpts = "";
4710		}
4711		// check for this choice
4712		if (inputOpts.indexOf(inputSep + str + inputSep) >= 0) return true;
4713		if (inputOpts.indexOf(inputSep + str + "=") >= 0) return true;
4714	}
4715	return false;
4716}
4717/*---------------------------------------------------------------------------
4718Looks for a key=value in the options string and returns the value portion.
4719(clone of getValue in RZTabSupport)
4720
4721Parameters:
4722	options - String searched for key=value
4723	key - Key to find in options string
4724
4725Returns:
4726	Associated value when key is found, otherwise returns blank string
4727----------------------------------------------------------------------------*/
4728function RZcheckoptionvalue(pOptions,pKey)
4729{ return RZgetoption(pOptions,pKey) }
4730
4731function RZgetKeyValue(pOptions,pKey)
4732{ return RZgetoption(pOptions,pKey) }
4733
4734function RZgetoptionvalue(pOptions,pKey)
4735{ return RZgetoption(pOptions,pKey) }
4736
4737function RZgetoption(pOptions, pKey, defaultValue)
4738{
4739	var pos, str, keyEqual;
4740	if (!pOptions) pOptions = '';
4741	if (typeof defaultValue == 'undefined') defaultValue = '';
4742
4743	//----- Search for key=
4744	keyEqual = pKey + "=";
4745	str = "," + pOptions;
4746	pos = str.toLowerCase().indexOf( keyEqual.toLowerCase() );
4747
4748	if (pos == -1) 	// key not found
4749		str = defaultValue;
4750	else
4751	{
4752		//----- Keep everything after = up to ,
4753		str = pOptions.substring(pos + keyEqual.length - 1);
4754		pos = str.indexOf(",");
4755		if (pos >= 0) str = str.substring( 0, pos );	// value
4756	}
4757	//----- For backward compatibility: only map to true or false
4758	//		if defaultValue specified as boolean type
4759	if (typeof defaultValue == 'boolean')
4760		str = RZistrue(str)
4761	return str;
4762}
4763/*---------------------------------------------------------------------------
4764Return following as false: 'off', 'no', 'false', false, NaN, null, undefined
4765otherwise any other true value as true
4766----------------------------------------------------------------------------*/
4767function RZistrue(str)
4768{
4769	if (str == 0 || str == false
4770	|| str === 'off' || str === 'no' || str === 'false')
4771		str = false;
4772	else
4773		str = true;
4774	return str;
4775}
4776/*---------------------------------------------------------------------------
4777Call Next URL (popup or forward link)
4778----------------------------------------------------------------------------*/
4779function RZcallNextUrl( name,url, width,height,scroll)
4780{
4781	if ( RZpopupUrl(name,url, width,height,scroll) == null )
4782	{
4783		RZtrace("Calling Next URL Form", "URL: " + url )
4784		document.location = url
4785	}
4786}
4787/*---------------------------------------------------------------------------
4788RZeditor(): See RZeditorsetup in snippet_helper_rte.
4789Stub kept here for backward compatibility and warning message.
4790----------------------------------------------------------------------------*/
4791function RZeditor()
4792{
4793	if( RZ.pagetype == 'editform' )
4794		RZeditorsetup()
4795	else
4796		RZalert('Rich Text Editor Must be Opened on Form Page')
4797}
4798/*---------------------------------------------------------------------------
4799Set Link Property value in link object passed to RTE (NOT yet used or tested)
4800Might be useful on edit forms to set link manager properties.
4801----------------------------------------------------------------------------*/
4802function RZsetLinkProperty( linkObj, property )
4803{
4804	if (typeof RZ.link[linkname] != 'object')
4805		if (typeof RZ.link[property] == 'undefined')
4806			linkObj[property] = ''
4807		else
4808			linkObj[property] = RZ[property]
4809}
4810/*---------------------------------------------------------------------------
4811Append key=value to end of set if key not already in set and value not blank.
4812
4813Optional argument options argument
4814	if not an object and true, replace existing key with specified value.
4815	if object then
4816		options.replace contains replaceFlag true to override a prior value
4817		options.update set true if value changed (replaceFlag must be true)
4818
4819Returns true if prior value for key was changed.
4820----------------------------------------------------------------------------*/
4821function RZaddset(key, value, options)
4822{
4823	var replaceFlag = false;
4824	if (typeof options == 'object')
4825		replaceFlag = options.replace;
4826	else if (options)
4827		replaceFlag = options;
4828
4829    // will property be updated (i.e. over-ridden)
4830	var status = false;			//default return status
4831	if (typeof value == 'undefined' || value == '') return status;
4832
4833	var setCheck = ','+ RZ.set;
4834	var start = setCheck.indexOf(','+key);
4835	if (start == -1)
4836	{
4837		if (RZ.set != '') RZ.set += ','
4838		RZ.set += key + '=' + value;
4839	}
4840	else if (replaceFlag)
4841	{
4842		var end = RZ.set.indexOf(',',start);
4843		if (end == -1) end = RZ.set.length;
4844		var oldStr = RZ.set.substring(start,end);
4845		var newStr = key + '=' + value;
4846		if (oldStr != newStr)  status = true;
4847		RZ.set = RZreplace( RZ.set, oldStr , newStr );
4848	}
4849
4850	if (typeof options == 'object')
4851	 	options.update = (options.update || status);
4852
4853	return status;
4854}
4855/*---------------------------------------------------------------------------
4856Set or update RZ property
4857	options.replace contains replaceFlag true to override a prior value
4858	options.update set true if value changed (replaceFlag must be true)
4859----------------------------------------------------------------------------*/
4860function RZupdate(key,value,options)
4861{
4862	if (!options.replace && RZ[key] != '') return;
4863	if (!value == 'undefined' || value == '') return;
4864
4865    // will property be updated (i.e. over-ridden)
4866	if (RZ[key] != '' && RZ[key] != value)
4867		options.update = true;
4868
4869	RZ[key] = value;
4870}
4871/*---------------------------------------------------------------------------
4872Set or update form property (probably won't work for Firefox).
4873	options.replace contains replaceFlag true to override a prior value
4874	options.update set true if value changed (replaceFlag must be true)
4875----------------------------------------------------------------------------*/
4876function RZupdateFormProperty(field,key,value,options)
4877{
4878	if (!options.replace && typeof field[key] != 'undefined') return;
4879    if (!field || typeof value == 'undefined') return;
4880
4881    if (typeof value == 'string' && value == '')
4882    	return;
4883
4884    else if (typeof value == 'object')
4885    {
4886		if (typeof value.length == 'undefined'
4887		|| value.length < 1
4888		|| value[0] == '')
4889    		return;
4890	}
4891
4892    // will property be updated (i.e. over-ridden)
4893    if (typeof field[key] != 'undefined' && field[key] != '' && field[key] != value)
4894		options.update = true;
4895
4896    field[key] = value;
4897}
4898/*-----------------------------------------------------------------------------
4899get innerHTML of el with leading and trailing spaces and &nbsp; removed.
4900return blank if el not valid element or id of valid element or innerHTML is not
4901valid element property.
4902-----------------------------------------------------------------------------*/
4903function RZgetInnerHTML(el)
4904{
4905	if (typeof el == 'string')
4906		el = document.getElementById(el);
4907
4908	var html = '';
4909	if (el && typeof(el.innerHTML) != 'undefined')
4910	{
4911		html = el.innerHTML
4912		html = html.toString();
4913		html = html.replace(/^(<br[^>]*>)*([\s\S]*?)(<br[^>]*>)*$/, '$2');
4914		html = html.replace(/^(\s|&nbsp;)*([\s\S]*?)(\s|&nbsp;)*$/, '$2');
4915	}
4916	return html;
4917}
4918/*-----------------------------------------------------------------------------
4919set innerHTML if el is valid element or id of valid element and innerHTML is
4920valid element property.
4921-----------------------------------------------------------------------------*/
4922function RZsetInnerHTML(id,html,doc)
4923{
4924	var el = id;
4925	if (!doc) doc = document;
4926	if (typeof el == 'string')
4927		el = doc.getElementById(id);
4928
4929	if (el && typeof(el.innerHTML) != 'undefined')
4930	{
4931		el.innerHTML = html.toString().replace(/\n/g,'<br>');
4932		return true;
4933	}
4934	//RZwarn('id=' + id + ' html element NOT found','level=info');
4935	return false;
4936}
4937/*---------------------------------------------------------------------------
4938Open Trace Window and Display Message
4939DCO 10-20-2014: Save trace for admin panel if RZ.trace not enabled
4940----------------------------------------------------------------------------*/
4941function RZtrace(heading,text)
4942{
4943	//console.log({TRACE:heading, message:text})
4944	if (!RZ.trace && !RZtrace.show) return
4945	if (!text) text = ''
4946
4947	text = text.toString();
4948	text = text.split('--').join('\n')
4949
4950	var MSIE = true;
4951	if (navigator.appVersion.indexOf('MSIE') == -1) MSIE = false;
4952
4953	//----- Always open using browser specific options
4954	//		(if already open, it reconnects to existing window)
4955	while (true)
4956	{
4957		if(!MSIE) //Navigator
4958		{
4959			RZ.tracewin = window.open('', 'RevizeTrace',
4960			'width=420,height=580,location=no,menubar=no,resizable=yes,screenX='
4961			+ (screen.availWidth-430)
4962			+ ',screenY=20,directories=no,status=no,scrollbars=yes');
4963		}
4964		else  //IE
4965		{
4966			RZ.tracewin = window.open('', 'RevizeTrace',
4967			'width=420,height=580,location=no,menubar=no,resizable=yes,left='
4968			+ (screen.availWidth-430)
4969			+ ',top=20,directories=no,status=no,scrollbars=yes');
4970		}
4971		//----- Close trace window if no access and open again
4972		if (MSIE && !RZwinaccess(RZ.tracewin))
4973			RZ.tracewin.close()
4974		else
4975			break
4976	}
4977
4978	//----- Convert special characters
4979	text = text.split('<').join('&lt;');
4980	text = text.split('>').join('&gt;');
4981
4982	//----- Display message.
4983	if (heading != '')
4984		RZ.tracewin.document.writeln(
4985			'</pre>',
4986			'<html><title>Trace</title><body>\n',
4987			'<b>',heading,'</b><br>\n',
4988			'<font size="-2" face="Arial">',location.href,'</font>\n',
4989			'<pre>\n',
4990			text)
4991	else if (text != '')
4992		RZ.tracewin.document.writeln( text )
4993	else
4994		RZ.tracewin.document.writeln( '</pre>' )
4995
4996	//----- Give focus, if trace window already open and accessible
4997	if (!MSIE || RZwinaccess(RZ.tracewin)) RZ.tracewin.scrollBy(0,600)
4998}
4999
5000/*---------------------------------------------------------------------------
5001POPUP EDITOR CAN NO LONGER BE CALLED FROM PUBLISHED PAGES
5002
5003***** Editor Support Code *****
5004
5005Open Html Editor in popup window
5006If specified field exists in XMLForm, use that value.
5007Otherwise Revize editor will read and store data from content database.
5008----------------------------------------------------------------------------*/
5009function RZcallEditor( moduleName, fieldName, width, height, options, recordid )
5010{
5011	if (typeof moduleName == 'undefined') moduleName = '';
5012	if (typeof fieldName == 'undefined') fieldName = '';
5013	if (typeof width == 'undefined' || width=='' ) width = '600';
5014	if (typeof height == 'undefined' || height=='') height = '400';
5015	if (typeof options == 'undefined') options = '';
5016	if (typeof recordid == 'undefined') recordid = '';
5017
5018	//----- Make sure field and image elements are supplied
5019	var msg = '';
5020	var useDatabase = false;
5021	if (moduleName == '')
5022		msg = "Module Name Not Specified"
5023	else
5024	{
5025		if (fieldName == '')
5026			msg = "Editable Field Name Not Specified"
5027		else
5028		{
5029		if (typeof document.XMLForm == 'undefined')
5030			useDatabase = true;
5031		else
5032			if (typeof document.XMLForm[fieldName] == 'undefined')
5033			useDatabase = true;
5034		}
5035	}
5036
5037
5038	//----- Report any problems with arguments before using
5039	if (msg != '')
5040	{
5041		RZalert( 'Invalid Revize Editor Request\n\n'
5042			   + 'Function: snippet_helper.js:RZcallEditor()\n\n'
5043			   + 'Problem: ' + msg + '\n' )
5044		return;
5045	}
5046
5047	//----- Make trace entry
5048	RZ.message = '';
5049	RZmsgAdd( "module"  , '\t' + moduleName )
5050	RZmsgAdd( "field"   , '\t' + fieldName )
5051	RZmsgAdd( "width"   , '\t' + width )
5052	RZmsgAdd( "height"  , '\t' + height )
5053	RZmsgAdd( "recordid", '\t' + recordid )
5054	RZmsgAdd( "options" , '\t' + options )
5055	RZtrace( "Revize Editor Request", RZ.message )
5056
5057	//----- Call Editor screen, passing parameters via Url
5058	var url;
5059	var editorDir = '/revize/'
5060
5061	if (!RZ.MSIE || RZ.browserversion < 5.5)
5062	{
5063		editorDir += 'javaeditor'
5064
5065		// Convert any rich edit options to applet editor Url parameters syntax
5066		options = RZ.options.split(';').join('&')
5067		if (options.substring(1,3) == '&&') options = options.substring(1)
5068	}else
5069	{
5070		editorDir += 'htmleditor'
5071		options = RZeditorOptions(options);		//convert to rich edit format
5072		options = 'options=' + escape(options)	//passed as a single parameter
5073	}
5074	url = editorDir + '/editor-editform.jsp?webspace=' + RZ.webspace;
5075	if (useDatabase != '') url += '&module=' + moduleName;
5076	url += '&field=' + fieldName
5077	if (recordid != '') url += '&recordid=' + recordid
5078	url += '&width=' + width + '&height=' + height + '&' + options
5079	RZpopupUrl('revize_editor',url,width,height,'no')
5080}
5081/*---------------------------------------------------------------------------
5082Open Url in Popup Window (return true if popup)
5083
5084Originally used popup window if either width, height or SCROLL was not blank;
5085with advent of RZaction() and use of RZ object arguments, do not assume popup
5086based on scroll value or if both width and height are set to 0.
5087
5088Since scroll is last feature, it can specify other features after the scroll
5089value. For example:
5090	yes,location=yes,menubar=yes,toolbar=yes,directories=yes'
5091
5092If niether width, heigth or scroll are specified assume popup window with no
5093features specified.
5094
5095Returns:
5096	window object of popup window or null if popup window not used
5097----------------------------------------------------------------------------*/
5098function RZpopupUrl(name,url,width,height,scroll)
5099{
5100	var useFeatures = true;
5101	if(typeof width == 'undefined'
5102	&& typeof height == 'undefined'
5103	&& typeof scroll == 'undefined')
5104		useFeatures = false;
5105	else
5106	{
5107		var popup = false;
5108		if (typeof width != 'undefined' && width != '' && width != 0 && width != '0')
5109			popup = true;
5110		if (typeof height != 'undefined' && height != ''	&& height != 0 && height!= '0')
5111			popup = true;
5112		if (!popup) return null;
5113
5114		// DCO 03-26-2014: for IE11+, remove RZ.baseurlprefix
5115		if ((RZ.isIEw3c || RZ.isMSEdge) && RZ.baseurlprefix && url.indexOf(RZ.baseurlprefix) == 0)
5116			url = url.substr(RZ.baseurlprefix.length);
5117	}
5118
5119	RZ.message = "Name: " + name + "\n"
5120		 + "Url:  " + url + "\n"
5121		 + "Width:  " + width + "\n"
5122		 + "Heigth: " + height + "\n"
5123		 + "Scroll: " + scroll + "\n"
5124	RZtrace("Opening Popup Window", RZ.message)
5125
5126	//----- Determine popup properties
5127	if(typeof url == 'undefined') url = ''
5128	if(typeof name == 'undefined') name = 'RevizeWindow'
5129	if(typeof width == 'undefined' || width=='') width = 400
5130	if(typeof height == 'undefined' || height=='') height = 400
5131	if(typeof scroll == 'undefined' || scroll=='') scroll = 'yes'
5132
5133	var menubar = 'no'
5134	var location = 'no'
5135	var toolbar = 'no'
5136	var directories = 'no'
5137	var status = 'yes'
5138	if( RZ.trace || RZ.debug )
5139	{
5140		scroll = 'yes'
5141		menubar = 'yes'
5142		location = 'yes'
5143		toolbar = 'yes'
5144		directories = 'yes'
5145		status = 'yes'
5146		width = parseInt(width) + 15
5147		height = parseInt(height) + 50
5148	}
5149	else if (name == 'admin')
5150	{
5151		menubar = 'yes'
5152		location = 'yes'
5153	}
5154
5155	var features = 'width=' + width + ',height=' + height
5156			   + ',location='+location
5157			   + ',menubar='+menubar
5158			   + ',resizable=yes'
5159			   + ',toolbar=' + toolbar
5160			   + ',directories=' + directories
5161			   + ',status=' + status
5162			   + ',scrollbars=' + scroll	//must be last to allow specify features
5163
5164	var x = (screen.availWidth - width) / 2 - 10
5165	if (RZ.browserdev) x=0;
5166
5167	var y = (screen.availHeight - height) / 2 - 30
5168	if (y < 50) y = 0
5169
5170	if(navigator.appVersion.indexOf('MSIE') == -1 && !RZ.isIEw3c )  // Netscape
5171		features += ',screenX=' + x.toString()
5172				 +  ',screenY=' + y.toString()
5173	else                                            // IE browser
5174		features += ',left=' + x.toString()
5175				 +  ',top=' + y.toString()
5176	if (!useFeatures) features = ''	//do not specify features
5177
5178	/*****
5179	First open the popup window and give it focus in case it was already open.
5180	It is possible that the popup window has been left open by another instance
5181	of the browser.  When this occurs on IE, the popup window will NOT have
5182	access to window.opener property.  To avoid this problem, we wait a second
5183	and then call RZpopupAccess() to close and reopen the popup if the popup
5184	window does not have proper access to this window.  We did not want to
5185	always close and reopen the window because it can be distracting for
5186	content editors.
5187	*****/
5188
5189	//TODO:	This statement gets 1075 error on IE when opening publishing window
5190	//		if popup edit form was left open from another edit (calendar_app)
5191	RZ.popupwin = window.open( url, name, features );
5192
5193	//----- On Netscape, RZ.popupwin sometimes not defined
5194	if (RZ.popupwin == null || typeof RZ.popupwin == 'undefined')
5195		RZ.popupwin = window.open( url, name, features );
5196
5197	//----- Give popup window focus
5198	RZ.timeoutfocus = window.setTimeout('RZfocus(RZ.popupwin)', 500);
5199
5200	//----- Check for access after page loads
5201	var str = 'RZpopupAccess("' + url + '","' + name+ '","' + features + '")'
5202	RZ.timeoutaccess = window.setTimeout(str, 1000)
5203
5204	return RZ.popupwin;
5205}
5206/*---------------------------------------------------------------------------
5207Cancel focus and access timeout events.
5208----------------------------------------------------------------------------*/
5209function RZcancelPopupEvents()
5210{
5211	window.clearTimeout(RZ.timeoutfocus)
5212	window.clearTimeout(RZ.timeoutaccess)
5213}
5214/*---------------------------------------------------------------------------
5215Sets focus in case the specified window was left open from a previous call
5216----------------------------------------------------------------------------*/
5217function RZfocus(win)
5218{
5219    if (RZwinaccess(win))
5220        if (win.name != 'rzrte' && win.name != 'RZpublishing') win.focus();
5221}
5222/*---------------------------------------------------------------------------
5223See above description in RZpopupUrl
5224----------------------------------------------------------------------------*/
5225function RZpopupAccess(url,name,features)
5226{
5227	var str = ''
5228	if (!RZwinaccess(RZ.popupwin))
5229	{
5230		str = 'popup window closed'
5231	}else
5232	{
5233		str = 'opener: '
5234		if (RZwinaccess(RZ.popupwin.opener))
5235		{
5236			if (typeof RZ.popupwin.opener.location == 'undefined')
5237				str += '*no url*'
5238			else
5239				str += RZ.popupwin.opener.location.href
5240		}
5241		else if (typeof RZ.popupwin.opener != 'undefined')
5242			str += 'no access to opener'
5243		else
5244			str += 'opener not defined'
5245	}
5246
5247	var msg = 'name: ' + name + '\n'
5248            + 'url: ' + url + '\n'
5249            + str + '\n'
5250	//alert('Popup Properties\n\n' + msg)
5251	RZtrace( 'Popup Properties', msg)
5252
5253	//----- Quit if popup window has been closed
5254	if (!RZwinaccess(RZ.popupwin)) return
5255
5256	//----- If no access to opener, close window and reopen
5257	if ( !RZwinaccess(RZ.popupwin.opener))
5258	{
5259		RZ.popupwin.close();
5260		RZ.popupwin = window.open( url, name, features );
5261		return
5262	}
5263
5264	/*
5265	//----- If Revize Control Panel... (future)
5266	if ( name == 'revizecontrol' )
5267	{
5268		if (typeof RZ.popupwin.RZ == 'undefined')
5269		{
5270			window.focus()
5271			RZ.popupwin.document.write('<title>Revize Control Panel</title>')
5272		}
5273	}
5274	*/
5275  	RZ.popupwin = null		//indicate popup processing complete
5276}
5277/*---------------------------------------------------------------------------------------------
5278Wait for access to "win" to perform "waitCommand" displaying "waitMsg" while waiting;
5279Only wait "maxSeconds" (default 30); check every "msInterval" (default 1000) milliseconds.
5280---------------------------------------------------------------------------------------------*/
5281function RZwait(win, waitCommand, waitMsg, maxSeconds, msInterval)
5282{
5283	if (typeof waitMsg == 'undefined') waitMsg = 'Waiting for access'
5284	if (typeof maxSeconds == 'undefined') maxSeconds = 30
5285	if (typeof msInterval == 'undefined') msInterval = 1000
5286
5287	RZcancelPopupEvents()	//RZwait overrides automatic popup events
5288
5289	//----- Validate arguments
5290	var msg = ''
5291	if (typeof win != 'string')
5292		msg = '1st Argument is type ' + typeof win;
5293	else if(typeof waitCommand != 'string')
5294		msg = '2nd Argument is type ' + typeof win;
5295
5296	if (msg != '')
5297	{
5298		msg = 'RZwait must be called with string variables\n\n' + msg;
5299		RZalert(msg)
5300		return;
5301	}
5302
5303	//----- Setup call to RZwaitCheck...
5304	var now = new Date()
5305	RZ.waitstart = now.getTime()	//start of wait
5306	RZ.waitaccess = 0
5307
5308	waitCommand = RZreplacesubstring( waitCommand, '"', '\\"' )
5309
5310	RZ.waitcall = 'RZwaitCheck( ' + win
5311	                          + ', "' + waitCommand + '" '
5312	                          + ', "' + waitMsg  + '" '
5313	                          + ', ' + maxSeconds
5314	                          + ', ' + msInterval
5315	                          + ' )'
5316
5317	RZtrace('Setup Wait', RZ.waitcall )
5318	//eval( RZ.waitcall )		//call RZwaitCheck() immediately
5319	setTimeout( RZ.waitcall, msInterval );	//give the url a chance to load
5320}
5321/*---------------------------------------------------------------------------
5322----------------------------------------------------------------------------*/
5323function RZwaitError(message)
5324{
5325	return true
5326}
5327/*---------------------------------------------------------------------------------------------
5328If access to "win" or "maxSeconds" have passed since "RZ.waitstart", perform "waitCommand";
5329otherwise wait another "msInterval" milliseconds.
5330
5331Access means permisison to access window, RZ not null and...
5332either window name is not blank (works for most non-Revize enabled pages)
5333--or-- RZ.loaded is not undefined nor null
5334
5335Notes:
5336It is possible that access to "win" is lost after checking access but prior to actually
5337accessing "win" variables which can cause one of the following JavaScript errors:
5338	RZ is null or not an object
5339	object does not support this property or method
5340
5341Checking the page access before the new url starts to load is believed to be one cause.
5342An alternative onerror handler is set to catch these potential javascript errors.
5343This function stops running after a javascript error but unfortunately when MS studio is
5344installed and IE script debugging is not disabled, the currently defined onerror handler
5345does not run either and therefore can't be used to restore the original onerror handler
5346or schedule RZwaitCheck() to run again.
5347
5348In order to restart RZwaitCheck in all cases is therefore rescheduled before the any
5349javascript error can occur and canceled if no more waiting is required.
5350---------------------------------------------------------------------------------------------*/
5351function RZwaitCheck (win, waitCommand, waitMsg, maxSeconds, msInterval)
5352{
5353	if (window.onerror == RZwaitError)
5354		window.onerror = RZ.waitonerror		//restore original handler
5355
5356	var now = new Date()
5357	var seconds = (now.getTime() - RZ.waitstart).toString() / 1000
5358	waitcallId = setTimeout( RZ.waitcall, msInterval)
5359
5360	var waitMore = ''
5361	if( !RZwinaccess(win) )
5362	{
5363		waitMore = 'no access'
5364		RZ.waitaccess = 0
5365	}
5366	else
5367	{	// see debugger notes this function description for onerror handling
5368		if (window.onerror != RZwaitError)
5369			RZ.waitonerror = window.onerror
5370		window.onerror = RZwaitError
5371
5372		//simulate race error one time as described in debugger notes above
5373		RZ.waitaccess++
5374		//if (RZ.waitaccess <= 1 && RZ.error.force) RZ.waitaccess = 99
5375
5376		// if window reloading, RZ.loaded first set to null
5377		if (typeof win.RZ != 'undefined' && win.RZ != null
5378		&& typeof win.RZ.loaded != 'undefined' && win.RZ.loaded != true)
5379			waitMore = 'refresh pending'
5380
5381		// window name undefined until window loaded (at least on IE)
5382		else if (typeof win.name == 'undefined')
5383			waitMore = 'window loading'
5384
5385		// if window name is not blank, assume window loaded
5386		// (recognizes non-revize enabled pages especially frames)
5387		else if (win.name != '')
5388			waitMore = ''
5389
5390		// RZ.loaded not defined until onload handler complete
5391		else if (typeof win.RZ == 'undefined' || win.RZ == null
5392		|| typeof win.RZ.loaded == 'undefined' || win.RZ.loaded != true)
5393			waitMore = 'onload pending'
5394
5395		window.onerror = RZ.waitonerror		//restore original handler
5396	}
5397
5398	var waitDone = false
5399	if (waitMore != '')
5400	{
5401		var waitedMsg = ' waited ' + parseInt(seconds) + ' seconds'
5402		RZtrace(waitMsg, waitedMsg )
5403		RZ.parent.status = waitMsg + ': ' +  waitedMsg + ' (' + waitMore + ')'
5404		if (seconds > maxSeconds )	//don't wait too long
5405			waitDone = true;		//waited long enough
5406	}
5407	if (waitMore=='' || waitDone)
5408	{
5409		RZ.waitcall = ''			//clear in case scheduled timeout starts
5410		clearTimeout( waitcallId )	//cancel scheduled waitCheck
5411		waitedMsg = 'waited ' + seconds + ' total seconds'
5412		RZtrace('RZwaitCheck(): ' + waitMsg, waitedMsg )
5413		if (!waitDone) RZ.parent.status = ''
5414		eval( waitCommand )
5415	}
5416}
5417
5418/*---------------------------------------------------------------------------
5419Determine if opener properties are still accessible
5420(they will not be if window closed or moved to another url)
5421
5422TODO: check access on NS (unknown)
5423
5424The following is always false on Netscape:
5425
5426if ( typeof RZ.popupwin.opener.document == 'unknown' )
5427----------------------------------------------------------------------------*/
5428function RZwinaccess(win)
5429{
5430	//default to opener for backward compatibility but all calls
5431	//now probably pass an argument.
5432	if (!win) win = RZ.parent.opener
5433
5434	try
5435	{
5436		//TODO: gets interface error (IE?) if calling window is closed
5437		//		(inside try/catch so should not cause issues)
5438
5439		// chrome (and probably FF), throw exception if invalid window
5440		// e.g. parent.opener when it does not exist
5441		if (typeof win == 'undefined' || win == 'undefined') return false
5442
5443		if(win != null
5444		&& typeof win != 'undefined'
5445		&& win.closed != true
5446
5447		// chrome (and probably FF), throw exception if invalid window
5448		// e.g. parent.opener when it does not exist
5449		&& win !='undefined')
5450		{
5451			if (RZ.MSIE && typeof win.document == 'unknown')
5452				return false;
5453			//force error if access denied
5454			else if (!RZ.MSIE && win.location.href == '')
5455				return false;
5456			else
5457				return true;
5458		}
5459	}
5460	catch (ex)
5461	{
5462		return false;
5463	}
5464	return false
5465}
5466
5467/*---------------------------------------------------------------------------
5468Give focus to opener if still accessible.
5469----------------------------------------------------------------------------*/
5470function RZopenerFocus(win)
5471{
5472	if (RZ.refresh)
5473		RZ.refresh = false
5474	else
5475	{
5476      if (typeof win == 'undefined') win = RZ.parent.opener
5477		if (RZwinaccess(win)) win.focus()
5478	}
5479}
5480
5481/*---------------------------------------------------------------------------
5482Display page permission warning defined by code.
5483----------------------------------------------------------------------------*/
5484function RZpagemessage(code,linkname,linkparent,linklevel)
5485{
5486	if (typeof linkname == 'undefined') linkname = ''
5487	if (typeof linkparent == 'undefined') linkparent = ''
5488	if (typeof linklevel == 'undefined') linklevel = ''
5489
5490	var msg = ''
5491	var hash = '';
5492
5493	switch ( code )
5494	{
5495		// button warning
5496		case "":
5497			break;
5498
5499		// page permission icon appearing in upper left corner of page is clicked.
5500		case "noparent":
5501			msg += 'No parent defined for this PAGE'
5502			break;
5503
5504		// link manager
5505		case "nolinkparentfield":
5506			msg += 'No linkparent field defined for this LINK'
5507			break;
5508
5509		// link manager
5510		case "nolinkparent":
5511			msg += 'No parent defined for this LINK'
5512			break;
5513
5514		// button warning
5515		case "nomodule":
5516			msg += 'Revize module not defined on button'
5517			break;
5518
5519		// button warning
5520		case "parent_itself":
5521			msg += 'Page can not be a parent of itself \n(no longer true)'
5522			break;
5523
5524		// unknown warning
5525		default:
5526			msg += 'Page permission incongruency'
5527			code = RZreplace(code,'--','\n')
5528			if (code.length > 25)
5529				msg += ':\n\n' + code
5530			else
5531				msg += ' (reason:' + code + ')'
5532			break;
5533	}
5534
5535	RZ.message = ''
5536	RZ.parameters = ''
5537	if (linkname != '')
5538	{
5539		RZ.message += 'Link Information:\n\n'
5540		RZaddUrlParameter('Link Name: ' + linkname )
5541		RZaddUrlParameter('Link Module: ' + RZ.link[linkname].linkmodule )
5542		RZ.message += '\n'
5543
5544		if (linkparent == '*nofield*')
5545			RZ.message += 'No linkparent field in linkmodule\n'
5546		else if (RZ.link[linkname].linkmodule != '')
5547			RZaddUrlParameter(RZ.link[linkname].linkmodule+'.linkparent: '+ linkparent)
5548		RZaddUrlParameter('First List Item Parent: '+ RZ.link[linkname].linkparent)
5549
5550		if (linklevel != '')
5551		{
5552			RZ.message += '\n'
5553			RZaddUrlParameter('Link Level: '+ linklevel)
5554			if (typeof RZ.linkparentnew[linkname] != 'undefined')
5555				RZaddUrlParameter('Level '+linklevel+' new parent_key: '
5556				                 + RZ.linkparentnew[linkname][linklevel])
5557		}
5558	}
5559	else
5560	{
5561		RZ.message += 'Page Information:\n\n'
5562		var templateType = '(unique)'
5563		if (RZ.pagemodule != '') templateType = '(dependent)'
5564		RZaddUrlParameter('Template: ' + RZ.pagetemplatename + '  ' + templateType )
5565		if (RZ.pagemodule != '')
5566		{
5567			RZaddUrlParameter('Module: '    + RZ.pagemodule )
5568			RZaddUrlParameter('Record Id: ' + RZ.editrecordid )
5569			hash = '#' + RZ.pagemodule + "_" + RZ.editrecordid;
5570		}
5571		RZ.message += '\n'
5572		RZaddUrlParameter('page_key:     '   + RZ.page_key )
5573		RZaddUrlParameter('parent_key:  '   + RZ.parent_key )
5574		RZ.message += '\n'
5575		RZaddUrlParameter('Permitted roles: ' + RZ.page_roles )
5576		RZaddUrlParameter('Permitted users: ' + RZ.page_users )
5577		if (RZ.inherit_key != '')
5578			RZaddUrlParameter('Inherited from: ' + RZ.inherit_key )
5579	}
5580	RZ.message += '\n'
5581	RZaddUrlParameter('permissions_options: ' + RZ.permissions_options )
5582
5583	if (msg != '')
5584	{
5585		msg =  '---------------------------------------------------\n' + msg + '\n'
5586		msg += '---------------------------------------------------\n\n'
5587	}
5588	msg += RZ.message + '\n'
5589	msg += '---------------------------------------------------\n'
5590	msg += 'Click Ok to find pages that link to this page      \n'
5591	msg += '---------------------------------------------------\n'
5592
5593	if (confirm(msg))
5594		location.href = RZ.webspacelinksurl + hash
5595	return void(0)
5596}
5597
5598/*---------------------------------------------------------------------------
5599Display and clear warning from jsp code
5600----------------------------------------------------------------------------*/
5601function RZwarning()
5602{
5603	if (RZ.warning != '')
5604	{
5605		window.status = RZreplaceAll( RZ.warning, '-- --', '; ')
5606		RZtrace( 'Warning from JSP code', RZ.warning )
5607		RZ.warning = ''
5608	}
5609}
5610/*---------------------------------------------------------------------------
5611Display alert or confirm dialog using RZalert (with prepended issue message)
5612Only displayed if RZ.debug is true;
5613
5614By using RZalert, the javascript debugger can be started if in debug mode.
5615
5616Parameters:
5617	message	- Message describing problem encounted with page
5618	isConfirm - Optional If true, confirm dialog is used (default is false)
5619----------------------------------------------------------------------------*/
5620function RZwarn(message,isConfirm) { return RZnote(message,isConfirm) }
5621function RZnote(message,isConfirm)
5622{
5623	var isNote = true
5624	return RZalert(message,isConfirm,isNote)
5625}
5626/*---------------------------------------------------------------------------
5627Display alert using confirm dialog
5628
5629Parameters:
5630	message	- Message describing problem encounted with page
5631----------------------------------------------------------------------------*/
5632function RZconfirm(message)
5633{
5634	return RZalert(message,true)
5635}
5636/*---------------------------------------------------------------------------
5637Add message to trace window (including call stack)
5638
5639Display message in alert with prepended with notation that page has a problem
5640
5641DCO 10-20-2014: Stop using alert() -- RZtrace() saves messages for AdminPanel
5642
5643If RZ.debug is true, a confirm dialog is used with option to start the
5644JavaScript debugger.
5645
5646----------
5647Parameters:
5648----------
5649message	 	Message describing problem encounted with page
5650
5651isConfirm 	(Optional) If true, confirm dialog is used (default is false)
5652				As of 07-22-2012, always prompt for debugger in Debug Mode
5653			09-14-2012: was deprecated probably 07-22; reactivated so can be used as
5654			extended confirm() with option to start debugger in debug mode.
5655			e.g. RZsave() uses as extended confirm() when Revize form wizard deleted.
5656
5657isNote 		(Optional) If true and not RZ.Debug, only display message in status bar
5658			Otherwise use RZalert() to display message.
5659----------------------------------------------------------------------------*/
5660function RZalert(message,isConfirm,isNote)
5661{
5662  	if (typeof isNote == 'undefined') isNote = false;
5663  	if (typeof isConfirm == 'undefined') isConfirm = false;
5664
5665	if (typeof message == 'undefined' || typeof message == 'object')
5666  		message = 'Message is ' + typeof message;
5667
5668  	else if (message == '')
5669  		message = 'No Reason Given';
5670
5671	message = message.split('--').join('\n\n');
5672	if (isConfirm || RZ.debug)
5673	{
5674		if (RZ.debug)
5675		{
5676			var msg = 'DEBUG mode is active; debugger starts if Ok clicked\n\n' + message
5677			message = RZdisplayCaller(msg);
5678		}
5679		if (confirm(message))
5680		{
5681			if (RZ.debug) debugger;
5682			return true;
5683		}
5684	}
5685	else if (isNote)
5686		window.status = message;
5687	else
5688		RZtrace('RZalert',message);	//DCO 10-20-2014
5689		//alert(message);			//		 ''
5690
5691	return '';	//can be used to clear message
5692}
5693/*---------------------------------------------------------------------------
5694Convenience function for determining if administrator logged in
5695----------------------------------------------------------------------------*/
5696function RZisadmin()
5697{
5698	return RZcheckoptions(RZ.roles,'superuser,administrator');
5699}
5700/*---------------------------------------------------------------------------
5701Write html if user is authenticated for current webspace (RZ.webspace).
5702During page initialization RZ.login is set to the RZlogin cookie defined by
5703the login function.
5704TODO: Do not write any html for production channels.
5705
5706Parameters:
5707	html -			html code to be written if logged in and proper permission
5708	module -		Module requiring permissions
5709	permits -		Permissions required on module
5710	action -		Button action
5711----------------------------------------------------------------------------*/
5712function RZlogin( html, module, permits, action )
5713{
5714	// 2nd parameter was webspace way back and there was not a 3rd parameter
5715	// so defaulting permits to blank retains backward compatibility.
5716	if (typeof module == 'undefined') module = '';
5717	if (typeof permits == 'undefined') permits = '';
5718	if (typeof action == 'undefined') action = '';
5719
5720	// backward compatibility
5721	if(typeof RZ.webspace == 'undefined'
5722	&& typeof RZ.webSpaceName != 'undefined')
5723		RZ.webspace = RZ.webSpaceName
5724
5725	// if login webspace does not match page webspace, return false
5726	if(RZ.login != RZ.webspace && RZ.login != '*ALL')
5727		return false
5728
5729	// if pointbasedemo webspace and NOT preview directory, return false
5730	if(RZ.webspace.indexOf('pointbasedemo') >= 0
5731	&& RZ.page.pathname.indexOf('-preview') == -1)
5732		return false;
5733
5734	// if demosite webspace and production directory, return false
5735	if(RZ.webspace.indexOf('demosite') >= 0
5736	&& RZ.page.pathname.indexOf('-prod') != -1)
5737		return false;
5738
5739	// if atwatercounty webspace and production directory, return false
5740	if(RZ.webspace.indexOf('atwatercounty') == 0
5741	&& RZ.page.pathname.indexOf('-prod') != -1)
5742		return false;
5743
5744	// if paradigm webspace and production directory, return false
5745	if(RZ.webspace.indexOf('paradigm') == 0
5746	&& RZ.page.pathname.indexOf('-prod') != -1)
5747		return false;
5748
5749	// show the help button before the permissions button
5750	if(module == 'webspace_page_permissions')
5751		document.write('<a href="http://cms4.revize.com/revize/supportrevize/revize_faq.php" target="_new"><img src="../images/edit/help.jpg" alt="Help" border="0" /></a>');
5752
5753	//----- If called with a module and required permits, check them.
5754	//		If no access, return false and do not write any html.
5755	if ( module != '' && permits != ''
5756	&& RZpermits(module , permits) != true )
5757		return false;
5758
5759
5760	//----- Hide button if no page permissions (TODO: hides what? seq?)
5761	if ( action != 'save' && action != 'cancel' && action != 'history')
5762		if ( !RZ.pagepermission && module != '' ) return false;
5763
5764
5765	if ( typeof html != 'undefined' && html != '')
5766		document.write(html);
5767
5768	return true;
5769}
5770/*---------------------------------------------------------------------------
5771Display rendered width of element
5772----------------------------------------------------------------------------*/
5773function RZrte(id)
5774{
5775	if (!id)
5776	{
5777		id=prompt('Enter element id',RZgetcookie('RZrte'));
5778		if (!id) return;
5779		RZsetcookie('RZrte',id);
5780	}
5781	var msg = '';
5782	var el = document.getElementById(id);
5783	if (!el)
5784		msg = 'id='+id+' not found';
5785	else
5786	{
5787		msg += '\n    font-family=' + currentStyle('font-family') + ';';
5788		msg += '\n    font-size=' + currentStyle('font-size') + ';';
5789		while (el.clientWidth == 0 && el.parentNode)
5790			el = el.parentNode;
5791		var padding = parseInt(currentStyle('padding-left'))
5792		            + parseInt(currentStyle('padding-right'));
5793		msg = '.rte-format {' + msg + '\n}'
5794			+ '\n\nwidth=' + el.clientWidth;
5795		if (padding > 0)
5796			msg += '\n\nwidth=' + (el.clientWidth - padding) + ' (less padding for RTE)';
5797	}
5798	alert(msg);
5799	return;
5800
5801	function currentStyle(style)	//style is css format (e.g. font-size)
5802	{
5803		if (!document.defaultView)
5804		{
5805			style = style.replace(/(-)(\w)/, function (all,dash,word){
5806				return word.toUpperCase();
5807			})
5808			return el.currentStyle[style];
5809		}
5810		else
5811		{
5812			var renderedStyle = document.defaultView.getComputedStyle(el,'');
5813			return renderedStyle.getPropertyValue(style);
5814		}
5815	}
5816}
5817/*---------------------------------------------------------------------------
5818Toggle debug mode with prompt that includes optional notes argument.
5819----------------------------------------------------------------------------*/
5820function RZdebug(notes,win)
5821{
5822	if (typeof win == 'undefined') win = window;
5823
5824	if (typeof notes == 'undefined')
5825		notes = '';
5826	else if (typeof notes == 'object')
5827	{
5828		win = notes;
5829		notes = '';
5830	}
5831
5832	var debugState = !RZ.debug
5833	var msg = 'Set debug ' + debugState + '?'
5834	if (typeof notes != 'undefined')
5835		msg = notes + '\n\n' + msg
5836
5837	//dont need confirm with new adminpanel
5838	if (!notes || win.confirm(msg))
5839	{
5840		RZ.debug = debugState;
5841		RZsetcookie('RZdebug', (RZ.debug ? RZ.webspace : '') ,RZ.page.domain);
5842	}
5843	return void(0)
5844}
5845/*---------------------------------------------------------------------------
5846Prompt to start debugger with optional notes argument.
5847----------------------------------------------------------------------------*/
5848function RZdebugger(notes)
5849{
5850	var msg = 'Start Debugger?'
5851	if (typeof notes != 'undefined')
5852		msg = notes + '\n\n' + msg
5853
5854	if (confirm(msg))
5855	{
5856		//RZ.debug = true;
5857		debugger;
5858	}
5859
5860	return void(0)
5861}
5862/*---------------------------------------------------------------------------
5863Ask to start IE or Netscript Javascript debugger.
5864----------------------------------------------------------------------------*/
5865function RZstartDebugger()
5866{
5867	debugger;
5868	return;
5869}
5870/*---------------------------------------------------------------------------
5871return function name of caller at depth
5872----------------------------------------------------------------------------*/
5873function RZgetcaller(depth)
5874{
5875	if (!depth) depth = 2;	//caller of this func caller
5876	var patternFunction = /function\s*(\w*)\s*\((.*?)\)[^{]*{([\s\S]*)}/
5877	//                                 1         2           3
5878	//								   name      args        body
5879	var funcName = '';
5880	for (var func = RZgetcaller.caller; func != null; func = func.caller)
5881	{
5882		var script = func.toString();
5883		var results = funcName = script.match(patternFunction);
5884		if (!results)
5885			funcName = '*unknown*';
5886		else
5887		{
5888			funcName = results[1];
5889			if (!results[1])
5890				funcName = "anonymous";
5891		}
5892		if (--depth <= 0) return funcName;
5893	}
5894	return '-main-';
5895}
5896/*---------------------------------------------------------------------------------------
5897Display caller stack
5898
5899---------
5900Arguments:
5901---------
5902msg			(Optional) String contain message to display before caller stack
5903options		(Optional) String contains the following seperated by commas
5904			debug		pause in debug mode (used in calendar_app)
5905			debug=???	only pause if RZdebugoption[???] is true
5906			force		pause even if not in debug mode
5907			yes			assume yes rather using comfirm
5908---------------------------------------------------------------------------------------*/
5909RZdisplayCaller.MAX_FUNCTIONS_SHOW_ARGS = 3;
5910RZdisplayCaller.MAX_FUNCTIONS = 15;
5911function RZdisplayCaller(msg,options)
5912{
5913    if (!msg) msg = '';
5914	if (msg) msg += '\n\n';
5915	if (!options) options = '';
5916
5917	var isDebug = RZcheckOptions(options,'debug')
5918	var isDebugForce = RZcheckOptions(options,'force')
5919	if (isDebugForce) isDebug = true;
5920
5921	var e = '';
5922	var funcName = '';
5923	var indentFunc = isDebug ? 0 : 4;
5924	var indentArgs = indentFunc + 4;
5925	var trace = msg;
5926	try											//don't want js error for users
5927	{
5928		if (isDebug)
5929		{
5930			if (!RZ.debug && !isDebugForce)		//RZ.debug can be typeof unknown
5931				return false;
5932			var isDebugYes = RZcheckOptions(options,'yes');
5933			var debugOption = RZgetOption(options,'debug');	//debug=
5934			if (!debugOption || !RZisDebugOption(debugOption)) return false;
5935		}
5936
5937		var i, count = 0;
5938		var patternFunction = /function\s*(\w*)\s*\((.*?)\)[^{]*{([\s\S]*)}/
5939		//                                 1         2           3
5940		//								   name      args        body
5941		for (var func = RZdisplayCaller.caller; func != null; func = func.caller)
5942		{
5943			var script = func.toString();
5944			var results = funcName = script.match(patternFunction);
5945			if (!results)
5946				funcName = '*unknown*';
5947			else
5948			{
5949				funcName = results[1] + '(' + results[2] + ')';
5950				if (!results[1])
5951					funcName = "anonymous" + funcName;
5952			}
5953
5954			// display args for 1st few functions
5955			if (++count <= RZdisplayCaller.MAX_FUNCTIONS_SHOW_ARGS)
5956			{
5957				msg = funcName + '\n';
5958
5959				// display args and current values
5960				var args = results[2];
5961				if (args)
5962				{
5963					args = args.split(',');
5964					for (i=0;i<args.length;i++)
5965					{
5966						var value = 'undefined';
5967						if (i < func.arguments.length) 	//value supplied
5968						{
5969							var indentValue = indentArgs + args[i].length + 1;
5970							value = func.arguments[i] + '';
5971							value = value.replace(/\t/g,'    ');
5972							if (value.length > 20)
5973								value = RZtrim(value.substr(0,20)) + '...';
5974							value = value.replace(/\n/g,'\n' + RZdup(indentValue,' '));
5975						}
5976						msg += RZdup(indentArgs,' ') + args[i] + '='
5977							   + value
5978							   + '\n';
5979					}
5980				}
5981				funcName = msg;
5982			}
5983			// for anonymous, display first non-blank line of function body
5984			if (funcName.indexOf('anonymous(') != -1)
5985			{
5986				results = results[3].match(/\s*(\w+.*)/);
5987				if (results)
5988				{
5989					funcName += RZdup(indentArgs,' ') + '{' + results[1] + '...}\n';
5990				}
5991			}
5992			if (count == 1)
5993			{
5994				if (isDebug)
5995					trace += 'DEBUG MODE pause in: ' + funcName + 'CALLED FROM...\n';
5996				else
5997					trace += 'CALLED FROM...\n' + RZdup(indentFunc,' ') + funcName;
5998			}
5999			else
6000				trace += '    ' + funcName + "";
6001
6002			if (func.caller == func) break;		//NS 4.0 bug workaround
6003			if (count > RZdisplayCaller.MAX_FUNCTIONS) break;	//probably in recursive loop (e.g. calendar setup())
6004		}	// end trace stack
6005
6006		// append main html file
6007		RZdisplayCaller.fn = funcName;
6008		var filepath = location.pathname;
6009		filepath = filepath.replace(/\\/g,'/');
6010		RZdisplayCaller.filename = filepath;
6011		filepath = filepath.substr(filepath.lastIndexOf('/')+1)
6012		trace += '    ' + filepath;
6013
6014		if (isDebug)
6015			return isDebugYes || confirm(trace + '\n\nStart Debugger?');
6016	}
6017	catch (e) {}	//ignore js errors
6018
6019	return trace;
6020}
6021/*---------------------------------------------------------------------------------------
6022Display all object values and expand object children down to OBJECT_DEPTH
6023
6024Can also be used to return display value for other types (i.e. boolean, number or string) OR
6025	*undefined*, *empty*, *null*, *true*, *false*
6026
6027TODO: typeof undefined is not displayed properly
6028	  html elements have el.contructor == Element is true
6029---------------------------------------------------------------------------------------*/
6030function RZdisplayObject(obj,name)
6031{
6032	try
6033	{
6034		return RZdisplayObjectProcess(obj,name);
6035	}
6036	catch (e)
6037	{
6038		RZdisplayObject.display += '\nException Displaying Object:\n' + e.description;
6039		return RZdisplayObject.display;
6040	}
6041}
6042function RZdisplayObjectProcess(obj,name,indent,isArray)
6043{
6044	var i, e, results;
6045
6046	//assume top level starting point, initialize variables
6047	if (typeof(indent) == 'undefined')
6048	{
6049		indent = 0;
6050		RZdisplayObject.objectCount = 0;
6051		RZdisplayObject.quit = false;
6052		RZdisplayObject.lastTypeObject = false;
6053		RZdisplayObject.firstObject = true;
6054		RZdisplayObject.display = '';			//build as processed in case exception
6055	}
6056	//----- Initialize any undefined RZdisplayObject settings
6057	if (!RZdisplayObject.OBJECT_LIMIT)
6058		RZdisplayObject.OBJECT_LIMIT = 100;		//max number of object displayed without prompt
6059	if (!RZdisplayObject.OBJECT_DEPTH)			//TODO:
6060		RZdisplayObject.OBJECT_DEPTH = 5;		//max depth for object display
6061	if (!RZdisplayObject.INDENT_SIZE)
6062		RZdisplayObject.INDENT_SIZE = 4;		//max depth for object display
6063	if (!RZdisplayObject.MAXLINE)
6064		RZdisplayObject.MAXLINE = 500;			//max characters displayed for any value
6065	if (typeof RZdisplayObject.SHOW_PROTOTYPE == 'undefined')
6066		RZdisplayObject.SHOW_PROTOTYPE = false;	//true to display prototype elements
6067	if (typeof RZdisplayObject.SHOW_TYPE == 'undefined')
6068		RZdisplayObject.SHOW_TYPE = true;		//true to display non-object data types
6069	if (!RZdisplayObject.MARKER)
6070		RZdisplayObject.MARKER = '&#8226;';		//used for null, empty, etc
6071	if (!RZdisplayObject.EOL_MARKER)
6072		RZdisplayObject.EOL_MARKER = '&#172;';	//end of non-object value
6073	if (!RZdisplayObject.OBJECT_SPACING)
6074		RZdisplayObject.OBJECT_SPACING = '\n';	//spacing before and after object
6075
6076	//----- Set work variables for this depth
6077	var spaces = RZdup(indent * RZdisplayObject.INDENT_SIZE, "&nbsp;");
6078	var spacesPlus = spaces + RZdup(RZdisplayObject.INDENT_SIZE, "&nbsp;");
6079	var spacesPlusPlus = spacesPlus + RZdup(RZdisplayObject.INDENT_SIZE, "&nbsp;");
6080
6081	var type = '';
6082	var isEmpty = true;
6083	var isObject = true;
6084	var isArrayElement = false;
6085	if (isArray && !isNaN(name))
6086		isArrayElement = true;
6087	var objAdjust = obj;
6088
6089	//----- Determine type
6090	if (obj && obj.constructor == Array)
6091	{
6092		type = 'array';
6093		isArray = true;
6094		//objAdjust = {length: obj.length}
6095		//for (i in obj) {objAdjust[i] = i};
6096	}
6097
6098	else if (obj && obj.constructor == Function)
6099		type = 'function';
6100
6101	//----- Not called with object, display value of obj argument
6102	else if (typeof(obj) != 'object' || (indent==0 && obj === null))
6103		return getValue(obj);
6104
6105	//----- Headings
6106	if (type) type += ' ';
6107	if (indent == 0)	//display for top level
6108	{
6109		if (isObject)
6110		{
6111			if (!name) name = '[' + type + 'object]: ';
6112			RZdisplayObject.display += name + '\n';
6113			indent = 1;
6114		}
6115	}
6116	else
6117	{
6118		RZdisplayObject.display += spaces;
6119		if (isArrayElement)
6120			RZdisplayObject.display += '[' + name + ']: (' + type + 'object)\n';
6121		else
6122			RZdisplayObject.display += '(' + type + 'object): ' + name + '\n';
6123		//RZdisplayObject.display += spaces + '[object' + type + ']: ' + name + '\n';
6124	}
6125
6126	//----- Iterate through the elements in obj; NOTE: when typeof(obj)==function, no iteration takes place
6127	//		Use objAdjust defined above since for (i in obj) does not find array length property
6128	for (i in objAdjust)
6129	{
6130		// process OBJECT within obj (including functions)
6131		if (typeof(obj[i]) == 'object' || typeof(obj[i]) == 'function')		//expand nested object
6132		{
6133			if (overLimit()) continue;
6134			if (typeof(obj[i]) == 'function' && skipPrototype(Function)) continue;
6135
6136			var prefix = '';
6137			if (RZdisplayObject.firstObject && !RZdisplayObject.lastTypeObject)
6138				prefix = RZdisplayObject.OBJECT_SPACING;
6139
6140			// move down another level
6141			RZdisplayObject.display += prefix + spaces + RZdisplayObjectProcess(obj[i],i,indent,isArray);
6142			if (RZdisplayObject.display.substr(RZdisplayObject.display.length-2,1) != '\n')		//don't need newline if returned from nested call
6143				RZdisplayObject.display += RZdisplayObject.OBJECT_SPACING;
6144
6145			RZdisplayObject.firstObject = false;
6146			RZdisplayObject.lastTypeObject = true;
6147			isEmpty = false;
6148		}
6149		// process NON-OBJECT element within obj
6150		else
6151		{
6152			if (skipPrototype()) continue;		// if not displaying prototype variables
6153			if (isArray && isArrayElement) RZdisplayObject.display += spaces;		// extra indentation for array objects
6154
6155			var value = getValue(obj[i]) 		// determine non-object value
6156
6157
6158			value = value.replace(/\n/gm,'\n'+spacesPlusPlus);	//apply indent to all lines
6159			value = RZdisplayObject.display += spacesPlus + i + ': ' + value + '\n';
6160
6161			RZdisplayObject.lastTypeObject = false;
6162			isEmpty = false;
6163		}
6164	}
6165
6166	//----- Done iterating through elements, if nothing displayed, indicate why
6167	if (isEmpty)
6168	{
6169		// extra indentation for array objects
6170		if (isArray) RZdisplayObject.display += spaces;
6171
6172		// special values: null, function, empty
6173		if (obj === null)							//null object
6174			RZdisplayObject.display += spacesPlus + RZdisplayObject.MARKER + 'null' + RZdisplayObject.MARKER + '\n';
6175
6176		else if (obj.constructor == Function)		//function (just show name and paramters)
6177		{
6178			results = obj.toString().match(/function\s*(\w*)\s*\(([^\)]*)\)/);
6179			if (results)
6180				RZdisplayObject.display += spacesPlus + results[0] + '...\n'
6181			else									//name not found (should not get here)
6182				RZdisplayObject.display += spacesPlus  + RZdisplayObject.MARKER+ 'unknown function' + RZdisplayObject.MARKER;
6183			RZdisplayObject.lastTypeObject = false;
6184		}
6185		else if (isEmpty)							//empty object (must test after function test above)
6186			RZdisplayObject.display += spacesPlus + RZdisplayObject.MARKER + 'no elements' + RZdisplayObject.MARKER + '\n';
6187	}
6188	// remove last newline (it gets added by caller)
6189	RZdisplayObject.display = RZdisplayObject.display.substring(0,RZdisplayObject.display.length-1);
6190	//-----------------------------
6191	return RZdisplayObject.display;
6192	//-----------------------------
6193
6194	/*
6195	*	Return true if not displaying any more nested objects.
6196	*/
6197	function overLimit()
6198	{
6199		if (RZdisplayObject.quit || indent >= RZdisplayObject.OBJECT_LIMIT) return true;
6200		if (++RZdisplayObject.objectCount > RZdisplayObject.OBJECT_LIMIT)
6201		{
6202			if ( confirm(RZdisplayObject.OBJECT_LIMIT + ' objects expanded\n'
6203			   + 'Display ' + RZdisplayObject.OBJECT_LIMIT + ' more?'))
6204				RZdisplayObject.objectCount = 0;
6205			else
6206				RZdisplayObject.quit = true;
6207		}
6208		return false;
6209	}
6210	/*
6211	*	Return true if not displaying prototype functions or variables.
6212	*	type (optional: Function if checking for Function constructor
6213	*/
6214	function skipPrototype(type)
6215	{
6216		var status = false;
6217		/* was throwing exceptions (replaced with code below)
6218		if (!RZdisplayObject.SHOW_PROTOTYPE
6219		|| !obj[i].hasOwnProperty(obj))
6220			status = true;
6221		else
6222			status = false;
6223		*/
6224
6225		//js error from RZupdateFieldList trace after RZclearlist(...)
6226		if (!RZdisplayObject.SHOW_PROTOTYPE
6227		&& obj && i && obj[i]
6228		&& obj[i].constructor
6229		&& obj[i].constructor.prototype)
6230		{
6231			if (type && type == Function
6232			&& obj[i].constructor.prototype.constructor == type)
6233				status = true;
6234
6235			//else if (!type && obj[i].constructor.prototype == i)
6236			else if (!type
6237			&& (obj.constructor != Array || isNaN(i))	//added so array[0] displays
6238			&& obj[i].constructor.prototype == i)
6239				status = true;
6240		}
6241		return status;
6242
6243		if (!RZdisplayObject.SHOW_PROTOTYPE
6244		|| !obj[i].hasOwnProperty(obj))
6245			status = true;
6246		else
6247			status = false;
6248	}
6249	/*
6250	*	determine non-object value
6251	*/
6252	function getValue(value)
6253	{
6254		var type = typeof(value);
6255
6256		if (type === 'undefined')
6257			value = RZdisplayObject.MARKER + 'undefined' + RZdisplayObject.MARKER;
6258
6259		else if (value === '')
6260			value = RZdisplayObject.MARKER + 'empty string' + RZdisplayObject.MARKER;
6261
6262		else if (value === null)
6263			value = RZdisplayObject.MARKER + 'null' + RZdisplayObject.MARKER;
6264
6265		else if (value === true)
6266			value = RZdisplayObject.MARKER + 'true' + RZdisplayObject.MARKER;
6267
6268		else if (value === false)
6269			value = RZdisplayObject.MARKER + 'false' + RZdisplayObject.MARKER;
6270
6271		else if (value.length > RZdisplayObject.MAXLINE)
6272			value = value.substr(0,RZdisplayObject.MAXLINE) + '...' + RZdisplayObject.EOL_MARKER;
6273
6274		else
6275			value += RZdisplayObject.EOL_MARKER;
6276
6277		if (RZdisplayObject.SHOW_TYPE && type !== 'undefined'
6278		&& value.indexOf(RZdisplayObject.MARKER + 'empty') != 0
6279		&& value.indexOf(RZdisplayObject.MARKER + 'null') != 0)
6280			value = '(' + type + '): ' + value;
6281
6282		return value;
6283	}
6284}
6285/*-----------------------------------------------------------------------------
6286-----------------------------------------------------------------------------*/
6287function RZdisplayMessage(msg)
6288{
6289	if (!msg) msg = '';
6290	var el = document.getElementById('errorMessage');
6291	if (!el)
6292		el = document.getElementById('message');
6293	if (!el)
6294		el = document.getElementById('msg');
6295
6296	if (el)
6297		el.innerHTML = msg == '' ? '&nbsp;' : msg;
6298	else if (msg)
6299		alert(msg);
6300	if (msg)
6301		return false;
6302	return true;
6303}
6304/*---------------------------------------------------------------------------
6305Load Color Picker.
6306----------------------------------------------------------------------------*/
6307function RZcolorpicker(field)
6308{
6309	RZ.colorfield = field;
6310	while (RZ.colorfield.tagName != 'INPUT')
6311	{
6312		RZ.colorfield = RZ.colorfield.previousSibling
6313		if (RZ.colorfield == null || typeof RZ.colorfield == 'undefined')
6314		{
6315			RZalert('Input field does not preceed Color Picker Icon')
6316			return false;
6317		}
6318	}
6319	features = 'width=320,height=160,scroll=auto,status=no,titlebar=no,resizable=yes';
6320	var x = (screen.availWidth - 320) / 2 - 10;
6321	var y = (screen.availHeight - 160) / 2 - 30;
6322	if (y < 50)
6323		y = 0;
6324
6325	if(navigator.appVersion.indexOf('MSIE') == -1)  // Netscape
6326	{
6327		features += ',screenX=' + x.toString()
6328				 +  ',screenY=' + y.toString();
6329	}
6330	else                                            // IE browser
6331	{
6332		features += ',left=' + x.toString()
6333				 +  ',top=' + y.toString();
6334	}
6335	colorPicker = window.open('/revize/util/snippet_helper_colorpicker.html','',features);
6336	return true;
6337}
6338/*---------------------------------------------------------------------------
6339Spellcheck input or textarea field proceeding specified field.
6340----------------------------------------------------------------------------*/
6341function RZspellcheck(field)
6342{
6343	RZ.spellcheckfield = field;
6344	while (RZ.spellcheckfield.tagName != 'INPUT'
6345	&& RZ.spellcheckfield.tagName != 'TEXTAREA')
6346	{
6347		RZ.spellcheckfield = RZ.spellcheckfield.previousSibling
6348		if (RZ.spellcheckfield == null || typeof RZ.spellcheckfield == 'undefined')
6349		{
6350			RZalert('Input field does not preceed Spell Check Icon')
6351			return false;
6352		}
6353	}
6354
6355	var sURL = "/revize/spellcheck/spellingchecker.html";
6356
6357	features = 'width=490,height=400,scroll=auto,status=yes,resizable=yes,'
6358	         + 'titlebar=yes,menubar=no,location=no,'
6359	         + 'channelmode=0,directories=0,fullscreen=0,center=1'
6360
6361	RZspellcheckwin = window.open(sURL,'_blank',features);
6362	return true;
6363}
6364
6365/*-----------------------------------------------------------------------------
6366Replace webspace template embed keys
6367-----------------------------------------------------------------------------*/
6368RZ.mapsEmbedKey = "AIzaSyC5cMe92Yw3JgHrkvgIyHgdS2lTsH4C95k";
6369function RZcycleMapsKeys() {
6370	var oldMapsKey = "AIzaSyAOLPINIt8gtJpi00yqu4vHL9Ye6hhKDYI";
6371	var newMapsKey = RZ.mapsEmbedKey;
6372	document.querySelectorAll("iframe").forEach(function(ifr) {
6373		if (ifr.src.indexOf(oldMapsKey) > -1) { ifr.src = ifr.src.replaceAll(oldMapsKey, newMapsKey); }
6374	});
6375}
6376
6377function RZaddNoOpenerToBlankLinks() {
6378	document.querySelectorAll("a[target=_blank]:not([rel*=noopener]),a[target=_new]:not([rel*=noopener])").forEach(function(linkElement) {
6379		linkElement.setAttribute('rel', 'noopener');
6380	});
6381}
6382
6383document.addEventListener('DOMContentLoaded', function() {
6384	RZcycleMapsKeys();
6385	RZaddNoOpenerToBlankLinks();
6386});
6387
6388/*-----------------------------------------------------------------------------
6389Indicate script loaded for RZloadjscss()
6390-----------------------------------------------------------------------------*/
6391if (RZ.scriptLoaded)
6392	RZ.scriptLoaded.snippet_helper = true;
6393/************************* End of snippet_helper.js *************************/

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.