1 /*
  2  *  Copyright (C) 2008-2009 WaveMaker Software, Inc.
  3  *
  4  *  This file is part of the WaveMaker Client Runtime.
  5  *
  6  *  Licensed under the Apache License, Version 2.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
  9  *
 10  *      http://www.apache.org/licenses/LICENSE-2.0
 11  *
 12  *  Unless required by applicable law or agreed to in writing, software
 13  *  distributed under the License is distributed on an "AS IS" BASIS,
 14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  *  See the License for the specific language governing permissions and
 16  *  limitations under the License.
 17  */
 18 dojo.provide('wm.base.lib.util');
 19 
 20 /**
 21 	@namespace Master namespace for all WaveMaker library objects.
 22 */
 23 wm = window["wm"] || {};
 24 
 25 // simple logging
 26 wm.logErrors = false;
 27 wm.log = function() {
 28 	console.log.apply(console, arguments);
 29 }
 30 
 31 // strings
 32 
 33 wm.capitalize = function(s) {
 34 	return s ? s.charAt(0).toUpperCase() + s.slice(1) : "";
 35 }
 36 
 37 wm.decapitalize = function(s) {
 38 	return s ? s.charAt(0).toLowerCase() + s.slice(1) : "";
 39 }
 40 
 41 wm.compareStrings = function(a, b) {
 42 	return a < b ? -1 : a == b ? 0 : 1;
 43 }
 44 
 45 wm.toTitleCase = function(s){
 46 	return s.replace(/\b\w+\b/g, function(word) {
 47 		return word ? word.charAt(0).toUpperCase() + (word.slice(1) || "").toLowerCase() : "";
 48 	}); 
 49 }
 50 
 51 wm.delimCat = function(inPrefix, inSuffix, inDelim) {
 52 	return inPrefix + (inPrefix && inSuffix ? inDelim : "") + inSuffix;
 53 }
 54 
 55 wm.joinEx = function(inValues, inDelim) {
 56 	var i = 0;
 57 	while (i < inValues.length) {
 58 		if (inValues[i++] !== "")
 59 			inValues.splice(--i, 1);
 60 	}
 61 	return inValues.join(inDelim);
 62 }
 63 
 64 // number
 65 
 66 wm.isNumber = function(v) {
 67 	return (typeof v == 'number') || (v instanceof Number);
 68 }
 69 
 70 wm.compareNumbers = function(a, b) {
 71 	var na = wm.isNumber(a), nb = wm.isNumber(b);
 72 	return na && nb ? a - b : (na ? -1 : (nb ? 1 : 0));
 73 }
 74 
 75 // lang
 76 
 77 wm.nop = function() {};
 78 
 79 wm.isEmpty = function(inObj) {
 80 	for (var i in inObj)
 81 		return false;
 82 	return true;
 83 }
 84 
 85 wm.fire = function(obj, method, args) {
 86 	var f = obj && method && obj[method];
 87 	if (f) 
 88 		return args ? f.apply(obj, args) : f.call(obj);
 89 }
 90 
 91 wm.async = function(f, delay) {
 92 	return function(){setTimeout(f, delay || 1);};
 93 }
 94 
 95 wm.forEach = function(inObject, inFunc) {
 96 	if (dojo.isArray(inObject))
 97 		dojo.forEach(inObject, inFunc);
 98 	else
 99 		wm.forEachProperty(inObject, inFunc);
100 }
101 
102 wm.forEachProperty = function(inObject, inFunc) {
103 	for (var i in inObject) {
104 			inFunc(inObject[i], i);
105 	}
106 }
107 
108 wm.evalJs = function(inJavascript, inDefault) {
109 	var r = inDefault || "";
110 	try {
111 		r = eval(inJavascript);
112 	} catch(e) {
113 		wm.logging && console.log("Error evaluating Javascript:", e);
114 	}
115 	return r;
116 };
117 
118 wm.getClassProp = function(inClassName, inProp) {
119 	var klass = dojo.getObject(inClassName);
120 	var ptype = klass && klass.prototype;
121 	return ptype && ptype[inProp];
122 }
123 
124 // DOM
125 
126 wm.showHideNode = function(inNode, inTrueToShow) {
127 	inNode.style.display = inTrueToShow ? "" : "none";
128 };
129 
130 wm.kids = function(inNode, inTag) {
131 	var result = [], t=inTag.toUpperCase();
132 	for (var i=0, n; (n=inNode.childNodes[i]); i++) 
133 		if (n.tagName == inTag) 
134 			result.push(n);
135 	return result;
136 }
137 
138 wm.divkids = function(inNode) {
139 	return wm.kids(inNode, 'div');
140 }
141 
142 wm.clearSelection = function() {
143 	try{
144 		if (window.getSelection) 
145 			window.getSelection().collapseToEnd();
146 		else if (document.selection) 
147 			document.selection.clear();
148 	}catch(e){
149 	}
150 }
151 
152 wm.focusOnIdle = function(inNode) {
153 	setTimeout(function() {
154 		try {
155 			wm.fire(inNode, "focus");
156 			wm.fire(inNode, "select");
157 		} catch(e) {};
158 	}, 1);
159 }
160 
161 wm.inScrollbar = function(e) {
162 	var t = e.target;
163 	var s = t.style && dojo.getComputedStyle(t);
164 	return  s && (
165 		((s.overflow != 'hidden' || s.overflowX != 'hidden') && (t.scrollWidth != t.offsetWidth) && (t.offsetWidth - 19 - e.clientX < 0)) ||
166 		((s.overflow != 'hidden' || s.overflowY != 'hidden') && (t.scrollHeight != t.offsetHeight) && (t.offsetHeight - 19 - e.clientY < 0))
167 	);
168 };
169 
170 wm.preloadImage = function(inPath) {
171 	var i = new Image();
172 	i.src = inPath;
173 	(wm.preloaded = (wm.preloaded || [])).push(i);
174 }
175 
176 // style
177 
178 wm.setUnitsBox = function(node, l, t, w, h) {
179 	with (node.style) {
180 		l&&(left = l);
181 		t&&(top = t);
182 		w&&(width = w);
183 		h&&(height = h);
184 	}
185 }
186 
187 wm.getNaturalBox = function(node){
188 	var tn = node.tagName, cs = dojo.getComputedStyle(node), box = dojo._getContentBox(node, cs);
189 	if(tn=="BUTTON" || tn=="TABLE"){
190 		var pb = dojo._getPadBorderExtents(node, cs);
191 		box.w += pb.w;
192 		box.h += pb.h;
193 	}
194 	return box;
195 }
196 
197 wm.calcOffset = function(inNode, inAncestor, inAdjustMargin) {
198 	var o = { x:0, y: 0}, n = inNode, cs, mb, be;
199 	while (n && n != inAncestor && n != document) {
200 		cs = dojo.getComputedStyle(n);
201 		mb = dojo._getMarginBox(n, cs);
202 		be = dojo._getBorderExtents(n, cs);
203 		me = inAdjustMargin ? dojo._getMarginExtents(n, cs) : {l:0, t:0};
204 		o.x += mb.l + be.l + me.l - (n.scrollLeft || 0);
205 		o.y += mb.t + be.t + me.t - (n.scrollTop || 0);
206 		n = n.parentNode;
207 	}
208 	return o;
209 }
210 
211 wm.addRemoveClass = function(node, classn, addRemove) {
212 	dojo[addRemove ? "addClass" : "removeClass"](node, classn);
213 }
214 
215 // misc
216 
217 wm.onidle = function(/*hitch args*/) {
218 	return setTimeout(dojo.hitch.apply(dojo, arguments), 1);
219 }
220 
221 wm.job = function(inName, inDelay, inJob) {
222 	wm.cancelJob(inName);
223 	var job = function() {
224 		delete wm._jobs[inName];
225 		inJob();
226 	}
227 	wm._jobs[inName] = setTimeout(job, inDelay);
228 }
229 wm.cancelJob = function(inName) {
230 	clearTimeout(wm._jobs[inName]);
231 }
232 wm._jobs = [ ];
233 
234 wm.connectEvents = function(inObject, inNode, inEvents) {
235 	// FIXME: maybe remove this at some point
236 	if (!dojo.isArray(inEvents)){throw("wm.connectEvents: event list must be an array (did you use variable args?)")};
237 	var links = [];
238 	for (var i=0, e; (e=inEvents[i]); i++) {
239 		links.push(dojo.connect(inNode, 'on' + e, inObject, e));
240 	}
241 	return links;
242 }
243 
244 wm._isUniqueName = function(inName, inNameSpaces) {
245 	for (var j=0, s; (s=inNameSpaces[j]); j++) 
246 		if (inName in s)
247 			return false;
248 	return true;
249 }
250 
251 wm.findUniqueName = function(inName, inNameSpaces) {
252 	if (wm._isUniqueName(inName, inNameSpaces))
253 		return inName;
254 	var m = (inName || '').match(/([^\d]*)([\d]*)/);
255 	var i = m[2] || 1, n0 = m[1] || 'noname';
256 	do { 
257 		inName = n0 + (i > 0 ? i : ''); 
258 		i++; 
259 	} while (!wm._isUniqueName(inName, inNameSpaces));
260 	return inName;
261 }
262 
263 wm.getValidJsName = function(inName) {
264 	var dc = "_";
265 	inName = inName.replace(new RegExp("[- ]", "g"), dc);
266 	inName = inName.replace(new RegExp("[^a-zA-Z0-9_]", "g"), "");
267 	if (inName.match(new RegExp("^[0-9]")) || !inName)
268 		inName = dc + inName;
269 	return inName;
270 }
271 
272 wm._modules = [];
273 wm.loadModule = function(inModule) {
274 	if (!wm._modules[inModule]) {
275 		tag = [ '<scrip', 't type="text/javascript" src="', inModule, '.js"></scrip', 't>' ].join('');
276 		document.write(tag);
277 		wm._modules[inModule] = true;
278 	}
279 }
280 
281 wm.widgetIsShowing = function(inWidget) {
282 	var w = inWidget, p;
283 	while (w) {
284 		p = w.parent;
285 		if (!w.showing || (w.isActive && !w.isActive()))
286 			return false;
287 		w = p;
288 	}
289 	return true;
290 }
291 
292 wm.forEachWidget = function(inWidget, inFunc, inIgnoreBuiltin) {
293 	if (inFunc&&inFunc(inWidget) === false)
294 		return false;
295 	for (var i=0, ws = inWidget.getOrderedWidgets(), r, w; w=ws[i]; i++) {
296 		r = w.forEachWidget && !inIgnoreBuiltin ? w.forEachWidget(inFunc) : wm.forEachWidget(w, inFunc, inIgnoreBuiltin);
297 		if (r === false)
298 			return false;
299 	}
300 }
301 
302 // themes
303 wm.theme = {
304 	getPath: function() {
305 			return dojo.moduleUrl("wm.base","widget/themes/" + "default/");
306 	},
307 	getImagesPath: function() {
308 		return wm.theme.getPath() + "images/";
309 	}
310 };
311