www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

pathparser.js (3006B)


      1 /**
      2  * pathparser.js - tiny URL parser/router
      3  *
      4  * Copyright (c) 2014 Dan Stillman
      5  * License: MIT
      6  * https://github.com/dstillman/pathparser.js
      7  */
      8 (function (factory) {
      9 	// AMD/RequireJS
     10 	if (typeof define === 'function' && define.amd) {
     11 		define(factory);
     12 	// CommonJS/Node
     13 	} else if (typeof exports === 'object') {
     14 		module.exports = factory();
     15 	// Mozilla JSM
     16     } else if (~String(this).indexOf('BackstagePass')) {
     17     	EXPORTED_SYMBOLS = ["PathParser"];
     18     	PathParser = factory();
     19 	// Browser global
     20 	} else {
     21 		PathParser = factory();
     22 	}
     23 }(function () {
     24 	"use strict";
     25 	
     26 	var PathParser = function (params) {
     27 		this.rules = [];
     28 		this.params = params;
     29 	}
     30 	
     31 	PathParser.prototype = (function () {
     32 		function getParamsFromRule(rule, pathParts, queryParts) {
     33 			var params = {};
     34 			var missingParams = {};
     35 			
     36 			// Parse path components
     37 			for (var i = 0; i < rule.parts.length; i++) {
     38 				var rulePart = rule.parts[i];
     39 				var part = pathParts[i];
     40 				
     41 				if (part !== undefined) {
     42 					if (rulePart.charAt(0) == ':') {
     43 						params[rulePart.substr(1)] = part;
     44 						continue;
     45 					}
     46 					else if (rulePart !== part) {
     47 						return false;
     48 					}
     49 				}
     50 				else if (rulePart.charAt(0) != ':') {
     51 					return false;
     52 				}
     53 				else {
     54 					missingParams[rulePart.substr(1)] = true;
     55 				}
     56 			}
     57 			
     58 			// Parse query strings
     59 			for (var i = 0; i < queryParts.length; ++i) {
     60 				var nameValue = queryParts[i].split('=', 2);
     61 				var key = nameValue[0];
     62 				// But ignore empty parameters and don't override named parameters
     63 				if (nameValue.length == 2 && !params[key] && !missingParams[key]) {
     64 					params[key] = nameValue[1];
     65 				}
     66 			}
     67 			
     68 			return params;
     69 		}
     70 		
     71 		return {
     72 			add: function (route, handler, autoPopulateOnMatch) {
     73 				this.rules.push({
     74 					parts: route.replace(/^\//, '').split('/'),
     75 					handler: handler,
     76 					autoPopulateOnMatch: autoPopulateOnMatch === undefined || autoPopulateOnMatch
     77 				});
     78 			},
     79 			
     80 			run: function (url) {
     81 				if (url && url.length) {
     82 					url = url
     83 						// Remove redundant slashes
     84 						.replace(/\/+/g, '/')
     85 						// Strip leading and trailing '/' (at end or before query string)
     86 						.replace(/^\/|\/($|\?)/, '')
     87 						// Strip fragment identifiers
     88 						.replace(/#.*$/, '');
     89 				}
     90 				
     91 				var urlSplit = url.split('?', 2);
     92 				var pathParts = urlSplit[0].split('/', 50);
     93 				var queryParts = urlSplit[1] ? urlSplit[1].split('&', 50) : [];
     94 				
     95 				for (var i=0; i < this.rules.length; i++) {
     96 					var rule = this.rules[i];
     97 					var params = getParamsFromRule(rule, pathParts, queryParts);
     98 					if (params) {
     99 						params.url = url;
    100 						// Automatic parameter assignment
    101 						if (rule.autoPopulateOnMatch && this.params) {
    102 							for (var param in params) {
    103 								this.params[param] = params[param];
    104 							}
    105 						}
    106 						// Call handler with 'this' bound to parameter object
    107 						if (rule.handler) {
    108 							rule.handler.call(params);
    109 						}
    110 						return true;
    111 					}
    112 				}
    113 				return false;
    114 			}
    115 		};
    116 	})();
    117 	
    118 	return PathParser;
    119 }));