Skip to content

Instantly share code, notes, and snippets.

@yoshuawuyts
Forked from Raynos/click-event.js
Created September 26, 2015 02:54
Show Gist options
  • Save yoshuawuyts/b2fe06c88e9db8fba8ae to your computer and use it in GitHub Desktop.
Save yoshuawuyts/b2fe06c88e9db8fba8ae 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));
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment