/** * $Id: helpers.js 366 2007-11-24 02:27:32Z wingedfox $ * $HeadURL: https://svn.debugger.ru/repos/jslibs/BrowserExtensions/tags/BrowserExtensions.018/helpers.js $ * * File contains differrent helper functions * * @author Ilya Lebedev * @license LGPL * @version $Rev: 366 $ */ //----------------------------------------------------------------------------- // Variable/property checks //----------------------------------------------------------------------------- /** * Checks if property is undefined * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isUndefined (prop /* :Object */) /* :Boolean */ { return (typeof prop == 'undefined'); } /** * Checks if property is function * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isFunction (prop /* :Object */) /* :Boolean */ { return (typeof prop == 'function'); } /** * Checks if property is string * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isString (prop /* :Object */) /* :Boolean */ { return (typeof prop == 'string'); } /** * Checks if property is number * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isNumber (prop /* :Object */) /* :Boolean */ { return (typeof prop == 'number'); } /** * Checks if property is the calculable number * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isNumeric (prop /* :Object */) /* :Boolean */ { return (isNumber(prop)||isString(prop))&&!isNaN(parseInt(prop))&&isFinite(parseInt(prop)); } /** * Checks if property is array * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isArray (prop /* :Object */) /* :Boolean */ { return (prop instanceof Array); } /** * Checks if property is regexp * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isRegExp (prop /* :Object */) /* :Boolean */ { return (prop instanceof RegExp); } /** * Checks if property is a boolean value * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isBoolean (prop /* :Object */) /* :Boolean */ { return ('boolean' == typeof prop); } /** * Checks if property is a scalar value (value that could be used as the hash key) * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isScalar (prop /* :Object */) /* :Boolean */ { return isNumeric(prop)||isString(prop)||isBoolean(prop); } /** * Checks if property is empty * * @param {Object} prop value to check * @return {Boolean} true if matched * @scope public */ function isEmpty (prop /* :Object */) /* :Boolean */ { if (isBoolean(prop)) return false; if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) return true; if (isString(prop) || isNumber(prop)) return !prop; if (Boolean(prop)&&false != prop) { for (var i in prop) if(prop.hasOwnProperty(i)) return false } return true; } //----------------------------------------------------------------------------- // File paths functions //----------------------------------------------------------------------------- /** * used to glue path's * * @param {String} number of strings * @return {String} glued path * @scope public */ function gluePath () /* :String */ { var aL=arguments.length, i=aL-2, s = arguments[aL-1]; for(;i>=0;i--) s = ((!isString(arguments[i])&&!isNumber(arguments[i]))||isEmpty(arguments[i]) ?s :arguments[i]+'\x00'+s); return s?s.replace(/\/*\x00+\/*/g,"/"):""; } /** * return full path to the script * * @param {String} sname script name * @return {String, Null} mixed string full path or null * @scope public */ function findPath (sname /* :String */) /* :String */{ var h =document.getElementsByTagName('html')[0].innerHTML ,sr=new RegExp(']+?src\s*=\s*["\']?([^>]+?/)'+sname+'[^>]*>.?','i') ,m =h.match(sr); if (m) { /* * we've matched the full path */ if (m[1].match(/^((https?|file)\:\/{2,}|\w:[\\])/)) return m[1]; /* * we've matched absolute path from the site root */ if (m[1].indexOf("/")==0) return m[1]; b = document.getElementsByTagName('base'); if (b[0] && b[0].href) return b[0].href+m[1]; /* * return matching part of the document location and path to js file */ return (document.location.href.match(/(.*[\/\\])/)[0]+m[1]).replace(/^\/+/,""); } return null; } /** * return parsed query string for the specified script name * * @param {String} sname script name * @return {String, Null} mixed string full path or null * @scope public */ function getScriptQuery (sname) { var h =document.getElementsByTagName('html')[0].innerHTML ,sr=new RegExp(']+?src\s*[^>]+?/'+sname+'([^#"\']*).+?','i') ,m = h.match(sr); if (m) return parseQuery(m[1].replace(/^[^?]*\?([^#]+)/,"$1")); return {}; } /** * Function parses supplied query string and returns the hash with the values * Multiple values are stored in the array * * @param {String} q query string * @return {Object} * @scope public */ function parseQuery (q) { if ('string'!=typeof q || q.length<2) return {}; q = q.split(/&|&/g); for (var z=0,qL=q.length,rs={},kv,rkv;z|<[^>]*>/g,""); span.normalize(); tr[tr.length] = span.firstChild?span.firstChild.nodeValue.trim(" \xA0"):""; } else { tr[tr.length] = ""; } } } else { for (var z=0, tL=id.rows[i].cells.length; z|<[^>]*>/g,""); span.normalize(); tr[tr.length] = span.firstChild?span.firstChild.nodeValue.trim(" \xA0"):""; } } if (!isEmpty(tr)) res[res.length] = tr; } return res; } /** * Creates element all-at-once * * @param {String} tag name * @param {Object} p element properties { 'class' : 'className', * 'style' : { 'property' : value, ... }, * 'event' : { 'eventType' : handler, ... }, * 'child' : [ child1, child2, ...], * 'param' : { 'property' : value, ... }, * @return {HTMLElement} created element or null * @scope public */ document.createElementExt = function (tag /* :String */, p /* :Object */ ) /* :HTMLElement */{ var L, i, k, el = document.createElement(tag); if (!el) return null; for (i in p) { if (!p.hasOwnProperty(i)) continue; switch (i) { case "class" : el.setAttribute('className',p[i]); el.setAttribute('class',p[i]); break; case "style" : for (k in p[i]) { if (!p[i].hasOwnProperty(k)) continue; el.style[k] = p[i][k]; } break; case "event" : for (k in p[i]) { if (!p[i].hasOwnProperty(k)) continue; el.attachEvent(k,p[i][k]); } break; case "child" : L = p[i].length; for (k = 0; k-1) { cl = links[ll]; if (!cl.rel || cl.rel.toLowerCase() != 'stylesheet' || cl.src != sn) continue; return cl; } var link = document.createElementExt('link',{'param': { 'rel': 'stylesheet', 'type': 'text/css', 'href': sn}}) head.appendChild(link); return link; }