router.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. var Qs = Npm.require('qs');
  2. Router = function () {
  3. this._routes = [];
  4. this._routesMap = {};
  5. this.subscriptions = Function.prototype;
  6. // holds onRoute callbacks
  7. this._onRouteCallbacks = [];
  8. };
  9. Router.prototype.route = function(pathDef, options) {
  10. if (!/^\/.*/.test(pathDef)) {
  11. var message = "route's path must start with '/'";
  12. throw new Error(message);
  13. }
  14. options = options || {};
  15. var route = new Route(this, pathDef, options);
  16. this._routes.push(route);
  17. if (options.name) {
  18. this._routesMap[options.name] = route;
  19. }
  20. this._triggerRouteRegister(route);
  21. return route;
  22. };
  23. Router.prototype.group = function(options) {
  24. return new Group(this, options);
  25. };
  26. Router.prototype.path = function(pathDef, fields, queryParams) {
  27. if (this._routesMap[pathDef]) {
  28. pathDef = this._routesMap[pathDef].path;
  29. }
  30. fields = fields || {};
  31. var regExp = /(:[\w\(\)\\\+\*\.\?]+)+/g;
  32. var path = pathDef.replace(regExp, function(key) {
  33. var firstRegexpChar = key.indexOf("(");
  34. // get the content behind : and (\\d+/)
  35. key = key.substring(1, (firstRegexpChar > 0)? firstRegexpChar: undefined);
  36. // remove +?*
  37. key = key.replace(/[\+\*\?]+/g, "");
  38. return fields[key] || "";
  39. });
  40. path = path.replace(/\/\/+/g, "/"); // Replace multiple slashes with single slash
  41. // remove trailing slash
  42. // but keep the root slash if it's the only one
  43. path = path.match(/^\/{1}$/) ? path: path.replace(/\/$/, "");
  44. var strQueryParams = Qs.stringify(queryParams || {});
  45. if(strQueryParams) {
  46. path += "?" + strQueryParams;
  47. }
  48. return path;
  49. };
  50. Router.prototype.onRouteRegister = function(cb) {
  51. this._onRouteCallbacks.push(cb);
  52. };
  53. Router.prototype._triggerRouteRegister = function(currentRoute) {
  54. // We should only need to send a safe set of fields on the route
  55. // object.
  56. // This is not to hide what's inside the route object, but to show
  57. // these are the public APIs
  58. var routePublicApi = _.pick(currentRoute, 'name', 'pathDef', 'path');
  59. var omittingOptionFields = [
  60. 'triggersEnter', 'triggersExit', 'action', 'subscriptions', 'name'
  61. ];
  62. routePublicApi.options = _.omit(currentRoute.options, omittingOptionFields);
  63. _.each(this._onRouteCallbacks, function(cb) {
  64. cb(routePublicApi);
  65. });
  66. };
  67. Router.prototype.go = function() {
  68. // client only
  69. };
  70. Router.prototype.current = function() {
  71. // client only
  72. };
  73. Router.prototype.triggers = {
  74. enter: function() {
  75. // client only
  76. },
  77. exit: function() {
  78. // client only
  79. }
  80. };
  81. Router.prototype.middleware = function() {
  82. // client only
  83. };
  84. Router.prototype.getState = function() {
  85. // client only
  86. };
  87. Router.prototype.getAllStates = function() {
  88. // client only
  89. };
  90. Router.prototype.setState = function() {
  91. // client only
  92. };
  93. Router.prototype.removeState = function() {
  94. // client only
  95. };
  96. Router.prototype.clearStates = function() {
  97. // client only
  98. };
  99. Router.prototype.ready = function() {
  100. // client only
  101. };
  102. Router.prototype.initialize = function() {
  103. // client only
  104. };
  105. Router.prototype.wait = function() {
  106. // client only
  107. };