diff --git a/api/router.js b/api/router.js index 92731e77..b1226d55 100644 --- a/api/router.js +++ b/api/router.js @@ -2,38 +2,56 @@ var Vnode = require("../render/vnode") var coreRouter = require("../router/router") -var autoredraw = require("../api/autoredraw") -module.exports = function($window, renderer, pubsub) { +module.exports = function($window, mount) { var router = coreRouter($window) + var globalId, currentComponent, currentRender, currentArgs + + var RouteComponent = {view: function() { + return currentRender(Vnode(currentComponent, null, currentArgs, undefined, undefined, undefined)) + }} + function defaultRender(vnode){ + return vnode + } var route = function(root, defaultRoute, routes) { - var current = {path: null, component: "div", resolver: null}, currentResolutionIdentifier = null - var replay = router.defineRoutes(routes, function(payload, args, path, route) { - var resolutionIdentifier = currentResolutionIdentifier = {} - function resolve(component) { - if (resolutionIdentifier !== currentResolutionIdentifier) return - resolutionIdentifier = null - current.path = path, current.component = component - renderer.render(root, payload.render(Vnode(component, null, args, undefined, undefined, undefined))) + currentComponent = "div" + currentRender = defaultRender + currentArgs = null + + mount(root, RouteComponent) + + router.defineRoutes(routes, function(payload, args, path, route) { + var resolutionIdentifier = globalId = {} + var isResolver = typeof payload.view !== "function" + var render = defaultRender + + function resolve (component) { + if (resolutionIdentifier !== globalId) return + globalId = null + + currentComponent = component != null ? component: isResolver ? "div" : payload + currentRender = render + currentArgs = args + + root.redraw(true) } - if (typeof payload.view !== "function") { - if (typeof payload.render !== "function") payload.render = function(vnode) {return vnode} - if (typeof payload.onmatch !== "function") payload.onmatch = function() {resolve(current.component)} - if (path !== current.path) payload.onmatch(Vnode(payload, null, args, undefined, undefined, undefined), resolve) - else resolve(current.component) + function onmatch() { + resolve() } - else { - renderer.render(root, Vnode(payload, null, args, undefined, undefined, undefined)) + if (isResolver) { + if (typeof payload.render === "function") render = payload.render.bind(payload) + if (typeof payload.onmatch === "function") onmatch = payload.onmatch } + + onmatch.call(payload, {attrs: args}, resolve) }, function() { router.setPath(defaultRoute, null, {replace: true}) }) - autoredraw(root, renderer, pubsub, replay) } route.link = router.link route.prefix = router.setPrefix route.set = router.setPath route.get = router.getPath - + return route } diff --git a/api/tests/test-router.js b/api/tests/test-router.js index 66275448..d3829bb5 100644 --- a/api/tests/test-router.js +++ b/api/tests/test-router.js @@ -8,13 +8,14 @@ var m = require("../../render/hyperscript") var coreRenderer = require("../../render/render") var apiPubSub = require("../../api/pubsub") var apiRouter = require("../../api/router") +var apiMounter = require("../../api/mount") o.spec("route", function() { void [{protocol: "http:", hostname: "localhost"}, {protocol: "file:", hostname: "/"}].forEach(function(env) { void ["#", "?", "", "#!", "?!", "/foo"].forEach(function(prefix) { o.spec("using prefix `" + prefix + "` starting on " + env.protocol + "//" + env.hostname, function() { var FRAME_BUDGET = Math.floor(1000 / 60) - var $window, root, redraw, route + var $window, root, redraw, mount, route o.beforeEach(function() { $window = browserMock(env) @@ -22,7 +23,8 @@ o.spec("route", function() { root = $window.document.body redraw = apiPubSub() - route = apiRouter($window, coreRenderer($window), redraw) + mount = apiMounter(coreRenderer($window), redraw) + route = apiRouter($window, mount) route.prefix(prefix) }) diff --git a/route.js b/route.js index 94c7eec8..d41c606b 100644 --- a/route.js +++ b/route.js @@ -1,4 +1,3 @@ -var renderService = require("./render") -var redrawService = require("./redraw") +var mount = require("./mount") -module.exports = require("./api/router")(window, renderService, redrawService) \ No newline at end of file +module.exports = require("./api/router")(window, mount) \ No newline at end of file