      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