1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 
 25 /**
 26  * 
 27  * 
 28  * @private
 29  */
 30 XFG = function() {} // XFormGlobal
 31 
 32 XFG.prefixList = {};
 33 XFG.objectCache = {};
 34 XFG.getUniqueId = function (namePrefix) {
 35 	if (namePrefix == null) namePrefix = "__id__";
 36 	var list = XFG.prefixList;
 37 
 38 	// if we've never seen one of these before, call it the name they passed in
 39 	//	(without a number) and set the counter to 1 (so the next one is #2)
 40 	if (list[namePrefix] == null) {
 41 		list[namePrefix] = 1;
 42 		return namePrefix;
 43 	} else {
 44 		list[namePrefix]++;
 45 		return namePrefix + "_" + list[namePrefix];
 46 	}
 47 };
 48 
 49 XFG.assignUniqueId = function (object, namePrefix) {
 50 	var id = XFG.getUniqueId(namePrefix);
 51 	object.__id = id;
 52 	XFG.objectCache[id] = object;
 53 };
 54 
 55 XFG.cacheGet = function (id){
 56 	return XFG.objectCache[id];
 57 }
 58 
 59 XFG.createEl = function (id, parentEl, tagName, contents) {
 60 	// create the element
 61 	if (tagName == null) tagName = "div";
 62 	var el = window.document.createElement(tagName);
 63 
 64 	// set its id and contents (if supplied)
 65 	el.id = id;
 66 	if (contents != null) el.innerHTML = contents;
 67 
 68 	// root it under the parent
 69 	if (parentEl == null) {
 70 		parentEl = document.body;
 71 	}
 72 	parentEl.appendChild(el);
 73 	
 74 	return el;
 75 }
 76 
 77 XFG.getEl = function (id, frame) {
 78 	// if they passed something other than a string, assume its the element itself
 79 	if (typeof id != "string") return id;
 80 	
 81 	var doc = (doc == null ? document : frame.document);
 82 	var it = doc.getElementById(id);
 83 	if (it == null) it = null;
 84 	return it;
 85 };
 86 
 87 XFG.hideEl = function (id,isBlock) {
 88 	var el = (typeof id == "string" ? XFG.getEl(id) : id);
 89 	if (el) {
 90 		if(!isBlock)
 91 			el.style.display = "none";
 92 			
 93 		el.style.visibility = "hidden";
 94 	} else {
 95 		DBG.println("hideEl(", id, "): element not found");
 96 	}
 97 };
 98 
 99 XFG.showEl = function (id) {
100 	var el = (typeof id == "string" ? XFG.getEl(id) : id);
101 	if (el) {
102 		if (el.tagName == "TD") {
103 			el.style.display = "table-cell";
104 		} else {
105 			el.style.display = "block";
106 		}
107 		el.style.visibility = "visible";
108 	} else {
109 		DBG.println("showEl(", id, "): element not found");
110 	}
111 };
112 
113 XFG.getClassName = function(element) {
114 	if (typeof element == "string") element = XFG.getEl(element);
115 	if (element) return element.className;
116 	return "";
117 };
118 
119 XFG.showSelected = function (element) {
120 	XFG.setClassName(element, XFG.addSuffix(XFG.getClassName(element), "_selected"));
121 };
122 
123 XFG.hideSelected = function (element) {
124 	XFG.setClassName(element, XFG.removeSuffix(XFG.getClassName(element), "_selected"));
125 };
126 
127 XFG.setClassName = function (element, className) {
128 	if (typeof element == "string") element = XFG.getEl(element);
129 	if (element) element.className = className;
130 };
131 
132 XFG.addSuffix = function (text, suffix) {
133 	if (text.indexOf(suffix) > -1) return text;
134 	return text + suffix;
135 };
136 
137 XFG.removeSuffix = function (text, suffix) {
138 	if (text.indexOf(suffix) < 0) return text;
139 	return text.substring(0, text.indexOf(suffix));	
140 };
141 
142 XFG.showOver = function (element) {
143 	XFG.setClassName(element, XFG.addSuffix(XFG.getClassName(element), "_over"));
144 };
145 
146 XFG.hideOver = function (element) {
147 	XFG.setClassName(element, XFG.removeSuffix(XFG.getClassName(element), "_over"));
148 }
149 
150 
151 XFG.showDisabled = function (element) {
152 	XFG.setClassName(element, XFG.addSuffix(XFG.getClassName(element), "_disabled"));
153 };
154 
155 XFG.hideDisabled = function (element) {
156 	XFG.setClassName(element, XFG.removeSuffix(XFG.getClassName(element), "_disabled"));
157 }
158 
159 
160 
161 /* StringBuffer class  changed to AjxBuffer and moved into Ajax/js/util/  */
162 
163 
164 
165 XFG.getCookie = function (name) {
166 	var value = new RegExp(name + "=([^;]+)").exec(document.cookie);
167 	return (value != null) ? unescape(value[1]) : null;
168 }
169 
170 
171 XFG.setCookie = function (name, value) { // use: setCookie("name", value);
172 	document.cookie = name + "=" + escape(value);
173 }
174 
175 
176 
177 
178 XFG.valueToString = function (value, skipDerivedProperties, skipMethods, skipPrototypeProperties) {
179 	if (value == null) return "null";
180 
181 	// strings get quotes
182 	if (typeof value == "string") return '"' + value + '"';
183 
184 	// for arrays, list all the objects in it
185 	if (value instanceof Array) {
186 		var buffer = new AjxBuffer();
187 		for (var i = 0; i < value.length; i++) {
188 			buffer.append("        ", XFG.valueToString(value[i], "    ", skipDerivedProperties, skipMethods, skipPrototypeProperties));
189 		}
190 		return "[\n" + buffer.join(",\n") + "\n" + "    ]";
191 	}
192 
193 	// for dates, return the syntax to create a new date (might as well)
194 	if (value instanceof Date) {
195 		return " new Date("+ [value.getFullYear(), value.getMonth(), value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds()].join(",") + ")";
196 	}
197 	
198 	if (typeof value == "function") {
199 		return "(function)";
200 	}
201 
202 	// for objects, call
203 	if (typeof value == "object") return XFG.objectToString(value, "    ", skipDerivedProperties, skipMethods, skipPrototypeProperties);
204 	
205 	return value;	
206 }
207 
208 XFG.objectToString = function (object, skipDerivedProperties, skipMethods, skipPrototypeProperties) {
209 
210 	var indentSpacer = "    ";
211 	var buffer = [];
212 	var hasObject = false;
213 	var propCount = 0;
214 	var proto = object.constructor.prototype;
215 
216 	if (proto == null) proto = {};
217 	for (var prop in object) {
218 		var value = object[prop];
219 		if (skipPrototypeProperties && (object[prop] == proto[prop])) continue;
220 		if (skipMethods && value instanceof Function) continue;
221 		
222 		// if we have a derived property, write its id or [object] so we don't recurse too much
223 		if ((prop.indexOf("__") == 0 || prop.indexOf("$") == 0) && value instanceof Object) {
224 			buffer.push(AjxBuffer.concat(prop, ": ", value.toString()));
225 		} else {
226 			hasObject = hasObject || (typeof value == "object");
227 			buffer.push(AjxBuffer.concat(prop, ": ", XFG.valueToString(value, skipDerivedProperties, skipMethods, skipPrototypeProperties)));
228 		}
229 		propCount++;
230 	}
231 	buffer.sort(XFG.sortSpecialLast);
232 	if (hasObject || propCount > 5) {
233 		return "{\n" + indentSpacer + buffer.join(",\n"+ indentSpacer) + "\n" + "}"
234 	} else {
235 		return "{" + indentSpacer + buffer.join(", ") + indentSpacer + "}";
236 	}
237 }
238 
239 XFG.sortSpecialLast = function (a,b) {
240 	var a1 = a.charAt(0);
241 	var b1 = b.charAt(0);
242 	var aIsSpecial = a1 == "_" || a1 == "$";
243 	var bIsSpecial = b1 == "_" || b1 == "$";
244 	if ( !aIsSpecial && !bIsSpecial) {
245 		return (a > b ? 1 : -1)
246 	} else if (aIsSpecial && bIsSpecial) {
247 		return (a > b ? 1 : -1)
248 	} else if (aIsSpecial) {
249 		return 1;
250 	} else {
251 		return -1;
252 	}
253 	
254 }
255 
256 
257 
258 /* DEPRECATED:  Use AjxBuffer() instead */
259 StringBuffer = function() {
260 	this.clear();
261 	if (arguments.length > 0) {
262 		arguments.join = this.buffer.join;
263 		this.buffer[this.buffer.length] = arguments.join("");
264 	}
265 }
266 StringBuffer.prototype.toString = function () {
267 	return this.buffer.join("");
268 }
269 StringBuffer.prototype.join = function (delim) {
270 	if (delim == null) delim = "";
271 	return this.buffer.join(delim);
272 }
273 StringBuffer.prototype.append = function () {
274 	arguments.join = this.buffer.join;
275 	this.buffer[this.buffer.length] = arguments.join("");
276 }
277 StringBuffer.prototype.join = function (str) {
278 	return this.buffer.join(str);
279 }
280 StringBuffer.prototype.set = function(str) {
281 	this.buffer = [str];
282 }
283 StringBuffer.prototype.clear = function() {
284 	this.buffer = [];
285 }
286 StringBuffer.concat = function() {
287 	arguments.join = Array.prototype.join;
288 	return arguments.join("");
289 }
290 
291 XFG.ARROW_DOWN = 40;
292 XFG.ARROW_LEFT = 37;
293 XFG.ARROW_RIGHT = 39;
294 XFG.ARROW_UP = 38;	
295