Created
April 5, 2013 08:54
-
-
Save beyond-code-github/5317736 to your computer and use it in GitHub Desktop.
State machine routing Javascript prototype
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>State machine routing prototype</title> | |
</head> | |
<body> | |
<h3>State machine routing concept</h3> | |
<p>Extremely flexible mechanism for defining routes for web applications</p> | |
<ul> | |
<li>Hierarchical | |
</li> | |
<li>Efficient | |
</li> | |
<li>Easy to configure | |
</li> | |
</ul> | |
<h3>Try it out with the following routes:</h3> | |
<p> | |
/Products/<br /> | |
/Products/{id}<br /> | |
/Categories/<br /> | |
/Categories/id}<br /> | |
/Products/{id}/Categories<br /> | |
/Products/{id}/Categories/{id}<br /> | |
</p> | |
<p><strong>View the source to see configuration</strong></p> | |
<label for="route">Enter route here: http://localhost</label> | |
<input type="text" id="route" value="/Api/Products/1" style="width: 600px"> | |
<input type="button" id="go" value="Go" onclick="execute(route.value);"> | |
<h3>Output:</h3> | |
<div id="output"></div> | |
<script type="text/javascript"> | |
function execute(route) { | |
var target; | |
var params = {}; | |
var categoryId = { | |
matcher: /[0-9]/, | |
action: function (value) { params.categoryId = value; } | |
}; | |
var categories = { | |
matcher: /Categories/, | |
action: function (value) { target = "Categories controller"; }, | |
transitions: [categoryId] | |
}; | |
var productId = { | |
matcher: /[0-9]/, | |
action: function (value) { params.productId = value; }, | |
transitions: [categories] | |
}; | |
var products = { | |
matcher: /Products/, | |
action: function (value) { target = "Products controller"; }, | |
transitions: [productId] | |
}; | |
var apiRoot = { | |
matcher: /Api/, | |
transitions: [products, categories] | |
}; | |
success = processRoute(route, [apiRoot]); | |
var output = document.getElementById("output"); | |
output.innerHTML = ""; | |
if (success) { | |
output.innerHTML = output.innerHTML + "<p><strong>Target:</strong> " + target + "</p>"; | |
output.innerHTML = output.innerHTML + "<p><strong>Parameters:</strong>"; | |
output.innerHTML = output.innerHTML + "<ul>"; | |
for (prop in params) { | |
if (params.hasOwnProperty(prop)) { | |
output.innerHTML = output.innerHTML + "<li>" + prop + ": " + params[prop] + "</li>"; | |
} | |
} | |
output.innerHtml = output.innerHtml + "</ul></p>"; | |
} | |
else { | |
output.innerHTML = "<p><strong>404</strong></p>"; | |
} | |
} | |
function processRoute(route, availableTransitions) { | |
if (!route || !availableTransitions || availableTransitions.length == 0) { | |
return false; | |
} | |
var remainingRoute = route; | |
var segment = null; | |
// Identify the next valid segment of the route, and remove this from the remaining route | |
while (!segment || segment == "") { | |
var slashIndex = remainingRoute.indexOf("/"); | |
if (slashIndex >= 0) { | |
segment = remainingRoute.substring(0, slashIndex); | |
remainingRoute = remainingRoute.substring(slashIndex + 1, remainingRoute.length); | |
} else { | |
segment = remainingRoute; | |
remainingRoute = null; | |
break; | |
} | |
} | |
// Check for transitions that match the segment | |
var matchedTransition; | |
for (index in availableTransitions) { | |
if (availableTransitions[index].matcher.test(segment)) { | |
matchedTransition = availableTransitions[index]; | |
break; | |
} | |
} | |
if (!matchedTransition) { | |
return false; | |
} | |
// Perform any actions | |
if (matchedTransition.action) { | |
matchedTransition.action(segment); | |
} | |
// Recurse for remainder of the route | |
if (remainingRoute) { | |
if (matchedTransition.transitions && matchedTransition.transitions.length > 0) { | |
return processRoute(remainingRoute, matchedTransition.transitions); | |
} else { | |
return false; | |
} | |
} | |
return true; | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment