X-Git-Url: http://git.onelab.eu/?p=myops.git;a=blobdiff_plain;f=web%2Fquery%2Fvendor%2Fcouchapp%2F_attachments%2Fjquery.pathbinder.js;fp=web%2Fquery%2Fvendor%2Fcouchapp%2F_attachments%2Fjquery.pathbinder.js;h=89f0dd4d91da6113f641ba0524c5e6334d944ea3;hp=0000000000000000000000000000000000000000;hb=85070b3d456667f238051af1a2f1f2a0c12300ab;hpb=607f0e13927eb18075c375fa9ba5527da4fcbb44 diff --git a/web/query/vendor/couchapp/_attachments/jquery.pathbinder.js b/web/query/vendor/couchapp/_attachments/jquery.pathbinder.js new file mode 100644 index 0000000..89f0dd4 --- /dev/null +++ b/web/query/vendor/couchapp/_attachments/jquery.pathbinder.js @@ -0,0 +1,174 @@ +(function($) { + // functions for handling the path + // thanks sammy.js + var PATH_REPLACER = "([^\/]+)", + PATH_NAME_MATCHER = /:([\w\d]+)/g, + QUERY_STRING_MATCHER = /\?([^#]*)$/, + SPLAT_MATCHER = /(\*)/, + SPLAT_REPLACER = "(.+)", + _currentPath, + _lastPath, + _pathInterval; + + function hashChanged() { + _currentPath = getPath(); + // if path is actually changed from what we thought it was, then react + if (_lastPath != _currentPath) { + _lastPath = _currentPath; + return triggerOnPath(_currentPath); + } + } + + $.pathbinder = { + changeFuns : [], + paths : [], + begin : function(defaultPath) { + // this should trigger the defaultPath if there's not a path in the URL + // otherwise it should trigger the URL's path + $(function() { + var loadPath = getPath(); + if (loadPath) { + triggerOnPath(loadPath); + } else { + goPath(defaultPath); + triggerOnPath(defaultPath); + } + }) + }, + go : function(path) { + goPath(path); + triggerOnPath(path); + }, + currentPath : function() { + return getPath(); + }, + onChange : function (fun) { + $.pathbinder.changeFuns.push(fun); + } + }; + + function pollPath(every) { + function hashCheck() { + _currentPath = getPath(); + // path changed if _currentPath != _lastPath + if (_lastPath != _currentPath) { + setTimeout(function() { + $(window).trigger('hashchange'); + }, 1); + } + }; + hashCheck(); + _pathInterval = setInterval(hashCheck, every); + $(window).bind('unload', function() { + clearInterval(_pathInterval); + }); + } + + function triggerOnPath(path) { + path = path.replace(/^#/,''); + $.pathbinder.changeFuns.forEach(function(fun) {fun(path)}); + var pathSpec, path_params, params = {}, param_name, param; + for (var i=0; i < $.pathbinder.paths.length; i++) { + pathSpec = $.pathbinder.paths[i]; + // $.log("pathSpec", pathSpec); + if ((path_params = pathSpec.matcher.exec(path)) !== null) { + // $.log("path_params", path_params); + path_params.shift(); + for (var j=0; j < path_params.length; j++) { + param_name = pathSpec.param_names[j]; + param = decodeURIComponent(path_params[j]); + if (param_name) { + params[param_name] = param; + } else { + if (!params.splat) params.splat = []; + params.splat.push(param); + } + }; + pathSpec.callback(params); + // return true; // removed this to allow for multi match + } + }; + }; + + // bind the event + $(function() { + if ('onhashchange' in window) { + // we have a native event + } else { + pollPath(10); + } + // setTimeout(hashChanged,50); + $(window).bind('hashchange', hashChanged); + }); + + function registerPath(pathSpec) { + $.pathbinder.paths.push(pathSpec); + }; + + function setPath(pathSpec, params) { + var newPath = $.mustache(pathSpec.template, params); + goPath(newPath); + }; + + function goPath(newPath) { + if (newPath) { + // $.log("goPath", newPath) + window.location = '#'+newPath; + } + _lastPath = getPath(); + }; + + function getPath() { + var matches = window.location.toString().match(/^[^#]*(#.+)$/); + return matches ? matches[1] : ''; + }; + + function makePathSpec(path, callback) { + var param_names = []; + var template = ""; + + PATH_NAME_MATCHER.lastIndex = 0; + + while ((path_match = PATH_NAME_MATCHER.exec(path)) !== null) { + param_names.push(path_match[1]); + } + + return { + param_names : param_names, + matcher : new RegExp("^" + path.replace( + PATH_NAME_MATCHER, PATH_REPLACER).replace( + SPLAT_MATCHER, SPLAT_REPLACER) + "/?$"), + template : path.replace(PATH_NAME_MATCHER, function(a, b) { + return '{{'+b+'}}'; + }).replace(SPLAT_MATCHER, '{{splat}}'), + callback : callback + }; + }; + + $.fn.pathbinder = function(name, paths, options) { + options = options || {}; + var self = $(this), pathList = paths.split(/\n/); + $.each(pathList, function() { + var path = this; + if (path) { + // $.log("bind path", path); + var pathSpec = makePathSpec(path, function(params) { + // $.log("path cb", name, path, self) + // $.log("trigger path: "+path+" params: ", params); + self.trigger(name, [params]); + }); + // set the path when the event triggered through other means + if (options.bindPath) { + self.bind(name, function(ev, params) { + params = params || {}; + // $.log("set path", name, pathSpec) + setPath(pathSpec, params); + }); + } + // trigger when the path matches + registerPath(pathSpec); + } + }); + }; +})(jQuery); + \ No newline at end of file