hledger-web 0.22.3 → 0.22.4
raw patch · 3 files changed
+165/−144 lines, 3 files
Files
- CHANGES.md +4/−0
- hledger-web.cabal +4/−4
- static/jquery.url.js +157/−140
CHANGES.md view
@@ -1,3 +1,7 @@+## 2014/2/10 hledger-web 0.22.4++* web: include the right unminified version of jquery.url.js (1.1) to avoid js breakage+ ## 2014/2/10 hledger-web 0.22.3 * web: fix version number reported by --version
hledger-web.cabal view
@@ -1,5 +1,5 @@ name: hledger-web-version: 0.22.3+version: 0.22.4 stability: beta category: Finance synopsis: A web interface for the hledger accounting tool.@@ -17,7 +17,7 @@ maintainer: Simon Michael <simon@joyful.com> homepage: http://hledger.org bug-reports: http://hledger.org/bugs-tested-with: GHC==7.4.2, GHC==7.6.3+tested-with: GHC==7.6.3 cabal-version: >= 1.8 build-type: Simple extra-tmp-files:@@ -71,7 +71,7 @@ Default: False library- cpp-options: -DVERSION="0.22.3"+ cpp-options: -DVERSION="0.22.4" if flag(dev) || flag(library-only) cpp-options: -DDEVELOPMENT @@ -162,7 +162,7 @@ if flag(library-only) Buildable: False - cpp-options: -DVERSION="0.22.3"+ cpp-options: -DVERSION="0.22.4" if flag(dev) cpp-options: -DDEVELOPMENT
static/jquery.url.js view
@@ -1,164 +1,181 @@-// JQuery URL Parser plugin - https://github.com/allmarkedup/jQuery-URL-Parser+// JQuery URL Parser // Written by Mark Perkins, mark@allmarkedup.com // License: http://unlicense.org/ (i.e. do what you want with it!) -;(function($, undefined) {- - var tag2attr = {- a : 'href',- img : 'src',- form : 'action',- base : 'href',- script : 'src',- iframe : 'src',- link : 'href'- },- - key = ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"], // keys available to query+jQuery.url = function()+{+ var segments = {}; - aliases = { "anchor" : "fragment" }, // aliases for backwards compatability-- parser = {- strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs- loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs- },+ var parsed = {}; - querystring_parser = /(?:^|&|;)([^&=;]*)=?([^&;]*)/g, // supports both ampersand and semicolon-delimted query string key/value pairs+ /**+ * Options object. Only the URI and strictMode values can be changed via the setters below.+ */+ var options = { - fragment_parser = /(?:^|&|;)([^&=;]*)=?([^&;]*)/g; // supports both ampersand and semicolon-delimted fragment key/value pairs+ url : window.location, // default URI is the page in which the script is running+ + strictMode: false, // 'loose' parsing by default - function parseUri( url, strictMode )- {- var str = decodeURI( url ),- res = parser[ strictMode || false ? "strict" : "loose" ].exec( str ),- uri = { attr : {}, param : {}, seg : {} },- i = 14;+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], // keys available to query - while ( i-- )- {- uri.attr[ key[i] ] = res[i] || "";- }+ q: {+ name: "queryKey",+ parser: /(?:^|&|;)([^&=;]*)=?([^&;]*)/g+ }, - // build query and fragment parameters+ parser: {+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs+ } - uri.param['query'] = {};- uri.param['fragment'] = {};+ };+ + /**+ * Deals with the parsing of the URI according to the regex above.+ * Written by Steven Levithan - see credits at top.+ */ + var parseUri = function()+ {+ str = decodeURI( options.url ); - uri.attr['query'].replace( querystring_parser, function ( $0, $1, $2 ){- if ($1)- {- uri.param['query'][$1] = $2;+ var m = options.parser[ options.strictMode ? "strict" : "loose" ].exec( str );+ var uri = {};+ var i = 14;++ while ( i-- ) {+ uri[ options.key[i] ] = m[i] || "";+ }++ uri[ options.q.name ] = {};+ uri[ options.key[12] ].replace( options.q.parser, function ( $0, $1, $2 ) {+ if ($1) {+ uri[options.q.name][$1] = $2; } });- - uri.attr['fragment'].replace( fragment_parser, function ( $0, $1, $2 ){- if ($1)++ return uri;+ };++ /**+ * Returns the value of the passed in key from the parsed URI.+ * + * @param string key The key whose value is required+ */ + var key = function( key )+ {+ if ( jQuery.isEmptyObject(parsed) )+ {+ setUp(); // if the URI has not been parsed yet then do this first... + } + if ( key == "base" )+ {+ if ( parsed.port !== null && parsed.port !== "" ) {- uri.param['fragment'][$1] = $2;+ return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/"; }- });- - // split path and fragement into segments- - uri.seg['path'] = uri.attr.path.replace(/^\/+|\/+$/g,'').split('/');- - uri.seg['fragment'] = uri.attr.fragment.replace(/^\/+|\/+$/g,'').split('/');- - // compile a 'base' domain attribute- - uri.attr['base'] = uri.attr.host ? uri.attr.protocol+"://"+uri.attr.host + (uri.attr.port ? ":"+uri.attr.port : '') : '';- - return uri;+ else+ {+ return parsed.protocol+"://"+parsed.host+"/";+ }+ }+ + return ( parsed[key] === "" ) ? null : parsed[key]; }; - function getAttrName( elm )+ /**+ * Returns the value of the required query string parameter.+ * + * @param string item The parameter whose value is required+ */ + var param = function( item ) {- var tn = elm.tagName;- if ( tn !== undefined ) return tag2attr[tn.toLowerCase()];- return tn;- }- - $.fn.url = function( strictMode )+ if ( jQuery.isEmptyObject(parsed) )+ {+ setUp(); // if the URI has not been parsed yet then do this first... + }+ if ( item === undefined )+ {+ return parsed.queryKey;+ }+ else+ {+ return ( parsed.queryKey[item] === null ) ? null : parsed.queryKey[item];+ }+ };++ /**+ * 'Constructor' (not really!) function.+ * Called whenever the URI changes to kick off re-parsing of the URI and splitting it up into segments. + */ + var setUp = function() {- var url = '';- - if ( this.length )- {- url = $(this).attr( getAttrName(this[0]) ) || '';- }- - return $.url({ url : url, strict : strictMode });+ parsed = parseUri();+ + getSegments(); }; - $.url = function( opts )+ /**+ * Splits up the body of the URI into segments (i.e. sections delimited by '/')+ */+ var getSegments = function() {- var url = '',- strict = false;-- if ( typeof opts === 'string' )- {- url = opts;- }- else- {- opts = opts || {};- strict = opts.strict || strict;- url = opts.url === undefined ? window.location.toString() : opts.url;- }- - return {- - data : parseUri(url, strict),- - // get various attributes from the URI- attr : function( attr )- {- attr = aliases[attr] || attr;- return attr !== undefined ? this.data.attr[attr] : this.data.attr;- },- - // return query string parameters- param : function( param )- {- return param !== undefined ? this.data.param.query[param] : this.data.param.query;- },- - // return fragment parameters- fparam : function( param )- {- return param !== undefined ? this.data.param.fragment[param] : this.data.param.fragment;- },- - // return path segments- segment : function( seg )- {- if ( seg === undefined )- {- return this.data.seg.path; - }- else- {- seg = seg < 0 ? this.data.seg.path.length + seg : seg - 1; // negative segments count from the end- return this.data.seg.path[seg]; - }- },- - // return fragment segments- fsegment : function( seg )- {- if ( seg === undefined )- {- return this.data.seg.fragment; - }- else- {- seg = seg < 0 ? this.data.seg.fragment.length + seg : seg - 1; // negative segments count from the end- return this.data.seg.fragment[seg]; - }- }- - };- + var p = parsed.path;+ segments = []; // clear out segments array+ segments = parsed.path.length == 1 ? {} : ( p.charAt( p.length - 1 ) == "/" ? p.substring( 1, p.length - 1 ) : path = p.substring( 1 ) ).split("/"); }; -})(jQuery);+ return {+ + /**+ * Sets the parsing mode - either strict or loose. Set to loose by default.+ *+ * @param string mode The mode to set the parser to. Anything apart from a value of 'strict' will set it to loose!+ */+ setMode : function( mode )+ {+ options.strictMode = mode == "strict" ? true : false;+ return this;+ },+ + /**+ * Sets URI to parse if you don't want to to parse the current page's URI.+ * Calling the function with no value for newUri resets it to the current page's URI.+ *+ * @param string newUri The URI to parse.+ */ + setUrl : function( newUri )+ {+ options.url = newUri === undefined ? window.location : newUri;+ setUp();+ return this;+ }, + + /**+ * Returns the value of the specified URI segment. Segments are numbered from 1 to the number of segments.+ * For example the URI http://test.com/about/company/ segment(1) would return 'about'.+ *+ * If no integer is passed into the function it returns the number of segments in the URI.+ *+ * @param int pos The position of the segment to return. Can be empty.+ */ + segment : function( pos )+ {+ if ( jQuery.isEmptyObject(parsed) )+ {+ setUp(); // if the URI has not been parsed yet then do this first... + } + if ( pos === undefined )+ {+ return segments.length;+ }+ return ( segments[pos] === "" || segments[pos] === undefined ) ? null : segments[pos];+ },+ + attr : key, // provides public access to private 'key' function - see above+ + param : param // provides public access to private 'param' function - see above+ + };+ +}();