var jsuri = {
    version : 0.0,
    
    newlines : /(\r\n|\r|\n)/g,
    
    // By 'literal', that means, a non-interpreted string.
    // For example, the literal version of alert("line1\nline2");
    // would be alert("line1\\nline2"); so that the resulting URI 
    // would be javascript:alert(%22line1%5Cnline2%22)%3B
    // Another way to get a literal code string is js code from
    // textarea.value or AnonymousFunction.toString();
    
    createURIFromLiteralCodeString : function(s) {
        try {
            return "javascript:" + encodeURIComponent(s.replace(this.newlines, "\r\n"));
        } catch (e) {
            return "javascript:";
        }
    },
    
    createURIFromAnonymousFunction : function(func) {
        return this.createURIFromLiteralCodeString("(" + func.toString() + ")();");
    },
    
    createURIFromAnonymousFunctionWithArgs : function(func, args) {
        return this.createURIFromLiteralCodeString("(" +  func.toString() + ")(" + args + ");");
    },
    
    getLiteralCodeStringFromURI : function(uri) {
        if (uri.search(/javascript:/i) == 0) {
            try {
                return decodeURIComponent(uri.substr(11)).replace(this.newlines, "\n");
            } catch (e) {
                return "";
            }
        } else {
            return "";
        }  
    },
    
    executeURI : function(uri) {
        eval(this.getLiteralCodeStringFromURI(uri));
    },
    
    // javascript URIs don't have any reserved chars or delims, so
    // you can safely decode the whole URI so you the user can see
    // human-readable code.
    // Use the returned value to set window.status on hover for 
    // example.
    
    getStatusBarTextForURI : function(uri) {
        return "javascript:" + this.getLiteralCodeStringFromURI(uri);
    },
    
    // Take the value returned from getAttribute("href")
    // and resolve it. Use this when the browser's .href resolver 
    // decides to unescape %HH representing unreserved chars or 
    // wide chars on you and you'd like to retain the %HH as
    // they were authored, but still trim leading and
    // trailing spaces and encode chars that were not encoded
    // but should have been.
    
    resolveURIFromRawHrefAttribute : function(href) {
        var x = href.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
        if (x.search(/javascript:/i) != 0) {
            return "javascript:";
        }
        x = x.substr(11);
        var ret = "";
        var noencode = "%ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()";
        for (var i = 0; i < x.length; ++i) {
            var c = x.charAt(i);
            if (noencode.indexOf(c.toUpperCase()) == -1) {
                try {
                    ret += encodeURIComponent(c);
                } catch (e) {
                
                }
            } else {
                ret += c;
            }
        }
        return "javascript:" + ret;
    },
    
    // Get a value for Copy link address that's closer to 
    // how it was authored. See resolveURIFromRawHrefAttribute
    // for why you'd want to do this.
    
    getCopyLinkAddressValueFromRawHrefAttribute : function(href) {
        return this.resolveURIFromRawHrefAttribute(href);
    }
};
