Skip to content

Instantly share code, notes, and snippets.

@Raynos
Created August 31, 2014 05:43
Show Gist options
  • Save Raynos/adbf7951bee3fdfe1a65 to your computer and use it in GitHub Desktop.
Save Raynos/adbf7951bee3fdfe1a65 to your computer and use it in GitHub Desktop.
Mercury router
module.exports = clickEvent;
function clickEvent(handler, opts) {
opts = opts || {};
return function clickHandler(ev) {
if (!opts.ctrl && ev.ctrlKey) {
return;
}
if (!opts.meta && ev.metaKey) {
return;
}
if (!opts.rightClick && ev.which === 2) {
return;
}
handler();
ev.preventDefault();
};
}
var h = require('mercury').h;
var clickEvent = require('./click-event.js');
var routeAtom = require('./router.js').atom;
module.exports = anchor;
function anchor(props, text) {
var href = props.href;
props.href = '#';
props['ev-click'] = clickEvent(pushState, {
ctrl: false,
meta: false,
rightClick: false
});
return h('a', props, text);
function pushState() {
routeAtom.set(href);
}
}
var routeMap = require('route-map');
module.exports = routeView;
function routeView(defn, args) {
if (args.base) {
defn = Object.keys(defn)
.reduce(function applyBase(acc, str) {
acc[args.base + str] = defn[str];
return acc;
}, {});
}
var match = routeMap(defn);
var res = match(args.route);
if (!res) {
throw new Error('router: no match found');
}
res.params.url = res.url;
return res.fn(res.params);
}
var mercury = require('mercury');
var source = require('geval/source');
var window = require('global/window');
var document = require('global/document');
var atom = Router.atom =
mercury.value(String(document.location.pathname));
/*
var mercury = require('mercury');
var h = require('mercury').h;
var anchor = require('mercury-route/anchor');
var routeView = require('mercury-route/route-view');
var Router = require('mercury-route/router');
function State() {
var state = mercury.struct({
route: Router()
});
return { state: state }
}
mercury.app(document.body, State().state, render);
function render(state) {
return h('div', [
menu(),
routeView({
'/': renderHome,
'/animals': renderAnimals,
'/animals/:id': renderAnimalItem
}, { route: state.route })
])
}
function menu() {
return h('ul', [
h('li', [
anchor({
href: '/'
}, 'Home')
]),
h('li', [
anchor({
href: '/animals'
}, 'Animals')
])
])
}
*/
module.exports = Router;
function Router() {
var inPopState = false;
var popstates = popstate();
popstates(onPopState);
atom(onRouteSet);
return { state: atom };
function onPopState(uri) {
inPopState = true;
atom.set(uri);
}
function onRouteSet(uri) {
if (inPopState) {
inPopState = false;
return;
}
pushHistoryState(uri);
}
}
function pushHistoryState(uri) {
window.history.pushState(undefined, document.title, uri);
}
function popstate() {
return source(function broadcaster(broadcast) {
window.addEventListener('popstate', onPopState);
function onPopState() {
broadcast(String(document.location.pathname));
}
});
}
@twilson63
Copy link

@Raynos - I took this gist and converted it into a repo mercury-router https://github.com/twilson63/mercury-router - gave you the credit - just wanted a npm module. if you want it under your account, I will be happy to transfer. Thanks again for the mercury framework and this gist!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment