/** * EGroupware clientside API object * * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @package etemplate * @subpackage api * @link http://www.egroupware.org * @author Andreas Stöckel (as AT stylite.de) * @author Ralf Becker <RalfBecker@outdoor-training.de> * @version $Id$ */ "use strict"; /*egw:uses egw_core; */ egw.extend('utils', egw.MODULE_GLOBAL, function() { function json_escape_string(input) { var len = input.length; var res = ""; for (var i = 0; i < len; i++) { switch (input.charAt(i)) { case '"': res += '\\"'; break; case '\n': res += '\\n'; break; case '\r': res += '\\r'; break; case '\\': res += '\\\\'; break; case '\/': res += '\\/'; break; case '\b': res += '\\b'; break; case '\f': res += '\\f'; break; case '\t': res += '\\t'; break; default: res += input.charAt(i); } } return res; } function json_encode_simple(input) { switch (input.constructor) { case String: return '"' + json_escape_string(input) + '"'; case Number: return input.toString(); case Boolean: return input ? 'true' : 'false'; default: return null; } } function json_encode(input) { if (input == null || !input && input.length == 0) return 'null'; var simple_res = json_encode_simple(input); if (simple_res == null) { switch (input.constructor) { case Array: var buf = []; for (var k in input) { //Filter non numeric entries if (!isNaN(k)) buf.push(json_encode(input[k])); } return '[' + buf.join(',') + ']'; case Object: var buf = []; for (var k in input) { buf.push(json_encode_simple(k) + ':' + json_encode(input[k])); } return '{' + buf.join(',') + '}'; default: switch(typeof input) { case 'array': var buf = []; for (var k in input) { //Filter non numeric entries if (!isNaN(k)) buf.push(json_encode(input[k])); } return '[' + buf.join(',') + ']'; case 'object': var buf = []; for (var k in input) { buf.push(json_encode_simple(k) + ':' + json_encode(input[k])); } return '{' + buf.join(',') + '}'; } return 'null'; } } else { return simple_res; } } var uid_counter = 0; // Create the utils object which contains references to all functions // covered by it. var utils = { ajaxUrl: function(_menuaction) { return this.webserverUrl + '/json.php?menuaction=' + _menuaction; }, elemWindow: function(_elem) { var res = _elem.ownerDocument.parentNode || _elem.ownerDocument.defaultView; return res; }, uid: function() { return (uid_counter++).toString(16); }, /** * Decode encoded vfs special chars * * @param string _path path to decode * @return string */ decodePath: function(_path) { return decodeURIComponent(_path); }, /** * Encode vfs special chars excluding / * * @param string _path path to decode * @return string */ encodePath: function(_path) { var components = _path.split('/'); for(var n=0; n < components.length; n++) { components[n] = this.encodePathComponent(components[n]); } return components.join('/'); }, /** * Encode vfs special chars removing / * * //'%' => '%25', // % should be encoded, but easily leads to double encoding, therefore better NOT encodig it * '#' => '%23', * '?' => '%3F', * '/' => '', // better remove it completly * * @param string _path path to decode * @return string */ /* */ encodePathComponent: function(_comp) { return _comp.replace(/#/g,'%23').replace(/\?/g,'%3F').replace(/\//g,''); }, /** * If an element has display: none (or a parent like that), it has no size. * Use this to get its dimensions anyway. * * @param element HTML element * @param boolOuter Pass true to get outerWidth() / outerHeight() instead of width() / height() * * @return Object [w: width, h: height] * * @author Ryan Wheale * @see http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/ */ getHiddenDimensions: function(element, boolOuter) { var $item = $j(element); var props = { position: "absolute", visibility: "hidden", display: "block" }; var dim = { "w":0, "h":0 , "left":0, "top":0}; var $hiddenParents = $item.parents().andSelf().not(":visible"); var oldProps = []; $hiddenParents.each(function() { var old = {}; for ( var name in props ) { old[ name ] = this.style[ name ]; } $j(this).show(); oldProps.push(old); }); dim.w = (boolOuter === true) ? $item.outerWidth() : $item.width(); dim.h = (boolOuter === true) ? $item.outerHeight() : $item.height(); dim.top = $item.offset().top; dim.left = $item.offset().left; $hiddenParents.each(function(i) { var old = oldProps[i]; for ( var name in props ) { this.style[ name ] = old[ name ]; } }); //$.log(”w: ” + dim.w + ”, h:” + dim.h) return dim; } }; // Check whether the browser already supports encoding JSON -- if yes, use // its implementation, otherwise our own if (typeof window.JSON !== 'undefined' && typeof window.JSON.stringify !== 'undefined') { utils["jsonEncode"] = JSON.stringify; } else { utils["jsonEncode"] = json_encode; } // Return the extension return utils; });