2017-03-21 03:00:45 +01:00
|
|
|
var documentReady = require('document-ready')
|
|
|
|
|
var nanorouter = require('nanorouter')
|
|
|
|
|
var nanomount = require('nanomount')
|
|
|
|
|
var nanomorph = require('nanomorph')
|
|
|
|
|
var nanoraf = require('nanoraf')
|
|
|
|
|
var nanobus = require('nanobus')
|
|
|
|
|
var assert = require('assert')
|
2016-05-10 23:23:33 +07:00
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
var onHistoryChange = require('./lib/history')
|
|
|
|
|
var onHref = require('./lib/href')
|
2016-05-10 23:23:33 +07:00
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
module.exports = Framework
|
|
|
|
|
|
|
|
|
|
function Framework (opts) {
|
2016-06-27 01:04:21 +02:00
|
|
|
opts = opts || {}
|
|
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
var routerOpts = {
|
|
|
|
|
default: opts.defaultRoute || '/404',
|
|
|
|
|
curry: true
|
2016-05-21 21:59:03 +09:00
|
|
|
}
|
|
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
var router = nanorouter(routerOpts)
|
|
|
|
|
var bus = nanobus()
|
|
|
|
|
var rerender = null
|
|
|
|
|
var tree = null
|
|
|
|
|
var state = {}
|
2016-05-11 13:51:17 +07:00
|
|
|
|
2016-06-27 01:04:21 +02:00
|
|
|
return {
|
2017-03-21 03:00:45 +01:00
|
|
|
toString: toString,
|
|
|
|
|
use: register,
|
|
|
|
|
mount: mount,
|
|
|
|
|
route: route,
|
|
|
|
|
start: start
|
2016-06-27 01:04:21 +02:00
|
|
|
}
|
2016-05-16 04:09:02 +07:00
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
function route (route, handler) {
|
|
|
|
|
router.on(route, function (params) {
|
|
|
|
|
return function () {
|
|
|
|
|
state.params = params
|
|
|
|
|
return handler(state, emit)
|
2016-12-11 19:35:29 +01:00
|
|
|
}
|
2017-03-21 03:00:45 +01:00
|
|
|
})
|
2016-12-11 19:35:29 +01:00
|
|
|
}
|
|
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
function register (cb) {
|
|
|
|
|
cb(state, bus)
|
2016-12-11 19:35:29 +01:00
|
|
|
}
|
|
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
function start () {
|
|
|
|
|
tree = router(createLocation(), state, emit)
|
|
|
|
|
rerender = nanoraf(function () {
|
|
|
|
|
var newTree = router(createLocation(), state, emit)
|
|
|
|
|
tree = nanomorph(tree, newTree)
|
|
|
|
|
})
|
2016-12-11 19:35:29 +01:00
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
bus.on('render', rerender)
|
2016-12-11 19:35:29 +01:00
|
|
|
|
|
|
|
|
if (opts.history !== false) {
|
2017-03-21 03:00:45 +01:00
|
|
|
onHistoryChange(function (href) {
|
2017-03-22 20:42:53 +01:00
|
|
|
bus.emit('pushState')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
bus.on('pushState', function (href) {
|
|
|
|
|
if (href) window.history.pushState({}, null, href)
|
|
|
|
|
bus.emit('render')
|
2017-03-25 02:17:43 -07:00
|
|
|
setTimeout(function () {
|
|
|
|
|
scrollIntoView()
|
|
|
|
|
}, 0)
|
2017-03-21 03:00:45 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (opts.href !== false) {
|
|
|
|
|
onHref(function (location) {
|
|
|
|
|
var href = location.href
|
|
|
|
|
var currHref = window.location.href
|
|
|
|
|
if (href === currHref) return
|
2017-03-22 20:42:53 +01:00
|
|
|
bus.emit('pushState', href)
|
2016-12-11 19:35:29 +01:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
documentReady(function () {
|
|
|
|
|
bus.emit('DOMContentLoaded')
|
|
|
|
|
})
|
2016-12-11 19:35:29 +01:00
|
|
|
|
2017-03-21 03:00:45 +01:00
|
|
|
return tree
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function emit (eventName, data) {
|
|
|
|
|
bus.emit(eventName, data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mount (selector) {
|
|
|
|
|
var newTree = start()
|
|
|
|
|
documentReady(function () {
|
|
|
|
|
var root = document.querySelector(selector)
|
|
|
|
|
assert.ok(root, 'could not query selector: ' + selector)
|
|
|
|
|
nanomount(root, newTree)
|
|
|
|
|
tree = root
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function toString (location, _state) {
|
|
|
|
|
state = _state || {}
|
|
|
|
|
var html = router(location)
|
|
|
|
|
assert.equal()
|
|
|
|
|
return html.toString()
|
2016-05-11 13:51:17 +07:00
|
|
|
}
|
|
|
|
|
}
|
2017-03-21 03:00:45 +01:00
|
|
|
|
|
|
|
|
function scrollIntoView () {
|
|
|
|
|
var hash = window.location.hash
|
|
|
|
|
if (hash) {
|
|
|
|
|
try {
|
|
|
|
|
var el = document.querySelector(hash)
|
|
|
|
|
if (el) el.scrollIntoView(true)
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createLocation () {
|
|
|
|
|
var pathname = window.location.pathname.replace(/\/$/, '')
|
|
|
|
|
var hash = window.location.hash.replace(/^#/, '/')
|
|
|
|
|
return pathname + hash
|
|
|
|
|
}
|